1. 内存参数
postgresql的内存分配主要由shared_buffers、temp_buffers、work_mem、maintenance_work_mem参数控制。
shared_buffers
又做共享缓冲区,postgresql对数据操作时都要先将数据从磁盘读取到内存中,然后进行更新,最后再将数据写回磁盘。shared_buffers的功能就是用于存放从磁盘读取的数据。设置范围一般在25%~40%之间。windows与linux对内存的管理方式不同,在linux中需要注意共享段大小的设置(kernel.shmmax)。
temp_buffers
临时缓冲区,用于数据库会话访问临时表数据,系统默认值为8M。可以在单独的session中对该参数进行设置,尤其是需要访问比较大的临时表时,将会有显著的性能提升。
work_mem
设置在写入临时磁盘文件之前查询操作(例如排序或哈希表)可使用的基础最大内存容量。 如果指定值时没有单位,则以千字节为单位。默认值是4兆字节 (`4MB`)。 注意对于一个复杂查询, 可能会并行运行好几个排序或者哈希操作;每个操作通常都会被允许使用这个参数指定的内存量,然后才会开始写数据到临时文件。 同样,几个正在运行的会话可能并发进行这样的操作。因此被使用的总内存可能是`work_mem`值的好几倍,在选择这个值时一定要记住这一点。 `ORDER BY`、`DISTINCT`和归并连接都要用到排序操作。 哈希连接、基于哈希的聚集以及基于哈希的`IN`子查询处理中都要用到哈希表。
与等效的基于排序的操作相比,基于哈希的操作通常对内存可用性更敏感。 可用于哈希表的内存通过将`work_mem`乘`hash_mem_multiplier`来计算。 这使得基于哈希的操作可以使用超出通常`work_mem`基本量的内存。
—— 摘自【PostgreSQL官方文档】
工作内存或者操作内存。负责内部的sort和hash操作,合适的work_mem大小能够保证这些操作在内存中进行。定义太小的话,sort或者hash操作将需要与硬盘进行swap,这样会极大的降低系统的性能;太大的话致使在能够在内存中完成的操作数量减少,其他的部分需要与磁盘进行swap操作,增加IO降低性能,系统提供的默认值是1M。在实际的维护中可以通过explain analyze分析语句的work_mem大小是否合适。在语句中设置work_mem参数的大小可以充分利用内存,提高语句的执行效率。对于work_mem内存分配时还要考虑数据库的并发情况,max_connections决定了系统的最大的并发连接数。不论如何调整work_mem都要考虑: $$ \begin{align} & max\_connections*work\_mem \\ & +shared\_buffers \\ & +temp\_buffers \\ & +maintenance\_work\_mem \\ & +操作系统所需内存 \\ & < = RAM总大小 \end{align} $$ 这是非常重要的。
maintenance_work_mem
维护工作内存,主要是针对数据库的维护操作或者语句。尽量的将这些操作在内存中进行。主要针对VACUUM,CREATE INDEX,REINDEX等操作。在对整个数据库进行VACUUM或者较大的index进行重建时,适当的调整该参数非常必要。
本章摘自:postgresql内存参数
2. PG内存资源消耗
参考PG文档
3. 内存资源使用
palloc单次申请内存最大值
- snippet.cpp
#define MaxAllocSize ((Size) 0x3fffffff) /* 1 gigabyte - 1 */ #define AllocSizeIsValid(size) ((Size) (size) <= MaxAllocSize) void * palloc(Size size) { …… if (!AllocSizeIsValid(size)) elog(ERROR, "invalid memory alloc request size %zu", size);
可见,palloc单词允许申请的最大内存不超过1GB。