>  기사  >  데이터 베이스  >  MySQL OOM 시스템 2 OOM Killer_MySQL

MySQL OOM 시스템 2 OOM Killer_MySQL

WBOY
WBOY원래의
2016-08-20 08:48:121226검색

누가 죽어야 하는가라는 질문이 포함됩니다. 일반적으로 Linux 커널에 대해 조금 아는 학생들은 먼저 Linux 커널을 가장 많이 사용하는 사람에게 반응하여 죽일 것입니다. 이는 물론 리눅스 커널이 먼저 고려하는 중요한 요소이지만, 완전히 그런 것은 아닙니다. 일부 리눅스 커널 정보를 확인해보면 실제로 누가 죽었는지는 /proc//oom_score 에 의해 결정된다는 것을 알 수 있습니다. 이 값은 각 프로세스에 대해 하나이며 Linux 커널의 oom_badness() 함수에 의해 계산됩니다. badness() 함수를 주의 깊게 읽어보자.

badness() 함수의 주석 부분에는 badness() 함수의 처리 아이디어가 명시되어 있습니다.

1) 최소한의 작업량을 잃습니다
​ 2) 대용량 메모리를 복구합니다
3) 우리는 엄청난 양의 메모리를 먹어도 무고한 사람을 죽이지 않습니다
4) 최소한의 프로세스(1개)를 종료하고 싶습니다
5) 사용자가 종료할 것으로 기대하는 프로세스를 종료하려고 합니다. 이 알고리즘은 최소 놀라움의 원칙을 충족하도록 세심하게 조정되었습니다... (변경 시 주의하세요)

일반적으로 최대 메모리 양을 얻기 위해 최소한의 프로세스를 종료하는 것이며, 이는 가장 많은 양의 메모리를 차지하는 프로세스를 종료하는 것과 일치합니다.

/*
* 프로세스의 크기 메모리는 불량의 기초입니다.
*/

포인트 = p->mm->total_vm;

점수 시작점은 프로세스에서 실제로 사용하는 RAM 메모리입니다. SWAP은 여기에 포함되지 않습니다. 즉, OOM Killer는 프로세스의 실제 물리적 메모리에만 관련되며 아무 작업도 수행하지 않습니다. Swap을 사용하면 프로세스의 실제 사용이 실제 메모리가 많을수록 점수가 높아지고 점수가 높을수록 희생하기가 더 쉽다는 것을 알 수 있습니다.

/*
* 많은 하위 프로세스를 분기하는 프로세스가 발생할 가능성이 높습니다
* 좋은 선택입니다.
* 자체 mm을 보유합니다. 이렇게 하면 서버가 폭주하는 것을 방지할 수 있습니다.
* 끝없이 많은 아이들이 있는 기계
*/
...
If (chld->mm != p->mm && chld->mm)
포인트 += chld->mm->total_vm;

이 단락은 하위 프로세스가 차지하는 메모리가 상위 프로세스로 계산된다는 의미입니다.

s = int_sqrt(cpu_time);
          만약(들)
포인트 /= s;
        s = int_sqrt(int_sqrt(run_time));
          만약(들)
포인트 /= s;

이는 프로세스가 차지하는 CPU 시간이 길거나 프로세스 실행 시간이 길수록 점수가 낮아지고 종료될 가능성이 낮아진다는 것을 보여줍니다.

/*
* 좋은 프로세스는 덜 중요할 가능성이 높으므로 두 배
* 그들의 나쁜점.
*/
If (task_nice(p) > 0)
포인트 *= 2;

프로세스 우선순위가 낮은 경우(좋은 값, 양수 값은 낮은 우선순위, 음수 값은 우선순위 높음) 포인트가 두 배가 됩니다.

       /*
        * 일반적으로 수퍼유저 프로세스가 더 중요하므로 이를 작성합니다
        * 우리가 그들을 죽일 가능성은 적습니다.
        */
        if (cap_t(p->cap_valid) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
                                p->uid == 0 || p->euid == 0)
                포인트 /= 4;

          매우 유용한 기능을 제공합니다.

        /*
         * 우리는 직접적인 하드웨어 접근으로 프로세스를 종료하고 싶지 않습니다.
         * 하드웨어를 망칠 수 있을 뿐만 아니라 일반적으로 사용자도
         * 자신이 생각하는 애플리케이션에만 이 플래그를 설정하는 경향이 있습니다
         * 중요합니다.
         */
        if (cap_t(p->cap_valid) & CAP_TO_MASK(CAP_SYS_RAWIO))
                포인트 /= 4;

          直接可以访问原始设备的进程优先级较高。

        /*
         * oomkilladj로 점수를 조정하세요.
         */
        if (p->oomkilladj) {
                if (p->oomkilladj > 0)
                        포인트 8428cef43a18c8ff27b763aa5f592054oomkilladj;
                그 외
                        포인트 >>= -(p->oomkilladj);

        }

下面我写个小程序实验一下:

 #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 1GB\n");
sleep(1);
int count = 0;
while( count < 10)
{
 memset(myblock,1,100*1024*1024);
 myblock = myblock + 100*1024*1024;
 count++;
 printf("Currently allocating %d00 MB\n",count);
 sleep(10);
  }
  exit(0);
 }

   

MySQL OOM 系统二 OOM Killer - 网易杭研后台技术中心 - 网易杭研后台技术中心的博客     test1、test2、test3分别申请了1G용 虚拟内存空间(VIRT), 然后每隔10s, 实际TM용 RAM 空间就增长100M(RES)。

    

MySQL OOM 系统二 OOM Killer - 网易杭研后台技术中心 - 网易杭研后台技术中心的博客    当물리内存공간间不足时,OS开始进行Swap,可用的Swap공간间开始减少。

   

    MySQL OOM 系统二 OOM Killer - 网易杭研后台技术中心 - 网易杭研后台技术中心的博客
     当内存是在没有可分配的 空间时,test1进程被操作系统Kill掉了。dmesg 我们可以看到,test1进程被OS Kill掉,同时oom_score 1000。

      这3个进程的oom_adj전체부티브토是默认值0。下面我们来实验一下设置了oom_adj的效果。 PID 12640

MySQL OOM 系统二 OOM Killer - 网易杭研后台技术中心 - 网易杭研后台技术中心的博客

다음 문장을 실행해 보겠습니다

에코 15 > /proc/12640/oom_adj

잠시 후 Swap 공간이 급격히 줄어들고 기본적으로 OS OOM_Killer가 시작되는 것을 확인했습니다.

MySQL OOM 系统二 OOM Killer - 网易杭研后台技术中心 - 网易杭研后台技术中心的博客

물론 예상대로 12640 프로세스가 종료되었습니다.

따라서 필요한 프로세스가 종료되는 것을 방지하려면 프로세스의 oom_adj를 설정하면 됩니다. 물론 일부 사람들은 이 모든 것이 초과 예약으로 인해 발생한다고 말할 것입니다. Linux는 오버커밋 기능을 비활성화하기 위해 overcommit_memory를 제공하므로 비활성화하는 것이 좋습니다. 이는 장점과 단점이 있습니다. 일단 오버커밋이 비활성화되면 MySQL은 실제 메모리보다 더 많은 공간을 적용할 수 없다는 의미입니다. MySQL에서는 메모리 공간을 동적으로 적용할 수 없는 경우 MySQL이 충돌합니다. 이로 인해 필요한 시간이 크게 늘어납니다. MySQL 가동 중지 시간의 위험은 Linux가 오버커밋하는 이유입니다.

위의 분석을 통해 oom_adj가 설정되지 않으면 일반적으로 MySQL이 OOM_Killer의 선호 개체가 된다는 것을 쉽게 알 수 있습니다. 왜냐하면 MySQL은 일반적으로 가장 큰 메모리 점유자이기 때문입니다. 그렇다면 MySQL로서 어떻게 죽을 위험을 피할 수 있을까요? 다음 장에서는 MySQL의 관점에서 OOM을 방지하는 방법을 중점적으로 분석하겠습니다.

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.