Linux OOM 自動殺死進程



問題描述:

今天上班后,登錄一台內網測試服務器,發現部分進程失蹤 (Nginx/PHP-FPM/MySQL/Crond)。

解決方法:

1、首先啟動這些進程,保證正常提供服務。

2、查看服務器日志信息,排除故障。

shell > less /var/log/messages-20160905

Sep  3 05:31:10 localdomain kernel: Out of memory: Kill process 3145 (mysqld) score 33 or sacrifice child
Sep  3 05:31:10 localdomain kernel: Killed process 3145, UID 804, (mysqld) total-vm:9170936kB, anon-rss:246880kB, file-rss:32kB

Sep  3 05:40:41 localdomain kernel: Out of memory: Kill process 20889 (nginx) score 2 or sacrifice child
Sep  3 05:40:41 localdomain kernel: Killed process 20889, UID 803, (nginx) total-vm:130256kB, anon-rss:216kB, file-rss:12kB

3、發現類似的日志信息,上網查資料。

4、資料顯示,這是由於系統內存不足導致觸發 Linux Kernel OOM(Out of memory killer)保護機制,將占用內存大的進程殺死,以保證系統正常運行。

Sep  3 05:37:10 localdomain kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Sep  3 05:37:10 localdomain kernel: mysqld cpuset=/ mems_allowed=0-1

Sep  3 05:39:30 localdomain kernel: crond invoked oom-killer: gfp_mask=0x84d0, order=0, oom_adj=0, oom_score_adj=0
Sep  3 05:40:26 localdomain kernel: crond cpuset=/ mems_allowed=0-1

Sep  3 05:40:36 localdomain kernel: php invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Sep  3 05:40:37 localdomain kernel: php cpuset=/ mems_allowed=0-1

5、還發現一種情況,內存夠用,但還是觸發了 OOM 殺死進程。這里涉及到一個 Low Memory 的知識點。內核使用 Low Memory 來跟蹤所有的內存分配。

注意:只有在 32 位操作系統中才區分 Low Memory 與 High Memory ,64 位系統中 Low Memory 就是所有內存空間。

shell > free -lm
             total       used       free     shared    buffers     cached
Mem:         11901       1039      10861          0         47        133
Low:         11901       1039      10861
High:            0          0          0
-/+ buffers/cache:        858      11042
Swap:         8191          2       8189

# 可以看到:Low 大小跟總內存一樣大,High 都為 0 。

6、那該怎么辦?

> 增加內存、使用 64 位操作系統。

> 合理配置內存空間,例如 PHP 加速器的緩存空間等,定期重啟 PHP-FPM 進程。

> 手動釋放內存:sync; echo 3 > /proc/sys/vm/drop_caches

> 使用 hugemem 內核,該內核以不同的方式分割 low/high memory ,而且多數情況下會提供足夠多的 low memory 到 high memory 的映射。
  安裝 hugemem kernel rpm 包,重啟服務器即可。
 
> 指定不殺死某進程:echo -17 > /proc/$(pidof mysqld)/oom_adj  # -17 為對該進程禁止使用 OOM

> echo "vm.panic_on_oom = 1" >> /etc/sysctl.conf; sysctl -p   # 關閉 OOM ( 后兩三種慎用吧 )

sync; echo 3 > /proc/sys/vm/drop_caches


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM