MYSQL数据库MySQL OOM 系统二 OOM Killer
《MYSQL数据库MySQL OOM 系统二 OOM Killer》要点: MYSQL应用这里就涉及到一个问题,到底Kill掉谁呢?一般稍微了解一些Linux内核的同学第一反应是谁用的最多,就Kill掉谁.这当然是Linux内核首先考虑的一种重要因素,但是也不完全是这样的,我们查一些Linux的内核方面的材料,可以知道其实Kill谁是由/proc/<pid>/oom_score来决定的,这个值每个进程一个,是由Linux内核的oom_badness()函数负责计算的.那下面我们来仔细读一读badness()函数.?? MYSQL应用在badness()函数的注释部门,写明了badness()函数的处理思路: MYSQL应用???????? 1) we lose the minimum amount of work done MYSQL应用总的来说便是Kill掉最小数量的进程来获取最大数量的内存,这与我们Kill掉占用内存最大的进程是吻合的. MYSQL应用??????? /* MYSQL应用???????? points = p->mm->total_vm; MYSQL应用分数的起始是进程实际使用的RAM内存,注意这里不包含SWAP,即OOM Killer只会与进程实际的物理内存有关,与Swap是没有关系的,并且我们可以看到,进程实际使用的物理内存越多,分数就越高,分数越高就越容易被牺牲掉. MYSQL应用??????? /* MYSQL应用这段表现子进程占用的内存都会计算到父进程上. MYSQL应用??????? s = int_sqrt(cpu_time); MYSQL应用?这注解进程占用的CPU时间越长或者进程运行的时间越长,分数越低,越不容易被Kill掉. MYSQL应用?????? /* MYSQL应用????????? 如果进程优先级低(nice值,正值低优先级,负值高优先级),则Point翻倍. MYSQL应用?????? /* MYSQL应用????????? super用户的进程优先级较低. MYSQL应用??????? /* MYSQL应用????????? 直接可以拜访原始设备的进程优先级较高. MYSQL应用??????? /* MYSQL应用??????? } MYSQL应用每个进程有个oomkilladj 可以设置该进程被kill的优先级,这个参数看上去对Point影响还是比拟大的,oomkilladj 最大+15,最小是-17,越大越容易被干掉,这个值由于是移位运算,所以影响还是比拟大的. MYSQL应用下面我写个小程序实验一下: MYSQL应用
#define MEGABYTE 1024*1024*1024
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc,char *argv[])
{
void *myblock = NULL;
myblock = (void *) malloc(MEGABYTE);
printf("Currently allocating 1GBn");
sleep(1);
int count = 0;
while( count < 10)
{
memset(myblock,1,100*1024*1024);
myblock = myblock + 100*1024*1024;
count++;
printf("Currently allocating %d00 MBn",count);
sleep(10);
}
exit(0);
}
MYSQL应用上面的程序先申请一个1G的内存空间,然后100M为单位,填充这些内存空间.在一个2G内存,400M Swap空间的机器上跑3个上面的进程.我们看一下运行结果: MYSQL应用? ? MYSQL应用? ? ?test1、test2、test3分别申请了1G的虚拟内存空间(VIRT),然后每隔10s,实际占用的RAM空间就增长100M(RES). MYSQL应用? ?? MYSQL应用? ??当物理内存空间不敷时,OS开始进行Swap,可用的Swap空间开始减少. MYSQL应用? ? ? ?? MYSQL应用? ? ?当内存是在没有可分配的空间时,test1进程被操作系统Kill掉了.dmesg 我们可以看到,test1进程被OS Kill掉,同时oom_score为1000. MYSQL应用?????这3个进程的oom_adj全部都是默认值0.下面我们来实验一下设置了oom_adj的效果.重新启动3个进程,然后我们看到test2的PID是12640 MYSQL应用? ? MYSQL应用? ?我们运行一下下面的语句 MYSQL应用???echo 15 > /proc/12640/oom_adj MYSQL应用? 一段时间后,我们看到Swap空间急剧减少,基本上OS OOM_Killer要开动了.? MYSQL应用? ? MYSQL应用? ? ?果然,不出意料,12640进程被kill掉了. MYSQL应用???? 所以为了避免本身需要的进程被kill掉,可以通过设置进程的oom_adj来实现.当然,有的人会说,这一切都是超售引起的,既然Linux提供了overcommit_memory可以禁用overcommit特性,那为什么不禁用呢.这有利也有弊,一旦禁用overcommit,就意味着MySQL根本无法申请超过实际内存的空间,而在MySQL中,存在很多动态申请内存空间的地方,如果申请不到,MySQL就会Crash,这大大增加了MySQL宕机的风险,这也是Linux为什么要overcommit的原因. MYSQL应用????? 有了上面的阐发,我们不难看出,如果在不设置oom_adj的前提下,MySQL一般都会成为OOM_Killer的首选对象,因为MySQL一般都是内存的最大占用者.那作为MySQL,我们如何尽量的去规避被Kill的风险呢,下一章我们将重点从MySQL的角度阐发如何规避OOM. 欢迎参与《MYSQL数据库MySQL OOM 系统二 OOM Killer》讨论,分享您的想法,编程之家PHP学院为您提供专业教程。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |