1 頁 (共 1 頁)

Linux oom-killer kernel: Out of Memory: Killed 問題處理 & 手動增加動態 swap

發表於 : 2018-12-20 11:44:52
yehlu
https://shazi.info/linux-oom-killer-ker ... 5%8B-swap/

由於今天開工第一天就遇到客戶的 CentOS Server 常常死機的狀況,Linux 在正常狀況應該是可以很穩的使用



在查看 /var/log/message 後,發現在死機前常有 Out of Memory 的問題發生,導致 kernel killed 了一些 process



OOM-killer (Out of Memory-killer)

顧名思義就是記憶體不足導致系統自動 Killer 一些程序,OOM-killer 存在於 Linux 較新的核心版本(2.6),比較麻煩的是造成死機的原因通常是因為 OOM-killer 殺掉了一些必要的執行程序,因為 oom-killer 僅考慮 lowmemory,即使物理記憶體還有許多 free/cache/buffer,只要 swap 不足就開始 oom-killer。




/var/log/message


Feb 20 11:19:33 Server kernel: Out of memory: Kill process 7352 (httpd) score 67 or sacrifice child
Feb 20 11:19:33 Server kernel: Killed process 7352, UID 48, (httpd) total-vm:1127828kB, anon-rss:309416kB, file-rss:20kB
1
2
Feb 20 11:19:33 Server kernel: Out of memory: Kill process 7352 (httpd) score 67 or sacrifice child
Feb 20 11:19:33 Server kernel: Killed process 7352, UID 48, (httpd) total-vm:1127828kB, anon-rss:309416kB, file-rss:20kB






OOM-killer 在挑選 kill 的對象是有依據的,可以參考內核源碼 oom_kill.c,當 out_of_memory() 被觸發後,會由 oom_badness() 來挑選最佔用記憶體的程序,誰的得分最高就是被 kill 掉的那位幸運兒。



那麼要如何得知哪一個程式容易被 kill,可以嘗試下面的方法來找出最有可能被 oom-killer 殺掉的程序


$ cat /proc/23681/oom_score
10
1
2
$ cat /proc/23681/oom_score
10
這一段主要是取得 pid 23681 的 oom 分數,分數越高則優先被 oom-killer 挑選到。



你也可以編寫底下 script 來印出目前系統 oom_score 分數最高的前 20 名程式


$ vim oom-killer-score.sh

#!/bin/bash
for proc in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do
printf "%2d %5d %s\n" \
"$(cat $proc/oom_score)" \
"$(basename $proc)" \
"$(cat $proc/cmdline | tr '\0' ' ' | head -c 50)"
done 2>/dev/null | sort -nr | head -n 20


$ ./oom-killer-score.sh

9 6472 php-fpm: pool php-wp
9 6471 php-fpm: pool php-wp
8 8723 php-fpm: pool php-wp
8 23232 php-fpm: pool php-wp
8 10333 php-fpm: pool php-wp
7 9362 php-fpm: pool php-wp
7 6475 php-fpm: pool php-wp
7 23231 php-fpm: pool php-wp
7 20807 php-fpm: pool php-wp
7 15521 php-fpm: pool php-wp
7 15520 php-fpm: pool php-wp
7 15518 php-fpm: pool php-wp
6 31050 php-fpm: pool php-wp
6 21170 php-fpm: pool php-wp
6 15524 php-fpm: pool php-wp
6 15522 php-fpm: pool php-wp
6 15517 php-fpm: pool php-wp
6 15157 php-fpm: pool php-wp
5 2835 php-fpm: pool php-wp
3 23681 /usr/libexec/mysqld --basedir=/usr --datadir=/var/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
$ vim oom-killer-score.sh

#!/bin/bash
for proc in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do
printf "%2d %5d %s\n" \
"$(cat $proc/oom_score)" \
"$(basename $proc)" \
"$(cat $proc/cmdline | tr '\0' ' ' | head -c 50)"
done 2>/dev/null | sort -nr | head -n 20


$ ./oom-killer-score.sh

9 6472 php-fpm: pool php-wp
9 6471 php-fpm: pool php-wp
8 8723 php-fpm: pool php-wp
8 23232 php-fpm: pool php-wp
8 10333 php-fpm: pool php-wp
7 9362 php-fpm: pool php-wp
7 6475 php-fpm: pool php-wp
7 23231 php-fpm: pool php-wp
7 20807 php-fpm: pool php-wp
7 15521 php-fpm: pool php-wp
7 15520 php-fpm: pool php-wp
7 15518 php-fpm: pool php-wp
6 31050 php-fpm: pool php-wp
6 21170 php-fpm: pool php-wp
6 15524 php-fpm: pool php-wp
6 15522 php-fpm: pool php-wp
6 15517 php-fpm: pool php-wp
6 15157 php-fpm: pool php-wp
5 2835 php-fpm: pool php-wp
3 23681 /usr/libexec/mysqld --basedir=/usr --datadir=/var/












如果你的機器真的沒辦法增加內存,又必須要執行這麼大的程式,可以參考以下方法



1. 增加動態 swap 空間

適合一開始安裝系統沒有分配好 swap 導致 swap 過小的問題,可以在安裝系統後增加動態 swap 來解決 swap 不足的窘境。

step1. 建立 swap 區,示範 4GB


$ dd if=/dev/zero of=/swap bs=1024 count=$[1024*1024*4]
1
$ dd if=/dev/zero of=/swap bs=1024 count=$[1024*1024*4]


step2. 將 /swap 設定為 swap 檔案型式


$ mkswap /swap
1
$ mkswap /swap


step3. 啟動 file mode swap


$ swapon /swap
1
$ swapon /swap


step4. 查看 /swap 有沒有被掛載上


$ swapon -s
Filename Type Size Used Priority
/dev/sda2 partition 2050040 0 -1
/swap file 4019160 0 -2
1
2
3
4
$ swapon -s
Filename Type Size Used Priority
/dev/sda2 partition 2050040 0 -1
/swap file 4019160 0 -2


step5. 設定開機自動掛載 file swap


$ vim /etc/fstab
/swap swap swap defaluts 0 0
$ reboot
1
2
3
$ vim /etc/fstab
/swap swap swap defaluts 0 0
$ reboot
若是要卸除 file swap 可以使用 swapoff /swap,記得 fstab 也要砍掉!



2. 有必要時停用 OOM-Killer

必須注意停用 OOM-killer 代表當 OOM 產生時無法再提供新的記憶體行為,都會被 request error。


$ echo 1 > /proc/sys/vm/overcommit_memory
1
$ echo 1 > /proc/sys/vm/overcommit_memory