OOM故障處理流程


一、OOM機制概述

Linux 內核有個機制叫OOM killer(Out Of Memory killer),該機制會監控那些占用內存過大,尤其是瞬間占用內存很快的進程,為防止內存耗盡而自動把該進程殺掉。

進程被Linux殺掉幾個可能的原因:

  • 內存泄露;
  • 你的進程所需要的內存資源太大,系統無法滿足;
  • 也不一定全是你的問題,也有可能是同一主機的其他進程占用資源過多。

數據庫OOM可能的故障現象:

  • 數據庫切換、服務中斷 ……
  • 通過數據庫的log確認有進程被kill 9,然后通過同時間的系統日志確認

二、操作系統參與OOM

vm.overcommit_memory 接受三種值:

  • 0 – 這是缺省值,它允許overcommit,但過於明目張膽的overcommit會被拒絕,比如malloc一次性申請的內存大小就超過了系統總內存。
  • 1 – 允許overcommit,對內存申請來者不拒。
  • 2 – 禁止overcommit。

OOM參數影響系統的可分配內存。舉例如下:操作系統內存 4G、swap 2G。以 kingbase 為例,shared_buffers 最大值:

  • vm.overcommit_memory = 0 , shared_buffers 最大值為 6G
  • vm.overcommit_memory = 1 , shared_buffers 最大值可以超過 6G,沒有限制
  • vm.overcommit_memory = 2 , 根據 (物理內存 + swap)* overcommit_ratio 確定可分配的內存,相當於可用內存不超過3G(所有進程可用的總內存,包括操作系統占用)。 默認 overcommit_ratio 50%。

如果vm.overcommit_memory = 2,正常不會發生OOM,只是在執行時報錯。類似如下:

ERROR:  out of memory
DETAIL:  Failed on request of size 16384 in memory context "ExecutorState".

三、OOM問題原因排查

1、查看操作系統日志

grep "Out of memory" /var/log/messages*
  Out of memory: Kill process <pid>(checkpoint) score 9 or sacrifice child
  checkpoint invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0

有的系統Log里會輸出kill時的全部進程和每個進程的內存使用情況,用於確認當時的情況。

dmesg -T
[Wed May 15 14:03:08 2019] Out of memory: Kill process 83446 (machine) score 250 or sacrifice child
[Wed May 15 14:03:08 2019] Killed process 83446 (machine) total-vm:1920560kB, anon-rss:1177488kB, file-rss:1600kB

2、確認問題時間點的內存使用情況

Linux 系統默認每10分鍾會收集系統狀態,數據保存在/var/log/sa 目錄。用戶可以找到對應時間點的文件,運行sar命令,如:sar -r -f sa04 ,取得當時的系統狀態信息。類似結果顯示如下:

 

 

從上圖可以看出,10:40 左右,系統可用內存不足,接着引發oom,之后可用內存恢復。

3、操作系統內存排查

查看系統內存使用情況:查看系統內存,關注可用內存情況:

free –g

cat /proc/meminfo

 

查看進程占用內存情況:

ps aux | sort -nrk5 | more 查看TOP VSZ ,表示請求的共享內存段的大小。這個並不表示實際分配的內存段,如shared_buffer = 1024M,但實際啟動時並沒有真正分配1024M內存(除非使用大頁)。

ps aux | sort –nrk6 | more  查看每個進程實際占用的物理內存大小

注:當前時間點內存占用並不能反應OOM時間點實際內存占用情況,只能查看哪些進程是可能的影響因素。

 

清除linux系統的cache

# echo 3 > /proc/sys/vm/drop_caches

4、排查OOM時間點的運行業務

  1. 如有可能,逐個停止、排查業務,確認最占用系統內存的業務。
  2. 如果所有業務都停止后,還未釋放內存,那可能是操作系統占用,需要排查操作系統問題。如以上例子,停止所有業務應用后,操作系統還占用大量內存,需要排查操作系統問題。
  3. 查看問題時間點,是否有crontab , job 等定時任務,確認是否有長時間運行的任務。
  4. 查看數據庫sys_log,確認是否有耗時的SQL、大量量臨時IO的SQL。
  5. 如果是 R6 版本,可以分析問題時間點kwr , ksh 報告。

5、查看數據庫內存配置參數

查看數據庫內存配置參數,計算主機可承受的負荷。樣例數據如下:

主機內存:                           256G

SWAP:                                   22G

shared_buffers:                 100G

max_connections:   4000

work_mem:                        100M     

temp_buffers:          32M

wal_buffers:              64M

autovacuum_max_workers:   3

autovacuum_work_mem:        -1

maintenance_work_mem:      10G

current connections:        150

 

數據庫占用內存計算公式:max_connections*work_mem + max_connections*temp_buffers +shared_buffers+wal_buffers+(autovacuum_max_workers * autovacuum_work_mem)+ maintenance_work_mem

數據庫理論峰值 =4000 * 100M + 4000 * 32M + 100G + 64M + 10G = 620G

數據庫當前值 = 150 * 100M + 150 * 32M + 100G + 64M + 10G = 130G

主機可承受連接數極值 = ( 250G - 100G - 10G ) / ( 100M + 32M ) = 1080

注意:這里的極限值其實是以每個連接占用132M 進行估算的,實際會話可能並不會占用這么多內存,且並不會有同時這么多並發排序操作。

 


免責聲明!

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



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