32GB内存服务器mongod占7GB时触发cgroup OOM被Kill是何原因?
MongoDB进程被OOM终止故障排查结论
核心根因
本次故障不是宿主机全局内存不足导致,是进程所属cgroup内存硬上限触顶触发的定向OOM kill,和宿主机总32GB内存无直接关联。
关键日志证据:
Task in /mongod killed as a result of limit of /mongod
memory: usage 7340032kB, limit 7340032kB, failcnt 2404739
从日志可以明确:
- 被杀的mongod进程归属
/mongod独立cgroup资源组 - 该cgroup配置的内存硬上限刚好是7GB(7340032kB),触发OOM时组内内存用量已经完全顶到上限,累计内存申请失败次数高达240万次,属于长期资源配额不足,不是偶发内存峰值
- cgroup是Linux内核级资源隔离机制,只要进程所属组的内存触达配置上限,无论宿主机剩余多少空闲内存,都会触发mem cgroup维度的OOM killer,优先杀掉组内内存评分最高的进程(即mongod),这也是为什么看到mongod仅占7GB内存就被杀的原因。
相关内核日志完整片段:
[11988.010379] Memory cgroup out of memory: Kill process 16392 (mongod) score 994 or sacrifice child [11988.022403] Killed process 16392 (mongod) total-vm:9016932kB, anon-rss:7284224kB, file-rss:0kB, shmem-rss:0kB [11988.319261] oom_reaper: reaped process 16392 (mongod), now anon-rss:4kB, file-rss:0kB, shmem-rss:0kB [15015.365245] conn2096 invoked oom-killer: gfp_mask=0x14000c0(GFP_KERNEL), nodemask=(null), order=0, oom_score_adj=0 [15015.379050] conn2096 cpuset=/ mems_allowed=0 [15015.385647] CPU: 3 PID: 15357 Comm: conn2096 Not tainted 4.14.285-147.501.amzn1.x86_64 #1 [15015.397908] Hardware name: Xen HVM domU, BIOS 4.11.amazon 08/24/2006 [15015.407529] Call Trace: [15015.411779] dump_stack+0x66/0x81 [15015.417104] dump_header+0x94/0x21a [15015.422586] oom_kill_process+0x223/0x410 [15015.428918] out_of_memory+0x102/0x4c0 [15015.434991] mem_cgroup_out_of_memory+0x3b/0x60 [15015.442077] mem_cgroup_oom_synchronize+0x2d8/0x310 [15015.449609] ? mem_cgroup_css_reset+0xd0/0xd0 [15015.456520] pagefault_out_of_memory+0xf/0x60 [15015.463452] __do_page_fault+0x4ae/0x4c0 [15015.469099] ? page_fault+0x2f/0x50 [15015.472734] page_fault+0x45/0x50 [15015.476267] RIP: 4420b8a8:0x5627db743000 [15015.480385] RSP: 0000:00007f197f53d6d0 EFLAGS: 00489d23 [15015.480411] Task in /mongod killed as a result of limit of /mongod [15015.491635] memory: usage 7340032kB, limit 7340032kB, failcnt 2404739 [15015.497460] memory+swap: usage 7340028kB, limit 9007199254740988kB, failcnt 0 [15015.503577] kmem: usage 38324kB, limit 9007199254740988kB, failcnt 0 [15015.515250] Memory cgroup stats for /mongod: cache:488KB rss:7300704KB rss_huge:0KB shmem:0KB mapped_file:264KB dirty:0KB writeback:0KB swap:0KB inactive_anon:0KB active_anon:7301024KB inactive_file:456KB active_file:52KB unevictable:4KB [15015.543894] [ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents oom_score_adj name [15015.555451] [ 3991] 498 3991 2281830 1826804 3980 11 0 0 mongod
修复步骤
- 确认当前cgroup内存配置:执行命令查看
/mongod组的内存上限,验证和日志中7GB的限制一致cat /sys/fs/cgroup/memory/mongod/memory.limit_in_bytes - 调整cgroup内存配额:如果是物理机/虚拟机直接部署的MongoDB,根据业务负载调大内存上限,生产环境专属MongoDB节点建议给cgroup分配宿主机50%-70%的内存,预留2-4GB给内核、系统进程和页缓存即可,比如32GB内存的节点可以给MongoDB分配20GB-22GB的cgroup内存限制,执行以下命令临时生效:
如果需要永久生效,需要把配置写入cgroup的持久化规则,避免服务器重启后失效。# 示例:设置为20GB,数值单位为字节 echo 21474836480 > /sys/fs/cgroup/memory/mongod/memory.limit_in_bytes
如果是Docker/K8s等容器化部署的MongoDB,直接调整容器启动参数的--memory值、或者K8s Pod的resources.limits.memory配置即可,不要手动修改cgroup文件,否则容器重启后配置会重置。 - 同步调整MongoDB自身内存参数:WiredTiger存储引擎默认会占用最多60%的可用内存做数据缓存,加上连接栈、排序聚合临时内存、索引加载的开销,需要把MongoDB配置文件中的
wiredTiger.engineConfig.cacheSizeGB参数设置为比cgroup内存上限小2-3GB,避免进程内存触顶,比如cgroup给20GB内存的话,该参数设为17GB即可,修改后重启mongod生效。 - 配置验证:调整完成后持续观察cgroup内存用量和OOM计数,确认不再触发杀进程逻辑:
# 查看当前cgroup内存用量 cat /sys/fs/cgroup/memory/mongod/memory.usage_in_bytes # 查看内存申请失败次数,调整后该数值不再持续增长即配置生效 cat /sys/fs/cgroup/memory/mongod/memory.failcnt
内容的提问来源于stack exchange,提问作者Rea Haas
相关产品推荐
相关产品推荐

