當前位置:編程學習大全網 - 源碼下載 - 為什麽MongoDB會丟數據

為什麽MongoDB會丟數據

MongoDB 丟數據的說法已經出現很久很久了,傳言甚多。這裏簡單總結下場景。 1.在MongoDB很早的版本,2.0之前,沒有journal,加上默認不是安全寫,系統壹宕機就可能出現數據丟失,因為數據沒有刷盤,也沒有恢復日誌恢復機制。這個問題倒默認啟用journal以及安

MongoDB 丟數據的說法已經出現很久很久了,傳言甚多。這裏簡單總結下場景。

1.在MongoDB很早的版本,2.0之前,沒有journal,加上默認不是安全寫,系統壹宕機就可能出現數據丟失,因為數據沒有刷盤,也沒有恢復日誌恢復機制。這個問題倒默認啟用journal以及安全寫之後,沒有問題了。

2.選舉機制造成的數據丟失。這裏主要說這個。簡單講,MongoDB目前的選舉機制是有缺陷的。在壹些場景下會造成數據丟失。這些場景實際中會出現,如多機房情況下,但壹般不會太多。

場景1

replica set有如下節點: n1, n2, n3, n4, n5

n1 主節點n2,n3從n1同步n4,n5從n3同步

假設發生如下事件:

(n1, n2)與(n3, n4, n5)之間發生網絡分裂(network partition)

n3連不到n1,然後選舉它自己

n4 n5 投票給 n3, 因此n3 變成主節點

n3執行寫操作A,然後復制到n4,n5並確認,這樣被復制集大部分成員確認了。

n1 重新連接到復制集, 但仍然是主節點. 它必須降級.

現在有2個主節點 n1 and n3.其中壹個需要降級,如果 n1降級,不會產生什麽後果, 但如果 n3 降級, 多數成員確認的寫操作就丟失了.

MongoDB 2.4中這是非常可能的. 雙主場景中,選擇哪壹個主節點降級是隨意的. SERVER-9765 描述了這個問題. 現在 2.6版本中,其中壹個主節點根據上壹次選舉的時間戳來決定哪壹個降級.上面例子中 n3被選舉為主的時間比 n1近, n3應該保持作為主而n1應該降級. 因為成員可能每30秒參與壹次選舉,因此成功的選舉之間最小間隔為30秒. 雖然如此,我仍然不知道不同成員之間的時鐘誤差在這個算法上如何影響。

場景2

(n1, n2)與(n3, n4, n5)之間發生網絡分裂(network partition)

n3連不到n1,然後選舉它自己

n4 n5 投票給 n3, 因此n3 變成主節點

n3執行寫操作A,然後復制到n4,n5並確認,這樣被復制集大部分成員確認了。

n1 重新連接到復制集, 但仍然是主節點. 它必須降級.

n1接受寫操作B,然後復制並被n2確認;

n4停止從n3復制並開始從n1復制;

因為n1沒有寫操作A,n4回滾寫操作A,然後復制並確認寫操作B.

這裏問題就是有兩個主,任意壹個降級,都要回滾相應的寫操作。這個例子也可以看出MongoDB復制的壹個潛在問題,即簡單的以來時間戳來決定oplog位置。

場景3

這個場景與2有點類似,但是考慮壹下降級的時候考慮選舉的時間,即選最近選舉出來的為主,另壹個主降級。

所有從節點從n1復制.

發生網裂,(n1, n2) 與 (n3, n4, n5)斷開

n3連不到n1,然後選舉它自己

n4 n5 投票給 n3, 但n3還沒變為主節點

n4和n5投票後,網絡恢復

n1發生寫操作A,並被n2,n4,n5確認,n3還沒變成主或者還沒復制並確認這個寫操作。

n3最終成為主了,還沒機會復制並確認A操作

n1註意到n3是主並且選舉的時間更近,因此n1降級

所有成員開始從n3復制,因此回滾A操作。

這裏可以看出的問題是,寫確認操作和投票選舉操作之間並沒有足夠的交流,n4,n5投票給n3,確認了壹個可能回滾的寫操作,部分原因是因為剛剛完成選舉操作。這是MongoDB選舉協議沒有考慮的地方。

總的來說,現在MongoDB的選舉協議問題如下:雙主的情況下,必須解決壹下問題

兩個主節點必須不能產生交錯的oplog

當雙主情況下,oplog位置小的降級

數據同步線程和寫確認操作線程必須與選舉主節點線程有更多交流,簡言之,應該如下:

成員不能投票會回滾寫操作的節點為主節點;

成員不能確認因為選舉投了贊成票可能造成回滾的寫操作。

tokumx將通過ark選舉協議來解決這個問題。

參考:/2014/07/explaining-ark-part-3-why-data-may-be-lost-on-a-failover/

原文地址:為什麽MongoDB會丟數據, 感謝原作者分享。

  • 上一篇:如何利用IP地址進行追蹤與定位
  • 下一篇:艾菲爾 生命靈數看2022運勢吉兇?
  • copyright 2024編程學習大全網