網路分割槽引發的oplog亂序問題

張友東發表於2016-08-29

線上一個Secondary節點crash,錯誤原因是出現了 OplogOutOfOrder 錯誤,也就是說Secondary 重放了一條比『已經重放過最新的 oplog』更早的操作,經過分析,發現問題是因網路分割槽導致出現2個 Primary 的問題導致,詳細的過程如下表分析。

說明:Node2、Node1、Node0分別是優先順序為2、1、0的複製整合員。

Timestamp Node2 Node1 Node0 Notes
t1 Primary Secondary Secondary Node2被選為主
t2 Primary write A Seconary sync A Secondary sync A Node2上寫入A,並同步到 Node1、Node0
t3 Primary write B Secondary Secondary Node2上寫入 B,但未同步到 Node1、Node0
t4 Primary Secondary Secondary Node2網路與 Node1、Node0隔離,發生新的選舉
t5 Primary Primary Secondary Node1被選為主
t6 Primary Primary WRITE C Secondary SYNC C Node1上寫入 C,同步到 Node0
t7 Primary Primary WRITE D Secondary SYNC D Node1上寫入 D,同步到 Node0
t8 Primary Write E Primary Secondary Node2上寫入 E, a實際上是一個耗時很長的建索引操作結束
t9 Secondary Primary Secondary network recovered, Node1發現 Node2的選舉時間戳更早,請求Node2降級
t10 Secondary Secondary Secondary Node1發現 Node2優先順序更高,並且oplog 足夠,主動降級
t11 Primary Secondary Secondary Node2贏得新的選舉
t12 Priamry Secondary Secondary Node1 Node0 從 Node2同步,先回滾 C D
t13 Primary Secondary Secondary Node1從 Node2 同步 B E
t14 Primary Secondary Secondary Node0從 Node2 同步 B E ,因為 Node0已經同步過 C D,時間戳比 B 更新,觸發oplogOutOfOrder 錯誤 crash

上述問題也提給了MongoDB 官方團隊,參考https://jira.mongodb.org/browse/SERVER-25838,這個問題在『3.0及以前的版本』或『使用 protocol version 為0的3.2版本』都有可能發生,但機率很小,使用 MongoDB 的同學不用擔心,我們也是因為MongoDB雲資料庫 使用者比較多,才觸發了一例;MongoDB 3.2引入了 raft 協議,避免了上述場景發生,遇到類似問題的使用者可以升級到 MongoDB-3.2,並使用複製集協議protocoal version 1


相關文章