MongoDB複製集資料同步流程

賀子_DBA時代發表於2019-12-13


本文轉自張友東的文章,文章連結:

正好解釋了我的問題,所以轉發記錄下

Mongodb複製集裡的Secondary會從Primary上同步資料,以保持副本集所有節點的資料保持一致,資料同步主要包含2個過程:

  1. initial sync
  2. replication (oplog sync)

先透過init sync同步全量資料,再透過replication不斷重放Primary上的oplog同步增量資料。

initial sync

Secondary啟動後,如果滿足以下條件之一,會先進行initial sync

  1. Secondary上oplog為空,比如新加入的空節點
  2. local.replset.minvalid集合裡_initialSyncFlag標記被設定。當initial sync開始時,同步執行緒會設定該標記,當initial sync結束時清除該標記,故如果initial sync過程中途失敗,節點重啟後發現該標記被設定,就知道應該重新進行initial sync。
  3. BackgroundSync::_initialSyncRequestedFlag被設定。當向節點傳送resync命令時,該標記會被設定,此時會強制重新initial sync。

initial sync同步流程

  1. minValid集合設定_initialSyncFlag
  2. 獲取同步源當前最新的oplog時間戳t0
  3. 從同步源Clone所有的集合資料
  4. 獲取同步源最新的oplog時間戳t1
  5. 同步t0~t1所有的oplog
  6. 獲取同步源最新的oplog時間戳t2
  7. 同步t1~t2所有的oplog
  8. 從同步源讀取index資訊,並建立索引
  9. 獲取同步源最新的oplog時間戳t3
  10. 同步t2~t3所有的oplog
  11. minValid集合清除_initialSyncFlag,initial sync結束

replication (sync oplog)

initial sync結束後,Secondary會建立到Primary上local.oplog.rs的tailable cursor,不斷從Primary上獲取新寫入的oplog,並應用到自身。

Tailable cursor每次會獲取到一批oplog,Secondary採用多執行緒重放oplog以提高效率,透過將oplog按照所屬的namespace進行分組,劃分到多個執行緒裡,保證同一個namespace的所有操作都由一個執行緒來replay,以保證統一namespace的操作時序跟primary上保持一致(如果引擎支援文件鎖,只需保證同一個文件的操作時序與primary一致即可)。

同步場景分析

1. 副本集初始化

初始化選出Primary後,此時Secondary上無有效資料,oplog是空的,會先進行initial sync,然後不斷的應用新的oplog

2. 新成員加入

因新成員上無有效資料,oplog是空的,會先進行initial sync,然後不斷的應用新的oplog

3. 有資料的節點加入

有資料的節點加入有如下情況:

  1. 該節點與副本集其他節點斷開連線,一段時間後恢復
  2. 該節點從副本集移除(處於REMOVED)狀態,透過replSetReconfig命令將其重新加入
  3. 其他? 因同一個副本集的成員replSetName配置必須相同,除非有誤配置,應該不會有其他場景

此時,如果該節點最新的oplog時間戳,比所有節點最舊的oplog時間戳還要小,該節點將找不到同步源,會一直處於RECOVERING而不能服務;反之,如果能找到同步源,則直接進入replication階段,不斷的應用新的oplog。

因oplog太舊而處於RECOVERING的節點目前無法自動恢復,需人工介入處理(故設定合理的oplog大小非常重要),最簡單的方式是傳送resync命令,讓該節點重新進行initial sync。

參考資料

  1. Create tailable cursor

作者簡介

,就職於阿里雲飛天技術部,主要關注分散式儲存、Nosql等技術領域,參與 、 等專案的開發工作,歡迎交流


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29654823/viewspace-2668577/,如需轉載,請註明出處,否則將追究法律責任。

相關文章