close
在mongodb replica set中加入新node時,如果因資料量太大,
造成新node最後停在recovering狀態而不可用.
(另外也可以用seed的方式,但也有其極限)
 
紀錄如何oplog來解決這問題,
第一步 => 正常加node
 
第二步 => 定時備分oplog,這邊有個假設,mongo的operation是順序寫入的
(這部分可以參考這篇文章[MongoDB同步原理解析],在producer是單一thread,所以理論上是順序的)
注意事項 : oplog的備分,不使用--oplog參數(開始與結束timestamp,取得複雜),不使用--archive參數(不支援解壓),
只要能將oplog.rs備分bson檔即可.
Ex:
 
第三步 =>
  1. 如果正常完成sync的步驟 => startup2 -> secondary
  2. 如果在重放oplog後,發現新node的optime比rs.printReplicationInfo() 所顯示的 oplog first event time還早 => startup2 -> Recovering
 
2.的情況就適用本篇所述方式,方法如下:
a.
當處於Recovering的狀態時,以rs.status()檢查Recovering node的optime或optimeDate.
選擇包含此時間點之後的所有oplog備分,依照順序改名稱為oplog.bson至於任意folder之下並replay.
 
Ex:下圖4個oplog.rs的備分檔是滿足optimeDate之後的所有備分檔
oplog.rs.png
b.
保留新node在replica set內,接著將新node使用standlone重啟,
針對此4個bson,個別執行更名回放.
(注意dump目錄下只能有一個oplog.bson)
Ex:
cp 2018-01-22_05_35.bson dump/oplog.bson
mongorestore --host IP --port PORT -u USER-p PASSWORD --oplogReplay dump/
在依次對2018-01-22_05_36.bson, 2018-01-22_05_37.bson, 2018-01-22_05_38.bson作相同操作.
 
c.
查看最後一個回放的bson檔最後一個操作的"ts","t","h","op","v","ns","o"等資訊,
並在local db內的oplog.rs寫入一筆新資料;在replset.minvalid刪除原資料並重新寫入一筆.
最後改成replica set重啟.檢查是否正常跟上其他nodes.
Ex:
oplog內容.png
針對oplog.rs與replset.minvalid 寫成insert query
 
db.oplog.rs.insert({
        "ts" : Timestamp(1516613871, 1),
        "t" : NumberLong(11),
        "h" : NumberLong("-5372784966925994798"),
        "v" : 2,
        "op" : "n",
        "ns" : "",
        "o" : {
                "msg" : "periodic noop"
        }
})
 
db.replset.minvalid.remove({})
db.replset.minvalid.insert(
{
        "oplogDeleteFromPoint" : Timestamp(0, 0),
        "ts" : Timestamp(1516613871, 1),
        "t" : NumberLong(11)
})
之後以replica set member重啟.
 
註1:沒測試過使用的oplog內包含ddl操作.
註2:當回放的速度比產生新的oplog.rs檔更慢時,是永遠跟不上的.
 
參考GitHub的資料
arrow
arrow

    abcg5 發表在 痞客邦 留言(0) 人氣()