Postgres内存周期性下降与pgsql_tmp目录sharedfileset临时文件未清理问题
- 集群硬件配置:32核CPU、84GB内存,数据库总大小近800GB,配置了跨主机流WAL复制热备副本
- 操作系统与数据库版本:
Linux 2.6.32-642.6.2.el6.x86_64 (CentOS 6.4, 待升级) Postgres Version - 11.11
异常现象
自上月起观测到实例出现以下异常:
- 无
specified-time/hourly/daily/weekly/monthly类定时任务运行的前提下,内存使用率每隔80小时出现一次突降 - 突降同时生成约70GB临时文件,命名格式如
pgsql_tmp90128.0.sharedfileset/i231326of1048576.p2.0,Postgres恢复运行10分钟后仍不会自动删除,多次CHECKPOINT执行后也未清理 - 异常窗口内系统CPU使用率骤升,内存刷新后回落
内存相关配置
work_mem 8 MB temp_buffers 8 MB shared_buffers 22 GB max_connections 2500
监控数据
CPU使用率(sar采集)
$ sar -f /var/log/sa/sa17 -s 08:36:00 -e 08:47:00 08:36:21 AM CPU %user %nice %system %iowait %steal %idle 08:37:21 AM all 18.66 0.01 26.05 9.54 0.00 45.74 08:38:21 AM all 5.21 0.01 81.71 2.11 0.00 10.96 08:39:21 AM all 2.71 0.01 96.90 0.04 0.00 0.34 08:40:08 AM all 1.55 0.00 98.44 0.00 0.00 0.00 08:41:08 AM all 9.96 0.02 38.49 2.20 0.00 49.34 08:42:08 AM all 0.12 0.00 1.50 1.63 0.00 96.74 08:43:08 AM all 0.10 0.01 1.32 1.79 0.00 96.79 08:44:08 AM all 0.20 0.01 2.25 0.76 0.00 96.79 08:45:08 AM all 1.74 0.01 1.83 5.89 0.00 90.53 08:46:08 AM all 10.09 0.01 7.37 18.90 0.00 63.63 Average: all 5.11 0.01 34.18 4.36 0.00 56.34
内存使用率(sar采集)
$ sar -r -f /var/log/sa/sa17 -s 08:36:00 -e 08:47:00 08:36:21 AM kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit 08:37:21 AM 430888 88277480 99.51 12176 23869496 79753764 87.83 08:38:21 AM 420612 88287756 99.53 7212 23425316 80174100 88.29 08:39:21 AM 424276 88284092 99.52 3552 23246368 81653952 89.92 08:40:08 AM 417172 88291196 99.53 4316 22819904 82023344 90.33 08:41:08 AM 84692800 4015568 4.53 978760 1124852 25077588 27.62 08:42:08 AM 78749436 9958932 11.23 2098912 1139416 25067128 27.61 08:43:08 AM 73598564 15109804 17.03 3065228 1140756 25067516 27.61 08:44:08 AM 70213124 18495244 20.85 3175984 1141168 25067016 27.61 08:45:08 AM 56661972 32046396 36.13 3179640 13233168 27063188 29.80 08:46:08 AM 30585252 58123116 65.52 3207036 30364932 32130264 35.38 Average: 39619410 49088958 55.34 1573282 14150538 48307786 53.20
待咨询问题
- 内存使用率周期性骤降的可能原因是什么?
- 上述生成的临时文件是什么,手动删除是否安全?
- 该场景下临时文件未自动清理是否是Postgres的已知Bug?
1. 内存周期性骤降原因
从监控数据可以看到内存使用率触达99.5%以上后触发突降,结合CPU%system占比短时间飙到96%以上的特征,判断是Linux内核的OOM Killer触发了批量杀进程操作:80小时的周期是业务流量累积导致内存占用逐步触顶的时间,OOM Killer会优先杀掉占用内存高的Postgres后端进程,进程批量终止后占用的内存被释放,就出现了内存使用率骤降的现象。
另外你的max_connections配置为2500,远高于常规合理值,每个连接的私有内存叠加后很容易超出系统总内存阈值,也会加快内存触顶的速度。
2. 临时文件说明与删除安全性
你看到的pgsql_tmp前缀文件是Postgres执行排序、哈希连接、聚合等操作时,数据量超出work_mem阈值后刷到磁盘的临时文件。
手动删除的安全前提:只有当生成这些临时文件的Postgres进程已经终止的情况下,删除才是安全的。如果进程还在运行,删除会导致对应查询执行报错。
你当前场景下这些临时文件是OOM杀进程后遗留的,对应生成文件的进程已经不存在,此时手动删除完全安全。
3. 临时文件未自动清理是否为已知Bug
是的,这是Postgres 11版本的已知问题:当执行并行查询的后端进程被意外终止(比如OOM杀死、人工kill -9)时,并行查询对应的共享临时文件集不会被自动清理,CHECKPOINT操作也不会触发这类文件的回收,该问题在Postgres 12及以上版本已经修复。
你可以升级到Postgres最新小版本,或者配置定期清理脚本,检查pgsql_tmp目录下修改时间超过24小时的临时文件进行批量删除,作为临时规避方案。
内容的提问来源于stack exchange,提问作者PiyusG

