You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

K8S环境PostgreSQL主从POD停测后缓存未清理引发崩溃问题咨询

PostgreSQL 压测后缓存不释放导致OOM问题分析

注:pg_top输出中的FATAL: role "root" does not exist是执行命令的用户为root、无对应PostgreSQL角色导致的报错,不影响内存、CPU等系统指标的有效性。

核心原因梳理

  • PostgreSQL 共享内存设计特性:你配置的shared_buffers = 40GB是PostgreSQL启动时就向操作系统申请的固定共享内存段,属于PG自己管理的缓存区域,只要PG进程不重启,这部分内存不会主动释放回操作系统,是正常的设计逻辑而非内存泄漏。压测过程中大量热数据会被加载到该区域,压测停止后无新请求也会被PG默认保留,避免下次访问需要重新读盘。
  • 操作系统页缓存未触发回收:pg_top输出的96G cached是Linux内核管理的页缓存,用于缓存最近访问的磁盘文件数据提升读写性能,默认只有在系统可用内存不足时才会自动淘汰冷数据。你当前停止压测后系统还有64G空闲内存,所以内核不会主动清理这部分缓存。
  • K8S 资源配置不合理触发OOM:你给PostgreSQL POD配置的内存上限为110Gi,而PG自身shared_buffers已占用40G,叠加操作系统页缓存、PG连接私有内存、运算临时内存的占用,很容易触碰到K8S的内存限制阈值,触发cgroup OOM Killer杀掉PG进程,最终导致后端服务崩溃。

配置不合理的叠加因素

  • max_connections = 10000配置过高:PostgreSQL每个连接会占用固定的私有内存,即便空闲也不会释放,压测如果跑满连接,单连接内存累加值会远超预期,PG官方建议该参数不要超过1000,更高并发场景建议用pgbouncer做连接池代理。
  • 内存预留空间不足:你配置的effective_cache_size = 90GB是PG查询优化器认为可用的缓存总大小,而POD内存上限仅110Gi,扣除PG自身占用后留给操作系统、页缓存的冗余空间不足,进一步提升了OOM概率。
  • work_mem = 6MB的潜在风险:每个数据库连接执行排序、哈希聚合等操作时,最多可申请6MB临时内存,压测高并发场景下大量并行运算的内存总占用可能超出预期,叠加其他内存开销更容易触顶。

修复与优化建议

临时修复

  • 执行echo 3 > /proc/sys/vm/drop_caches手动清理操作系统冷页缓存,该操作不会影响PostgreSQL的正常运行,可快速降低内存占用。
  • 不要盲目重启PostgreSQL进程,会导致shared_buffers内的热数据全部丢失,重启后业务请求直接打磁盘可能引发慢查询雪崩。

长期优化

  • 下调max_connections到1000以内,前端部署pgbouncer连接池代理数据库连接,大幅降低连接本身的内存开销。
  • 上调POD内存limit到128Gi及以上,预留足够的冗余空间给页缓存、临时运算内存使用,避免触碰到cgroup内存阈值。
  • 调整Linux内核参数vm.min_free_kbytes,让系统在可用内存低于阈值时提前触发页缓存回收,避免内存占用直接触顶。
  • 如果需要严格控制内存占用,可开启cgroup内存统计的页缓存计数,配合内核回收策略实现内存占用的动态调整。

内容的提问来源于stack exchange,提问作者JAN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:06:05