MongoDB 4 0 啟動失敗問題定位

2021-10-11 03:11:36 字數 2808 閱讀 2675

mongod是啟動mongodb的主程式,該程式通過命令列引數或者配置檔案進行啟動。

mongod會在mongodb異常關閉後(例如oom killer前置關閉mongo程序),執行恢復過程,無需採用repair引數啟動,因此正常情況下mongo啟動會成功的,除非有錯誤。錯誤通過錯誤日誌可以排除。

本篇的問題現象是,mongo被oom kill之後,多次重新啟動後,mongod主動關閉,日誌大概如下:

[initandlisten] assertion failure kill(serverglobalparams.leaderproc.tonative(), 12) == 0 src/mongo/db/initialize_server_global_state.cpp 103

----- begin backtrace -----

,...

[shardservercatalogcacheloader-0] marking host m4.mongo.cnbd:27003 as failed :: caused by :: shutdowninprogress: connection pool is in shutdown

或者

[signalprocessingthread] shutting down replication subsystems ..

.[signalprocessingthread] got signal 1

(hangup)

, will terminate after current cmd ends

[signalprocessingthread] shutting down replication subsystems

此環境我在恢復乙個一主一從的db分片庫時,出現的錯誤日誌,日誌提示恢復資料成功後,mongodb主動關閉,導致恢復失敗,嘗試過程啟動方式後無果,經過分析mongodb的啟動過程,並親自寫**做實驗,發現mongodb的啟動的乙個小漏洞。

當提示「will terminate after current cmd ends」表示系統在執行完當前命令後就會停止執行,如果是在啟動的恢復過程,那麼在恢復執行完成後停止。(mongo的oplog日誌恢復後,如果主從狀態沒有達成一致是不會固化oplog的,這意味著下次重啟需要重新恢復,如果oplog很大,那麼恢復時間就很長)

從上圖可以看出該問題已經關閉,開發團隊的答覆是;

we think this is currently functioning as we would expect.

大意就是:我們認為當前該功能是如我們所期望的那樣。

那……我的檔案無解嗎?特意檢視了mongod的啟動過程,如下:

首先mongo會在啟動的時候,派生子程序和孫程序,這個邏輯是為mongodb主程式執行在後台做守護程序做準備,具體原因可以參考這裡,這都沒有問題。可是,如果啟動mongo沒有結束,那麼主程序就不會結束(啟動成功會提示fork successfully)。啟動過程中,會出現父程序/子程序/孫程序三代同堂的場景(通過ps -ef | grep mongod可以檢視)。此時如果是通過ssh連線,如果沒有採用nohup啟動,那麼等mongo載入完畢後,mongodb會自動退出(原始碼後面論述)。這裡注意,把mongod作為後台啟動後,如果終端異常退出,程序依然會關閉,分析參考這裡。

經過分析,我任務問題出在沒有採用nohup導致啟動失敗,可是事情遠沒有這麼簡單,我自信的任務我用nohup啟動後一定可以啟動,可是事實再一次打臉(我的oplog日誌50+gb,恢復需要4-5天時間)。

我懷疑是nohup有什麼問題,如是採用screen方式啟動……結果執行一天之後,發現恢復沒有結束,程序只留下孫程序,如此經過幾天之後,一定會自動關閉的。

上一段引起此問題引起傷心的**:r4.0.7

void signalforksuccess() 

}

上述**就是在mongdb恢復完成後,會執行fork成功的函式,該函式有乙個verify驗證kill傳送sigusr2訊號是否成功,該訊號是發給父程序的,如果父程序不在,那麼該驗證一定會失敗,導致程式退出。該**也是官方任務是合理的,是他們期望的工作方式。

期望的工作方式,為什麼有問題呢,恢復經過半個月的嘗試依舊失敗,業務一致掛起!傷心!(對不起我的客戶)

作為程式設計師,我知道,問題一定在某個地方。

我懷疑nohup時,我通過screen方式啟動mongod後(screen的優點請看這裡),第二天發現螢幕上有乙個:「signal 1」的訊息,我知道了……一切後果都是有原因的。

大家知道,sigusr1是mongo的日誌迴旋功能訊號,該功能可以讓mongo日誌截斷,避免日誌檔案過大,而無法清理。而這裡的訊號1就是sigusr1.

原來問題出在這兒!因為我之前為了清理日誌方便,寫了定時任務,每日給所有mongod程序傳送sigusr1訊號進行日誌迴旋操作。可是,如果在恢復的時候,此時三代同堂,那麼父程序和子程序也會接收到該型號(我的指令碼是遍歷所有mongod程序的),那麼如果沒有設定訊號處理器的程式就會採用預設動作終止程式。這三個程序中,只有孫程序處理了sigusr1訊號,導致留下未完成恢復使命的孫程序,等他恢復完後,無法傳送關閉祖父的訊號時,他會默默的停止服務……

所以……如果需要恢復資料庫,且需要耗費較長時間,那麼請一定要關閉日誌清理定時任務!切記!

那麼mongod的正確啟動姿勢為:

nohup mongod -f /xx/mongod.conf > mongo-boot.log 2>&1 &

mongodb4 0 資料遷移

我們的mongodb使用的是阿里雲的雲資料庫 mongodb4.0 昨天新買的mongo需要把舊的mongo做一次遷移,發現阿里雲的dts還不支援4.0版本,於是要自己動手遷移了.用root賬號連上新開通的mongodb,然後新建我們要的資料庫efiles,使用者 efile,密碼 123456,授...

CentOS 上面安裝 MongoDB 4 0

傳入到linux系統中 通過命令列工具來安裝 解壓 重新命名 將解壓出來的mongodb 資料夾重新命名 root centos usr mv mongodb linux x86 86 4.0.1.tgz mongodb 進入 mongodb 新增環境變數mongodb 的可執行檔案位於 bin 目...

mongoDB4 0新增使用者許可權

下面資訊給自己做筆記,防止時間長,會忘記 在mongo安裝的bin目錄,開啟cmd,登入mongo,使用以下命令,建立使用者 db.createuser readwriteanydatabase 在服務中,找到mongodb服務 使用管理員許可權,開啟cmd,輸入sc delete mongodb服...