1. 程式人生 > >Mongodb副本集RECOVERING

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();
首長愛吃麵


在這裡插入圖片描述
這裡發現一個問題,除了主節點以為所有的狀態都是RECOVERING ,我去看了一下mongodb的日誌.(這個可以在vim /etc/mongod.conf配置檔案找日誌路徑)
資訊如下:
在這裡插入圖片描述
一直在報同步延遲錯誤,登上去一臺從節點看一下複製集資訊

在這裡插入圖片描述
可以看到這裡的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()
在這裡插入圖片描述

2、然後進去mongodb的資料存放目錄
[email protected]:~ # cd /data
在這裡插入圖片描述
我的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副本集已經在向主節點同步資料了
在這裡插入圖片描述

登陸一下mongodb,切換超級使用者(沒有設定的不用做這個操作,我的mongodb做了設定不切換超級使用者無法執行命令)
在這裡插入圖片描述
rset:STARTUP2> rs.status(); #檢視一下叢集資訊
在這裡插入圖片描述
發現剛才重啟的這臺狀態已經變成startup2了,接下來的就是等待了

等了大概一天同步資料,登上去看看
rset:PRIMARY> rs.status()
在這裡插入圖片描述
發現這個節點的資料已經恢復了,並加入了叢集裡,其他的副本集如果也是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

在這裡插入圖片描述

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

在這裡插入圖片描述

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 }

在這裡插入圖片描述

去從節點看一下,資料確實插入了
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 }

在這裡插入圖片描述