PostgreSQL 11共享内存段丢失求助:运行15小时后文件遭删除
问题概述
你的PostgreSQL 11实例在运行约15小时后出现共享内存段被删除的错误,核心报错信息如下:
2019-07-09 08:46:41 CDT [] [6723]: [1-1] user=,db=,e=58P01 ERROR: 无法打开共享内存段"/PostgreSQL.291691635":没有该文件或目录
2019-07-09 08:46:41 CDT [10.40.0.204(60550)] [13880]: [2-1] user=user_name,db=db_name,e=58P01 CONTEXT: 并行工作进程2
结合你的环境配置来看:
- GCP虚拟机:4核CPU、16GB内存,Ubuntu 18.04.1 LTS
- 内核共享内存参数:
kernel.shmmax=8589934592 kernel.shmall=2097152 - PostgreSQL核心配置(postgresql.conf):
max_connections = 500 shared_buffers = 4GB max_worker_processes = 4 max_parallel_workers_per_gather = 2
从配置判断,内核共享内存资源完全满足PostgreSQL需求,启动阶段无报错,问题核心是共享内存段被外部进程或系统自动清理机制删除,咱们一步步排查:
1. 优先排查systemd临时文件清理机制(最常见诱因)
Ubuntu 18.04默认通过systemd-tmpfiles-clean.service定期清理/dev/shm(tmpfs临时文件系统)下的文件,若规则阈值过短,会误删PostgreSQL的共享内存段。
检查清理规则:
查看系统默认的tmp文件配置:
cat /usr/lib/tmpfiles.d/tmp.conf重点关注
/dev/shm相关规则,比如:d /dev/shm 1777 root root 10d最后一个数字是清理阈值(
10d表示10天未访问则删除),如果你的配置阈值小于15小时(比如1h),就会触发误删。同时检查自定义配置文件:
cat /etc/tmpfiles.d/*.conf
永久修复方法:
创建自定义配置,排除PostgreSQL的共享内存段不被清理:
- 创建配置文件:
这里的sudo touch /etc/tmpfiles.d/postgresql-shm.conf sudo echo "x /dev/shm/PostgreSQL.*" >> /etc/tmpfiles.d/postgresql-shm.confx表示跳过匹配的文件,不执行清理操作。 - 重启清理服务生效:
sudo systemctl restart systemd-tmpfiles-clean.service
2. 监控/dev/shm的文件删除操作(精准定位元凶)
如果不确定是哪个进程删除了共享内存段,可以用auditd工具跟踪文件系统操作:
操作步骤:
- 安装auditd:
sudo apt update && sudo apt install auditd - 添加监控规则,跟踪
/dev/shm下的写入/删除操作:sudo auditctl -w /dev/shm/ -p wa -k shm_delete-p wa表示监控写入、属性修改操作,-k shm_delete是自定义标记,方便后续过滤日志。 - 再次出现错误时,查看审计日志:
日志会明确显示哪个进程(PID、进程名)在什么时间删除了文件,直接锁定根因。sudo ausearch -k shm_delete
3. 验证共享内存段的访问状态
可以检查PostgreSQL共享内存段的访问时间,确认是否符合清理规则:
ls -l --time=atime /dev/shm/PostgreSQL.*
如果某个段的访问时间距离当前超过了systemd的清理阈值,就会被标记为待清理对象。
补充说明
你的PostgreSQL并行工作进程配置和CPU核数匹配,并行查询本身不会导致共享内存段丢失,只是共享内存被删除后,并行进程无法正常初始化才触发了报错。
内容的提问来源于stack exchange,提问作者Pruthviraj

