程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> MYSQL數據庫 >> MySQL綜合教程 >> MySQL OOM 體系二 OOM Killer

MySQL OOM 體系二 OOM Killer

編輯:MySQL綜合教程

MySQL OOM 體系二 OOM Killer。本站提示廣大學習愛好者:(MySQL OOM 體系二 OOM Killer)文章只能為提供參考,不一定能成為您想要的結果。以下是MySQL OOM 體系二 OOM Killer正文


這裡就觸及到一個成績,究竟Kill失落誰呢?普通略微懂得一些Linux內核的同窗第一反響是誰用的最多,就Kill失落誰。這固然是Linux內核起首斟酌的一種主要身分,然則也不完整是如許的,我們查一些Linux的內核方面的材料,可以曉得其實Kill誰是由/proc/<pid>/oom_score來決議的,這個值每一個過程一個,是由Linux內核的oom_badness()函數擔任盤算的。那上面我們來細心讀一讀badness()函數。  

在badness()函數的正文部門,寫清楚明了badness()函數的處置思緒:

         1) we lose the minimum amount of work done
         2) we recover a large amount of memory
         3) we don't kill anything innocent of eating tons of memory
         4) we want to kill the minimum amount of processes (one)
         5) we try to kill the process the user expects us to kill, this  algorithm has been meticulously tuned to meet the principle of least surprise ... (be careful when you change it)

總的來講就是Kill失落最小數目的過程來獲得最年夜數目的內存,這與我們Kill失落占用內存最年夜的過程是吻合的。

        /*
         * The memory size of the process is the basis for the badness.
         */

         points = p->mm->total_vm;

分數的肇端是過程現實應用的RAM內存,留意這裡不包含SWAP,即OOM Killer只會與過程現實的物理內存有關,與Swap是沒有關系的,而且我們可以看到,過程現實應用的物理內存越多,分數就越高,分數越高就越輕易被就義失落。

        /*
         * Processes which fork a lot of child processes are likely
         * a good choice. We add the vmsize of the childs if they
         * have an own mm. This prevents forking servers to flood the
         * machine with an endless amount of childs
         */
          ...
                  if (chld->mm != p->mm && chld->mm)
                        points += chld->mm->total_vm;

這段表現子過程占用的內存都邑盤算到父過程上。

        s = int_sqrt(cpu_time);
        if (s)
                points /= s;
        s = int_sqrt(int_sqrt(run_time));
        if (s)
                points /= s;

 這注解過程占用的CPU時光越長或許過程運轉的時光越長,分數越低,越不輕易被Kill失落。

       /*
        * Niced processes are most likely less important, so double
        * their badness points.
        */
        if (task_nice(p) > 0)
                points *= 2;

          假如過程優先級低(nice值,正值低優先級,負值高優先級),則Point翻倍。

       /*
        * Superuser processes are usually more important, so we make it
        * less likely that we kill those.
        */
        if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_ADMIN) ||
                                p->uid == 0 || p->euid == 0)
                points /= 4;

          super用戶的過程優先級較低。

        /*
         * We don't want to kill a process with direct hardware access.
         * Not only could that mess up the hardware, but usually users
         * tend to only have this flag set on applications they think
         * of as important.
         */
        if (cap_t(p->cap_effective) & CAP_TO_MASK(CAP_SYS_RAWIO))
                points /= 4;

          直接可以拜訪原始裝備的過程優先級較高。

        /*
         * Adjust the score by oomkilladj.
         */
        if (p->oomkilladj) {
                if (p->oomkilladj > 0)
                        points <<= p->oomkilladj;
                else
                        points >>= -(p->oomkilladj);

        }

每一個過程有個oomkilladj 可以設置該過程被kill的優先級,這個參數看上去對Point影響照樣比擬年夜的,oomkilladj 最年夜+15,最小是-17,越年夜越輕易被干失落,這個值因為是移位運算,所以影響照樣比擬年夜的。

上面我寫個小法式試驗一下:

 #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);
 }

下面的法式先請求一個1G的內存空間,然後100M為單元,填充這些內存空間。在一個2G內存,400M Swap空間的機械上跑3個下面的過程。我們看一下運轉成果:

   MySQL OOM 系統二 OOM Killer - 網易杭研後台技術中心 - 網易杭研後台技術中心的博客

     test1、test2、test3分離請求了1G的虛擬內存空間(VIRT),然後每隔10s,現實占用的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的後果。從新啟動3個過程,然後我們看到test2的PID是12640

   MySQL OOM 系統二 OOM Killer - 網易杭研後台技術中心 - 網易杭研後台技術中心的博客    

   我們運轉一下上面的語句

   echo 15 > /proc/12640/oom_adj

  一段時光後,我們看到Swap空間急劇削減,根本上OS OOM_Killer要開動了。 

   MySQL OOM 系統二 OOM Killer - 網易杭研後台技術中心 - 網易杭研後台技術中心的博客

     果真,不出料想,12640過程被kill失落了。

     所認為了防止本身須要的過程被kill失落,可以經由過程設置過程的oom_adj來完成。固然,有的人會說,這一切都是超售惹起的,既然Linux供給了overcommit_memory可以禁用overcommit特征,那為何不由用呢。這有益也有弊,一旦禁用overcommit,就意味著MySQL基本沒法請求跨越現實內存的空間,而在MySQL中,存在許多靜態請求內存空間的處所,假如請求不到,MySQL就會Crash,這年夜年夜增長了MySQL宕機的風險,這也是Linux為何要overcommit的緣由。

      有了下面的剖析,我們不好看出,假如在不設置oom_adj的條件下,MySQL普通都邑成為OOM_Killer的首選對象,由於MySQL普通都是內存的最年夜占用者。那作為MySQL,我們若何盡可能的去躲避被Kill的風險呢,下一章我們將重點從MySQL的角度剖析若何躲避OOM。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved