Ubuntu 20.04+PostgreSQL 12大内存下触发OOM-killer问题咨询
可能的原因分析
PostgreSQL 内存配置不合理
work_mem设置过高:如果你的程序并发执行大量排序、哈希操作,每个会话的work_mem会叠加计算。比如100个并发会话搭配1GB的work_mem,瞬间就能吃掉100GB内存,长期运行后累积的内存占用会触发OOM。哪怕默认work_mem只有4MB,若为了提速盲目调高,也会埋下隐患。- 多内存参数总和超标:哪怕你有128GB内存,如果
shared_buffers设置过大(比如64GB),再叠加maintenance_work_mem、wal_buffers以及操作系统的页缓存,PostgreSQL的内存占用会持续攀升,最终突破系统内存限制。
程序资源管理缺陷
- 数据库连接未正确回收:你的C++程序如果不断创建新连接却不关闭,PostgreSQL多进程架构下每个连接对应一个子进程,长期运行后连接数爆炸,子进程占用的内存会累积到OOM阈值。
- 程序自身内存泄漏:虽然
top显示程序内存占比不高,但如果循环生成瓦片时,持续申请内存却未释放(比如未清空的STL容器、未销毁的对象),内存会缓慢耗尽,最终触发系统回收postgres进程。
数据库事务与查询设计问题
- 未提交的长事务:若程序开启事务后长时间不提交,PostgreSQL需要保留事务快照、undo日志等数据,这些数据会持续占用内存,尤其是事务涉及大量数据操作时,内存占用会不断膨胀。
- 低效查询导致内存堆积:比如用
SELECT *拉取大量数据到内存,或是无索引导致全表扫描,PostgreSQL处理这类查询时会缓存大量数据,长期累积后内存占用飙升。
操作系统内存管理特性
- 页缓存过度占用:Ubuntu会尽可能用空闲内存做磁盘页缓存,
top显示的剩余内存不代表实际可用内存,要看free -h里的available值。如果程序持续读写大量数据,页缓存会不断膨胀,当系统需要内存时,脏页写入磁盘的速度赶不上内存需求,OOM-killer就会选中postgres这类高内存占用进程。 - OOM-killer的选择逻辑:系统内存不足时,会根据进程的
oom_score_adj值选择目标,postgres默认分数较高,容易被优先杀死。可以用cat /proc/<postgres-pid>/oom_score_adj查看,但调整分数只是治标,核心还是要解决内存泄漏问题。
瓦片任务负载特性
- 后期处理高数据量区域:比如生成城市区域瓦片时,数据量远高于乡村区域,后期大量高负载查询会导致PostgreSQL内存占用突然飙升,直接触发OOM。
内容的提问来源于stack exchange,提问作者hjj
相关产品推荐
相关产品推荐

