欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL OOM 系統(tǒng)二 OOM Killer

 更新時(shí)間:2016年07月16日 23:05:56   投稿:mdxy-dxy  
前面一節(jié)重點(diǎn)分享了Linux的內(nèi)存分配策略,基于上述的分配策略,為了規(guī)避超售的風(fēng)險(xiǎn),Linux采了一種OOM Killer的機(jī)制,即系統(tǒng)可用內(nèi)存(包括Swap)即將使用完之前,選擇性的Kill掉一些進(jìn)程以求釋放一些內(nèi)存

這里就涉及到一個(gè)問題,到底Kill掉誰呢?一般稍微了解一些Linux內(nèi)核的同學(xué)第一反應(yīng)是誰用的最多,就Kill掉誰。這當(dāng)然是Linux內(nèi)核首先考慮的一種重要因素,但是也不完全是這樣的,我們查一些Linux的內(nèi)核方面的資料,可以知道其實(shí)Kill誰是由/proc/<pid>/oom_score來決定的,這個(gè)值每個(gè)進(jìn)程一個(gè),是由Linux內(nèi)核的oom_badness()函數(shù)負(fù)責(zé)計(jì)算的。那下面我們來仔細(xì)讀一讀badness()函數(shù)。  

在badness()函數(shù)的注釋部分,寫明了badness()函數(shù)的處理思路:

         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掉最小數(shù)量的進(jìn)程來獲取最大數(shù)量的內(nèi)存,這與我們Kill掉占用內(nèi)存最大的進(jìn)程是吻合的。

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

         points = p->mm->total_vm;

分?jǐn)?shù)的起始是進(jìn)程實(shí)際使用的RAM內(nèi)存,注意這里不包括SWAP,即OOM Killer只會(huì)與進(jìn)程實(shí)際的物理內(nèi)存有關(guān),與Swap是沒有關(guān)系的,并且我們可以看到,進(jìn)程實(shí)際使用的物理內(nèi)存越多,分?jǐn)?shù)就越高,分?jǐn)?shù)越高就越容易被犧牲掉。

        /*
         * 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;

這段表示子進(jìn)程占用的內(nèi)存都會(huì)計(jì)算到父進(jìn)程上。

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

 這表明進(jìn)程占用的CPU時(shí)間越長或者進(jìn)程運(yùn)行的時(shí)間越長,分?jǐn)?shù)越低,越不容易被Kill掉。

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

          如果進(jìn)程優(yōu)先級低(nice值,正值低優(yōu)先級,負(fù)值高優(yōu)先級),則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用戶的進(jìn)程優(yōu)先級較低。

        /*
         * 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;

          直接可以訪問原始設(shè)備的進(jìn)程優(yōu)先級較高。

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

        }

每個(gè)進(jìn)程有個(gè)oomkilladj 可以設(shè)置該進(jìn)程被kill的優(yōu)先級,這個(gè)參數(shù)看上去對Point影響還是比較大的,oomkilladj 最大+15,最小是-17,越大越容易被干掉,這個(gè)值由于是移位運(yùn)算,所以影響還是比較大的。

下面我寫個(gè)小程序?qū)嶒?yàn)一下:

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

上面的程序先申請一個(gè)1G的內(nèi)存空間,然后100M為單位,填充這些內(nèi)存空間。在一個(gè)2G內(nèi)存,400M Swap空間的機(jī)器上跑3個(gè)上面的進(jìn)程。我們看一下運(yùn)行結(jié)果:

   MySQL OOM 系統(tǒng)二 OOM Killer - 網(wǎng)易杭研后臺(tái)技術(shù)中心 - 網(wǎng)易杭研后臺(tái)技術(shù)中心的博客

     test1、test2、test3分別申請了1G的虛擬內(nèi)存空間(VIRT),然后每隔10s,實(shí)際占用的RAM空間就增長100M(RES)。

    MySQL OOM 系統(tǒng)二 OOM Killer - 網(wǎng)易杭研后臺(tái)技術(shù)中心 - 網(wǎng)易杭研后臺(tái)技術(shù)中心的博客

    當(dāng)物理內(nèi)存空間不足時(shí),OS開始進(jìn)行Swap,可用的Swap空間開始減少。

   MySQL OOM 系統(tǒng)二 OOM Killer - 網(wǎng)易杭研后臺(tái)技術(shù)中心 - 網(wǎng)易杭研后臺(tái)技術(shù)中心的博客
    

     當(dāng)內(nèi)存是在沒有可分配的空間時(shí),test1進(jìn)程被操作系統(tǒng)Kill掉了。dmesg 我們可以看到,test1進(jìn)程被OS Kill掉,同時(shí)oom_score為1000。

     這3個(gè)進(jìn)程的oom_adj全部都是默認(rèn)值0。下面我們來實(shí)驗(yàn)一下設(shè)置了oom_adj的效果。重新啟動(dòng)3個(gè)進(jìn)程,然后我們看到test2的PID是12640

   MySQL OOM 系統(tǒng)二 OOM Killer - 網(wǎng)易杭研后臺(tái)技術(shù)中心 - 網(wǎng)易杭研后臺(tái)技術(shù)中心的博客    

   我們運(yùn)行一下下面的語句

   echo 15 > /proc/12640/oom_adj

  一段時(shí)間后,我們看到Swap空間急劇減少,基本上OS OOM_Killer要開動(dòng)了。 

   MySQL OOM 系統(tǒng)二 OOM Killer - 網(wǎng)易杭研后臺(tái)技術(shù)中心 - 網(wǎng)易杭研后臺(tái)技術(shù)中心的博客

     果然,不出意料,12640進(jìn)程被kill掉了。

     所以為了避免自己需要的進(jìn)程被kill掉,可以通過設(shè)置進(jìn)程的oom_adj來實(shí)現(xiàn)。當(dāng)然,有的人會(huì)說,這一切都是超售引起的,既然Linux提供了overcommit_memory可以禁用overcommit特性,那為什么不禁用呢。這有利也有弊,一旦禁用overcommit,就意味著MySQL根本無法申請超過實(shí)際內(nèi)存的空間,而在MySQL中,存在很多動(dòng)態(tài)申請內(nèi)存空間的地方,如果申請不到,MySQL就會(huì)Crash,這大大增加了MySQL宕機(jī)的風(fēng)險(xiǎn),這也是Linux為什么要overcommit的原因。

      有了上面的分析,我們不難看出,如果在不設(shè)置oom_adj的前提下,MySQL一般都會(huì)成為OOM_Killer的首選對象,因?yàn)镸ySQL一般都是內(nèi)存的最大占用者。那作為MySQL,我們?nèi)绾伪M量的去規(guī)避被Kill的風(fēng)險(xiǎn)呢,下一章我們將重點(diǎn)從MySQL的角度分析如何規(guī)避OOM。

相關(guān)文章

  • MySQL綠色解壓縮版安裝與配置操作步驟

    MySQL綠色解壓縮版安裝與配置操作步驟

    這篇文章主要介紹了MySQL綠色解壓縮版安裝與配置操作步驟,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-05-05
  • mysql 數(shù)據(jù)庫安裝經(jīng)驗(yàn)問題匯總

    mysql 數(shù)據(jù)庫安裝經(jīng)驗(yàn)問題匯總

    這篇文章主要介紹了mysql 數(shù)據(jù)庫安裝經(jīng)驗(yàn)問題匯總,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-09-09
  • MySQL索引失效的14種場景分享

    MySQL索引失效的14種場景分享

    作為一名后端程序員,經(jīng)常會(huì)對慢查詢SQL語句進(jìn)行調(diào)優(yōu),而SQL語句出現(xiàn)慢查詢,很多情況是由于索引失效造成的,本文為大家整理了14種MySQL索引失效的場景,需要的可以參考一下
    2023-05-05
  • Windows?本地安裝?Mysql8.0圖文教程

    Windows?本地安裝?Mysql8.0圖文教程

    本文介紹了如何在Windows本地安裝Mysql8.0。從下載Mysql8.0安裝包,運(yùn)行安裝程序,配置初始設(shè)置到啟動(dòng)Mysql服務(wù)等詳細(xì)步驟進(jìn)行了講解。
    2023-04-04
  • 深入理解Mysql事務(wù)隔離級別與鎖機(jī)制問題

    深入理解Mysql事務(wù)隔離級別與鎖機(jī)制問題

    MySQL默認(rèn)的事務(wù)隔離級別是可重復(fù)讀,用Spring開發(fā)程序時(shí),如果不設(shè)置隔離級別默認(rèn)用MySQL設(shè)置的隔離級別,如果Spring設(shè)置了就用已設(shè)置的隔離級別,本文重點(diǎn)給大家介紹Mysql事務(wù)隔離級別與鎖機(jī)制的相關(guān)知識(shí),一起看看吧
    2021-09-09
  • Mysql連接本地報(bào)錯(cuò):1130-host?...?is?not?allowed?to?connect?to?this?MySQL?server解決

    Mysql連接本地報(bào)錯(cuò):1130-host?...?is?not?allowed?to?connect?t

    這篇文章主要給大家介紹了關(guān)于Mysql連接本地報(bào)錯(cuò):1130-host?...?is?not?allowed?to?connect?to?this?MySQL?server的解決方法,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • MySQL多表查詢與7種JOINS的實(shí)現(xiàn)舉例

    MySQL多表查詢與7種JOINS的實(shí)現(xiàn)舉例

    最近學(xué)習(xí)了多表查詢,對此做一些筆記的整理,下面這篇文章主要給大家介紹了關(guān)于MySQL多表查詢與7種JOINS實(shí)現(xiàn)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • MySQL用戶和數(shù)據(jù)權(quán)限管理詳解

    MySQL用戶和數(shù)據(jù)權(quán)限管理詳解

    這篇文章主要為大家詳細(xì)介紹了MySQL數(shù)據(jù)庫管理中的用戶和數(shù)據(jù)權(quán)限管理,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)MySQL有一定幫助,需要的可以參考一下
    2022-08-08
  • MySQL5.5版本安裝與安裝失敗詳細(xì)講解

    MySQL5.5版本安裝與安裝失敗詳細(xì)講解

    MySQL是一款安全、跨平臺(tái)、高效的,并與PHP、Java等主流編程語言緊密結(jié)合的數(shù)據(jù)庫系統(tǒng),下面這篇文章主要給大家介紹了關(guān)于MySQL5.5版本安裝與安裝失敗詳細(xì)講解的相關(guān)資料,需要的朋友可以參考下
    2023-03-03
  • mysql視圖原理與用法實(shí)例小結(jié)

    mysql視圖原理與用法實(shí)例小結(jié)

    這篇文章主要介紹了mysql視圖原理與用法,結(jié)合實(shí)例形式分析了mysql視圖的概念、原理、創(chuàng)建、使用方法及相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2018-04-04

最新評論