記一次系統錯誤問題的排查經驗-----sh: can't fork
最近系統出現了一個莫名其妙的問題,就是執行一段時間之後出現了很多奇怪的異常現象,所以第一反應是看一下程序的執行情況、記憶體佔用情況和cpu利用情況,但是更加奇怪的問題是無論是執行ps還是free都出現了sh: can't fork的錯誤資訊,這是什麼鬼東西,去Google搜尋了各種資料(不要問我怎麼上的Google,你懂的),沒有得到任何有用的資訊,所以智慧靠感覺定位了額,既然沒辦法fork,可能是記憶體被佔用完了,那麼目前就需要確認系統的記憶體使用情況。
1、free命令用不了,ls也出現報錯,通過各種方式最後在/proc路徑下vi meminfo看到了記憶體資訊,內容如下:
MemTotal: 16357468 kB
MemFree: 4878352 kB
MemAvailable: 7485820 kB
Buffers: 538576 kB
Cached: 1894516 kB
發現記憶體還有4個多G沒使用完,那麼就能排除記憶體不足導致的fork出現錯誤了。
2、既然不是記憶體問題,那麼還有什麼原因導致了,我查了fork的相關介面程式碼,發現fork主要動作是建立子程序,建立子程序如果記憶體充足怎麼會建立失敗呢?後來搜到一個命令ulimit -a檢視系統當前使用者的資源限制資訊,才知道可能是執行緒數超過了系統的最大限制數量,從而導致的fork失敗的發生。為了驗證這個猜想我查看了ulimit -a命令結果:
HH:~#ulimit -a
-f: file size (blocks) unlimited
-t: cpu time (seconds) unlimited
-d: data seg size (kb) unlimited
-s: stack size (kb) 8192
-c: core file size (blocks) unlimited
-m: resident set size (kb) unlimited
-l: locked memory (kb) 64
-p: processes 63893
-n: file descriptors 65535
-v: address space (kb) unlimited
-w: locks unlimited
-e: scheduling priority 0
-r: real-time priority 0
發現系統限制的最大執行緒數為63893。由於許多美麗沒法執行,所以就殺掉一個已知程序號的程序,幸好kill可以使用,通過kill -15 XXX和kill -9 XXX殺掉一個程序之後,很多操作就能進行了,沒有再出現can't fork的報錯,所以該問題就鎖定了原因:建立執行緒的數量超過了系統限制該使用者建立的數量,所以就出現了異常。