1. 程式人生 > >記一次"詭異"的mongodb程序退出事件

記一次"詭異"的mongodb程序退出事件

shell中通過mongo args &的方式啟動mongo程序,退出shell重新登進之後發現mongo程序沒了,檢視日誌發現有如下輸出:

2015-06-18T18:39:58.593+0800 [signalProcessingThread] got signal 1 (Hangup), will terminate after current cmd ends
2015-06-18T18:39:58.593+0800 [signalProcessingThread] now exiting
2015-06-18T18:39:58.593+0800 [signalProcessingThread] dbexit:
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: going to close listening sockets…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] closing listening socket: 8
2015-06-18T18:39:58.593+0800 [signalProcessingThread] closing listening socket: 10
2015-06-18T18:39:58.593+0800 [signalProcessingThread] removing socket file: /tmp/mongodb-27017.sock
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: going to flush diaglog…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: going to close sockets…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: waiting for fs preallocator…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: lock for final commit…
2015-06-18T18:39:58.593+0800 [signalProcessingThread] shutdown: final commit…
2015-06-18T18:39:58.603+0800 [replslave] repl: AssertionException dbclient error communicating with server: 172.19.2.176:27017
2015-06-18T18:39:58.615+0800 [signalProcessingThread] shutdown: closing all files…
2015-06-18T18:39:58.642+0800 [signalProcessingThread] closeAllFiles() finished
2015-06-18T18:39:58.642+0800 [signalProcessingThread] journalCleanup…
2015-06-18T18:39:58.642+0800 [signalProcessingThread] removeJournalFiles
2015-06-18T18:39:58.643+0800 [signalProcessingThread] shutdown: removing fs lock…
2015-06-18T18:39:58.643+0800 [signalProcessingThread] dbexit: really exiting now

可以看到有其他程序給mongo發了Hangup資訊,就如同kill -1 pid,但可以確認的是沒有人手動訊號給mongodb程序,google之後發現這篇文章
原因大致如下:
Bash resends a SIGHUP to all jobs if it receives a SIGHUP itself; this would include mongod.
Also, if you happen to have huponexit turned on, every job will receive a SIGHUP when bash exits.
https://www.gnu.org/software/bash/manual/html_node/Signals.html

原來我用shell登進之後啟動了mongo,然後退出shell使用的方式是直接關掉視窗,linux認為這是一起異常退出,這樣一來這個shell程序就會收到SIGHUP訊號,為了保證狀態一致性,從而給它的所有子程序傳送SIGHUP訊號.而使用命令exit退出就不會有這種問題,因為linux會認為這是一種正常的退出
那麼如何避免這種問題呢? 直接關閉視窗可能是很多人的習慣了(陋習),所以我們不能要求linux管理員總是這樣做,是人就有可能會犯錯,應該從根本上解決這個問題
檢視mongodb官方文件會發現mongo有–fork這樣的一個引數,使用該引數啟動mongo時,會自動將其掛到init程序(pid為1)下啟動,而不加的話ppid(父程序id)就是當前的shell程序,所以只要加上–fork問題就引刃而解了,這裡需要注意的是,所有需要在後臺執行的程式都需要注意該情況,務必採用像mongo –fork的方式執行
關於Linux的signal(訊號)和bash更多內容請自行關注man bash