MongoDB3.2 之 Rollback講解及避免

前言

前段時間忽然發現數據庫文件路徑下多了個rollback名字的文件夾,非常納悶,裏面竟然還有.bson後綴格式的文件,隨一探究竟。
原來是在這段時間內發生過failover(主從切換),致使了某些不一致數據的丟失,這但是一個大問題啊,弄很差就是要丟數據的,
故進行了些調查研究,詳述於此;供大蝦們大繩們指點。mongodb

解釋

首先,rollback究竟是什麼意思呢?在關係型數據庫中由於有事務的概念,操做數據後在沒有commit以前是能夠執行rollback命令進行數據回退的。
而在單實例mongodb中,寫入就寫入了,刪除就刪除了,沒有事務的概念,也沒有rollback的操做,因此這裏要討論的是replicaset(複製集)的rollback數據庫

事故演示

以下圖架構,在primary上執行寫操做
圖片描述
圖片描述
圖片描述網絡

步驟1: 客戶端向Primary寫入3筆數據 一、二、3, 通過oplog日誌後同步到secondary節點上,此時各個節點數據一致
步驟2: 但當Primary節點再次被寫入一筆數據4的時候,發生宕機,此時 數據4 還沒來得及同步到從節點上
步驟3: 此時集羣短期關閉寫操做開始競選,通過一系列選舉後有了新的primary節點,此時新Primary節點上是沒有數據4的
步驟4: 新的primary承接了客戶端的write請求,寫入新數據 5,此時新primary的數據狀態爲1,2,3,5
步驟5: 原primary節點從新啓動後申請加入replica member做爲secondary節點,由於此時它與新primary數據不一致,因此就會發生rollback(回滾)動做,將數據狀態恢復爲1,2,3
步驟6:回滾完以後,將繼續同步新primary節點的數據,以後數據狀態變爲1,2,3,5架構

rollback發生的具體過程:

請看下圖:
圖片描述測試

流程說明

客戶端驅動在鏈接mongo以後進行寫操做的大體流程就是這樣的,寫操做會按照編號順序進行, 當Client收到5號的response反饋後即認爲寫入成功,
而如何數據已寫入journal files,可是還沒有oplog同步到Secondary節點重放,若是此時發生Primary宕機,則就會形成主從之間數據不一致,即原Primary中有
剛纔新寫入的數據,但新選舉出來的Primary卻沒有那部分數據,歷來形成數據丟失spa

結論

綜上所述,rollback的發生,主要是Primary寫入數據後還將來得及同步到secondary節點時,發生宕機事故,致使數據缺失,
經從新選舉後產生新primary節點,但當原Primary從新加入集羣時,因爲要追隨新Primary節點進行強一致性處理,因此會回滾宕機前未同步的數據。rest

存放位置

那麼回滾的數據跑到哪裏去了呢?當rollback發生時,MongoDB將把rollback的數據以BSON格式存放到dbpath路徑下rollback文件夾中,BSON文件的命名格式以下:日誌

<database>.<collection>.<timestamp>.bsoncode

還原數據

那麼這個rollback數據如何寫回到mongodb呢?咱們能夠利用mongorestore命令進行基於文件的恢復操做,具體操做能夠看我另一篇關於mongodump/mongorestore的文章blog

mongorestore --host <hostname:port> --db db1 --collection c2 -u admin_user -p"123456" --authenticationDatabase admin rollback/c2_rollback.BSON

避免策略

要講避免策略那就應先講講Write Concern(寫關注),也就是關心寫操做。是在驅動的connection level進行配置,支持一下值:

* w:0 | 1 | n | majority | tag
* j:1
* wtimeout: millis

w:0 unacknowledged
驅動只是一味的進行寫入操做,不會關心是否寫入成功,也就是mongo不會返回操做結果
圖片描述

w:1 Acknowledged
看圖咱們很容易理解,Driver在作寫入操做後會收到mongod的反饋OK仍是NG,而這個反饋行爲只是在確認數據被成功寫入Data Buffer,Journal Buffer
後的狀態,不保證數據可以被寫入datafile(落盤)
圖片描述

J:1 Journaled
驅動寫操做不只要寫入Journal Buffer,Data Buffer中,還要確認數據持久化到Journal file中後才反饋結果。
即便數據庫宕機,重啓後,操做已經持久化到journal中,能夠徹底恢復,但前提是mongod必定要開啓journal參數
圖片描述

w:2/n/majority Replica Acknowledged
看到下圖,你應該就明白一半了,好的,下一半讓小弟再給你解釋一下。
rollback的發生就是由於數據成功寫入Primary,可是還沒有同步到Secondary節點,此時Primary宕機,
當原Primary從新加入集羣后則會發生灰色數據自行rollback的現象,那麼怎麼避免呢?固然就是在發送反饋信息給驅動前
確保數據已經更新到至少一個Secondary節點,不就完美解決此問題了。是的,使用w:2/n/majority的配置參數
就能實現,固然,爲了防止網絡問題出現阻塞等待,咱們能夠設置wtimeout
圖片描述

Rollback 的限制

應用官方的一段話:
圖片描述
個人理解是rollback的數據超過300M後就須要手動干預從原Primary去除灰色數據了,可是有網友測試3G多的數據也能自行rollback,
So,I'm not clear the real meaning of the Limitations

相關文章
相關標籤/搜索