前几天写了一篇关于CPU分析和IO分析的文章。本来昨天还想再做一次内存分析的,但是昨天一早就去拜访了一个客户,所以今天才补上。今天早上,本来约了欧诺的奥涵,向他学习,听取他对智能运维的看法,但因为一些其他的安排,暂时取消了,非常遗憾。PG数据库遇到内存问题需要立即分析的场景并不多,因为大多数PG数据库内存占用高的告警并不代表内存占用异常,内存真的不够用。因为PG数据库使用了DOUBLEBUFFERING机制,所以很可能大量的内存被BUFFER/CACHE占用。上面free命令显示32G内存使用了15G多,但是free只剩下599M,BUFF/CACHE占用15G多。但是如果看available,有9G多,目前PG服务器的内存是够用的。从这个例子可以看出,我们在看fee命令的结果时,不应该看free,更准确的说是看available。/proc/meminfo可以更详细的看到OS的内存状态,我们可以关注红框内的几个数字。脏是指文件缓存中还没有写入磁盘的脏数据,是不能快速丢弃的内存。如果该指标持续偏高,说明需要关注操作系统回写机制或磁盘性能问题。如果PageTalbes比较大,对于PG数据库,很可能配置了更大的shared_buffers,却没有开启HugePages,这样不仅会影响PG数据库访问内存的性能,还会占用大量不必要的内存记忆。如果AnonHugePages指标大于0,说明透明大页面没有被禁用,已经使用了透明大页面。对于PG、Oracle等数据库,透明大页利大于弊,会造成内存碎片。建议禁用它们。另一个需要注意的是SWAP的使用率。如果空闲内存很大,但是SWAP使用率超过20%,很可能是OS的NUMA内存配置有问题,没有全局分配内存。当遇到PG数据库空闲内存不足的问题时,首先通过这些机制来分析OS内存是否真的存在风险。如果没有发现明显的风险,暂时不需要进一步分析。如果有风险,我们可以继续在OS层面进行搜索。psaux–sort-rss|head-20命令可以找出rss使用率最高的20个进程。然后找出有问题的进程,用smem进一步分析。如果你发现有问题的过程,你可以使用smem进一步分析。其中USS是进程的私有内存,PSS是私有内存+共享内存之和。如果发现OS层面有问题的进程,可以通过上面的语句找到它的PG会话信息,进一步定位。一般情况下,PGsession占用较多的内存用于VACUUM、ANALYZE、排序、表连接、内存临时表等操作。如果没有一个进程占用过多的内存,而是大量的进程占用了相似的内存,那么很可能是数据库并发执行了某种类型的SQL,使用了排序、表连接等临时内存分配。这时候就要分析是不是数据库的性能有问题,导致某类SQL或者某条SQL大量并发执行。或者某个SQL的执行计划有错误,导致执行时间长,并发量大,物理内存占用大。
