测试系统的mongodb莫名被杀掉了,看下mongo日志是内存溢出被杀掉了。
重新指定了下mongo配置中的
wiredTigerCacheSizeGB 属性,限制内存占用
但是不就多占点内存么,为啥杀的是我???
顺便看下linux OOM Killer原理。
系统在内存耗尽时,为防止系统崩溃,会查找当前系统所有进程,给每个进程进行打分,选择其中分值高的进程执行kill,以此来进行系统的自我保护。
其中选择给每个进程的打分方式是选择进行kill的依据。
源代码在https://github.com/torvalds/linux/blob/master/mm/oom_kill.c
unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
const nodemask_t *nodemask, unsigned long totalpages)
{
long points;
long adj;
//判断 如果是pid为1的initd进程,或者kthread内核进程,是否是其他cgroup,或者就没占内存。如果是则为0分。就是不能被kill
if (oom_unkillable_task(p, memcg, nodemask))
return 0;
p = find_lock_task_mm(p);
if (!p)
return 0;
/*
* Do not even consider tasks which are explicitly marked oom
* unkillable or have been already oom reaped or the are in
* the middle of vfork
*/
//每个进程有个调整分值可用,具体是在 /pro/${pid}/oom_adj,用于干涉oom情况下的打分分值
adj = (long)p->signal->oom_score_adj;
if (adj == OOM_SCORE_ADJ_MIN ||
test_bit(MMF_OOM_SKIP, &p->mm->flags) ||
in_vfork(p)) {
task_unlock(p);
return 0;
}
/*
* The baseline for the badness score is the proportion of RAM that each
* task's rss, pagetable and swap space use.
*/
//分值为 进程RSS, pagetable和swap 的空间利用情况 进程内存使用情况可以使用 pmap -d ${pid} 或者 cat /pro/${pid}/maps 查看,打分结果在 /pro/${pid}/oom_score
points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
atomic_long_read(&p->mm->nr_ptes) + mm_nr_pmds(p->mm);
task_unlock(p);
/*
* Root processes get 3% bonus, just like the __vm_enough_memory()
* implementation used by LSMs.
*/
//root的进程可以占到3%的便宜。。。亲儿子。。。
if (has_capability_noaudit(p, CAP_SYS_ADMIN))
points -= (points * 3) / 100;
/* Normalize to oom_score_adj units */
//totalpages为ram的pages + swap的pages
adj *= totalpages / 1000;
points += adj;
/*
* Never return 0 for an eligible task regardless of the root bonus and
* oom_score_adj (oom_score_adj can't be OOM_SCORE_ADJ_MIN here).
*/
return points > 0 ? points : 1;
}
通过阅读源码,可以知道大致的打分流程。
简单总结:
1、你是 pid为1的创始者,或者kthread核心人员,这俩惹不起,或者其他进程组的,不找麻烦。这三都不处理
2、其他的通过进程的内存RSS,pagetable和swap占用情况打分,当然你要是root直系给你3%的cheap。其他的除非有人照顾你oom_score_adj。没关系就被kill吧。
mongodb,mysql一副生无可恋的样子,有关系也不能太过分,哈哈哈。。。。
当然,上述是没有修改内核参数的默认情况。通过修改/etc/sysctl.conf内核参数修正可以调整一定oom killer处理方式,在后续文章说明