天天看點

Mongodb副本集RECOVERING

今天早上突然接收到資料人員說mongodb節點挂了,正式服APP不能通路,我登入到主節點檢視叢集狀态 mongodb01這台機器是我們mongo副本集的主節點

[email protected]:~ # mongo 172.18.30.181:37017

MongoDB shell version v3.6.7

connecting to: mongodb://172.18.30.181:37017/test

MongoDB server version: 3.6.7

rset:PRIMARY> use admin

switched to db admin

rset:PRIMARY> db.auth(“使用者名”,“密碼”)

1

#上面的步驟隻是登入到節點并且切換成超級使用者模式

rset:PRIMARY> rs.status();

Mongodb副本集RECOVERING
Mongodb副本集RECOVERING

這裡發現一個問題,除了主節點以為所有的狀态都是RECOVERING ,我去看了一下mongodb的日志.(這個可以在vim /etc/mongod.conf配置檔案找日志路徑)

資訊如下:

Mongodb副本集RECOVERING

一直在報同步延遲錯誤,登上去一台從節點看一下複制集資訊

Mongodb副本集RECOVERING

可以看到這裡的mongodb的複制時間是在昨天的20:56:13左右,現在的時間已經是第二天的10:01:32了, 表示這台備庫已經斷檔很久很久了,導緻sync失敗。

經過排查初步分析是由于資料量寫入過大導緻的,因為資料人員使用爬蟲伺服器往主節點寫資料,從節點去同步資料的時候同步不過來,而主節點的oplog大小實在是太小,從節點還沒有同步完主節點就已經更新了oplog進行下一步操作了,導緻從節點跟不上主節點的速度直接斷檔了(主節點的硬體配置比從節點也要高出許多)是以我們需要再次人工同步,并調整一下oplog的大小

上網搜了一下資料,需要手動同步資料,mongo官網給了兩種辦法

1、 自動同步,最簡單也是操作最少的一種辦法,先把mongodb停止服務,然後把mongodb的資料目錄移走,建立一個mongo的資料目錄,再起服務,這樣他就會自動去追趕主庫的資料,缺點是恢複時間比較久,根據資料量來決定

2、 從另外一個成員拷貝資料檔案, 停止備庫,從primary庫copy資料檔案,在copy的時候,注意要把local庫也複制過來,複制不能采用mongodump,僅僅隻允許使用快照備份資料檔案

分析了上面的2種方式,第一種方式,清空資料目錄重新開機mongodb執行個體讓mongodb初始化同步資料,操作簡單,但是恢複時間比較長,需要花費更多時間替換資料,第二種方式從副本集合的另外一個成員拷貝資料目錄後重新開機mongodb執行個體,這個恢複過程速度快但是需要比較多的手工操作步驟,為了友善和簡單,我這裡用第一種方式

一、把資料重新同步

1、再此之前先把mongodb的服務給停了,進去mongo裡use admin庫再輸入db.shutdownServer()

Mongodb副本集RECOVERING

2、然後進去mongodb的資料存放目錄

[email protected]:~ # cd /data

Mongodb副本集RECOVERING

我的mongo的資料放在這個檔案夾裡,現在把原來的資料改個名字 建立一個mongo的資料檔案夾,要知道自己的資料檔案夾放哪裡可以看/etc/mongod.conf檔案

[email protected]:/data # mv mongo mongo.bak #給舊的mongo資料檔案進行改名

[email protected]:/data # mkdir mongo #建立新的mongo檔案夾

[email protected]:~ # mongod -f /etc/mongod.conf #啟動mongodb

Mongodb副本集RECOVERING

啟動成功 沒有報錯

檢視一下新檔案夾, mongodb副本集已經在向主節點同步資料了

Mongodb副本集RECOVERING

登陸一下mongodb,切換超級使用者(沒有設定的不用做這個操作,我的mongodb做了設定不切換超級使用者無法執行指令)

Mongodb副本集RECOVERING

rset:STARTUP2> rs.status(); #檢視一下叢集資訊

Mongodb副本集RECOVERING

發現剛才重新開機的這台狀态已經變成startup2了,接下來的就是等待了

等了大概一天同步資料,登上去看看

rset:PRIMARY> rs.status()

Mongodb副本集RECOVERING

發現這個節點的資料已經恢複了,并加入了叢集裡,其他的副本集如果也是RECOVERING也要做相同的操作,總的來說就是停止服務,然後移走老的資料檔案夾,建立新的檔案夾,再起服務等他自己同步

二、把oplog調整大一點,防止以後又出現這種情況

參考至mongodb官方文檔

https://docs.mongodb.com/manual/tutorial/change-oplog-size/

1、進入mongodb

rs0:SECONDARY> db.printReplicationInfo(); #檢視目前副本集oplog狀态,可以看到現在是2000MB的

configured oplog size: 2000MB

log length start to end: 0secs (0hrs)

oplog first event time: Thu Nov 08 2018 22:23:46 GMT+0800 (CST)

oplog last event time: Thu Nov 08 2018 22:23:46 GMT+0800 (CST)

now: Thu Nov 08 2018 17:45:42 GMT+0800 (CST)

rs0:SECONDARY> db.adminCommand({replSetResizeOplog: 1, size: 4000}) #調整oplog大小為4000MB

Mongodb副本集RECOVERING

rs0:SECONDARY> db.printReplicationInfo(); #再檢視一下,變成4000MB了

Mongodb副本集RECOVERING

2、測試一下同步情況正不正常

rs0:PRIMARY> for(var i=0;i<4;i++){db.test.insert({“name”:“test”+i,“age”:123})} #在主節點插入4條資料測試一下

WriteResult({ “nInserted” : 1 })

rs0:PRIMARY> db.test.find() #檢視資料是否插入

{ “_id” : ObjectId(“5be406de8da5c06ab0e7727f”), “name” : “test0”, “age” : 123 }

{ “_id” : ObjectId(“5be406de8da5c06ab0e77280”), “name” : “test1”, “age” : 123 }

{ “_id” : ObjectId(“5be406de8da5c06ab0e77281”), “name” : “test2”, “age” : 123 }

{ “_id” : ObjectId(“5be406de8da5c06ab0e77282”), “name” : “test3”, “age” : 123 }

Mongodb副本集RECOVERING

去從節點看一下,資料确實插入了

rs0:SECONDARY> db.test.find()

{ “_id” : ObjectId(“5be406de8da5c06ab0e77281”), “name” : “test2”, “age” : 123 }

{ “_id” : ObjectId(“5be406de8da5c06ab0e77280”), “name” : “test1”, “age” : 123 }

{ “_id” : ObjectId(“5be406de8da5c06ab0e77282”), “name” : “test3”, “age” : 123 }

{ “_id” : ObjectId(“5be406de8da5c06ab0e7727f”), “name” : “test0”, “age” : 123 }

Mongodb副本集RECOVERING