数据库内存不足,服务器交换空间大量占用,以及最近遇到的autovacuum进程导致内存溢出等问题。本文就数据库参数配置预防内存溢出
这是一个PostgreSQL实例的图形视图描述了内存区域,服务器后台进程和底层数据库文件。
计算公式
max_connections * work_mem + max_connections * temp_buffers +shared_buffers * 2
+ autovacuum_max_workers * autovacuum_work_mem + maintenance_work_mem + wal_buffers
+ OS运行最小要求的内存(2GB)< 服务器物理内存
shared_buffers*2的原因是pg数据库是双缓存,虽然系统缓存不一定就和shared_buffers一样大,但是差距不会太大如果没有配置
autovacuum_work_mem那么默认会以maintenance_work_mem为准以一台
128GB服务器,3000连接为例:
autovacuum_max_workersmax_connections = 3000
shared_buffers=32GB #--1/4物理内存
temp_buffers=8MB --默认值
work_mem=4MB --默认值
wal_buffers=16MB #--with-wal-segsize的默认值
autovacuum_max_workers = 3 --默认值
maintenance_work_mem=2GB --vacuum,create index等维护工作内存
autovacuum_work_mem = 1GB --autovacuum清理进程,总耗内存:autovacuum_max_workers*autovacuum_work_mem
计算如下:
select (3000*4+3000*8+32*1024*2+3*1*1024+2*1024+16)/1024=104GB
pg满载峰值时最多使用104GB内存,物理内存128GB,还有24GB供操作系统使用,但是如果我们改大连接数到6000,计算出结果139GB超过了服务器物理内存,那么在高负载的时候就有内存溢出的风险
shared_buffers
(推荐值:系统内存的25%)
在内存中读取或写入数据总是比在任何其他介质上更快。数据库服务器还需要内存来快速访问数据,无论是读访问还是写访问。在 PostgreSQL 中,这称为共享缓冲区并由参数shared_buffers控制。共享缓冲区所需的RAM量在 PostgreSQL实例的生命周期内始终被锁定。连接到数据库的所有后台服务器和用户进程都可以访问共享缓冲区。
推荐的值接近系统RAM 的25%
wal_buffers:
推荐值:16MB
默认值:16MB
预写日志 (WAL) 缓冲区也称为事务日志缓冲区,这是用于存储 WAL数据的内存分配量。此WAL 数据是有关实际数据更改的元数据信息,足以在数据库恢复操作期间重建实际数据。WAL 数据被写入持久位置中的一组物理文件,称为WAL 段或检查点段。
WAL 缓冲区内存分配由wal_buffers参数控制,它是从操作系统 RAM中分配的。尽管所有后台服务器和用户进程也可以访问此内存区域,但它不是共享缓冲区的一部分。WAL 缓冲区位于共享缓冲区的外部,与共享缓冲区相比非常小。WAL 数据在写入磁盘上的 WAL 段之前首先在 WAL 缓冲区中被修改(弄脏)。如果保留为默认设置,则分配的大小为共享缓冲区的 1/16。
work_mem:
推荐值:4MB,针对复杂查询可在会话级设置较大值
默认值:4MB
work_mem的值用于排序操作,并定义用于中间结果(如哈希表)和排序的最大内存量。
work_mem值不要设置得太高,因为当应用程序执行排序操作时,它可能会造成系统上可用内存的瓶颈。理想的做法是将work_mem的全局值设置为一个相对较低的值,然后针对复杂的排序在会话级别设置较大的work_mem值。
默认值:4MB
autovacuum_work_mem
推荐值:1GB
默认值:-1
我们可以在这里指定每个autovacuum worker 使用的最大内存量。
autovacuum 默认时使用maintenance_work_mem,建议分开设置一般情况下maintenance_work_mem维护都是单进程可以稍微设置大点,而autovacuum_work_mem受autovacuum_max_workers影响,设置1GB的维护工作内存足以一次处理大约 1.79 亿个死元组
这是每个autovacuum 工作进程使用的最大内存量,它由autovacuum_work_mem数据库参数控制。内存是从操作系统 RAM分配的,也受autovacuum_max_workers数据库参数的影响。所有这些参数设置仅在启用自动真空守护进程时起作用,否则,这些设置在其他上下文中运行时对VACUUM的行为没有影响。此内存组件不由任何其他后台服务器或用户进程共享。
maintenance_work_mem
推荐值:2GB
默认值:64MB
maintenance_work_mem指定用于例行维护任务(如VACUUM、CREATE INDEX等)的内存使用量。
与work_mem不同的是,数据库会话一次只能执行这些维护操作中的一个。因此,大多数系统不会并发运行许多这样的进程,因此,将这个值设置为比work_mem大得多通常是安全的,因为更大的可用内存可以提高清理和恢复数据库转储的性能。
temp_buffers
推荐值:8MB
默认:8MB
一个数据库可能有一个或多个临时表,这些临时表的数据块(页面)需要单独分配内存以进行处理。临时缓冲区通过利用由temp_buffers参数定义的一部分 RAM 来达到此目的. 临时缓冲区仅用于访问 用户会话中的临时表。内存中的临时缓冲区与大型排序和哈希表操作期间在pgsql_tmp 目录下创建的临时文件之间没有关系。
effective_cache_size
推荐值50%-75% RAM
默认值:4GB
除了上面这些参数外,我们还经常看到一个参数effective_cache_size,这个值仅由PostgreSQL查询规划器使用,以确定它所考虑的计划是否应该适合RAM。
具体点就是:如果effecve_cache_size的值太低,那么查询规划器可能会决定不使用某些索引,即使它们可以极大地提高查询速度。所以换句话说,这个值是PG用来估计索引的成本用的。
effective_cache_size的保守值是系统上可用总量的1/2。最常见的情况是,该值被设置为专用DB服务器上系统总内存的75%,但根据特定服务器工作负载上的特定离散需求,该值可以有所不同。
此参数提供可用于磁盘缓存的总内存的估计值。请注意,这只是一个指南,而不是确切的缓存大小。effective_cache_size 不分配内存,相反,它通知优化器内核中可用的缓存级别。如果这个值设置得很低,那么查询规划器会自动限制使用某些索引,有时这些索引是有帮助的。所以总是把这个参数设置一个大的值。




