在mongodb副本集的local庫中,有一個replset.minvalid集合,這個集合正常情況下會記錄一個optime,包含時間戳(ts)字段和選舉任期(t,如果使用的v1選舉協定)。有時候會有一些額外的字段,如『begin』、『doinginitialsync:true』等,如下,摘抄自mongodb代碼注釋:
那這個集合是幹什麼用的呢?簡單來說這個集合是secondary節點用來辨別目前是否處于一個一緻狀态。當節點已經應用到了這個集合中的optime對應的oplog,那麼它是一緻的。具體地看,這個集合主要有如下幾個作用:
标記目前正在執行initial sync。在initial sync開始時,會在這個集合中寫入一個『doinginitialsync:true』的标記,結束後清除。如果initial sync過程中程序crash了,下次重新開機的時候會根據這個标記重新進行initial sync。
保證secondary節點在同步過程能原子性的應用一批oplog(即要麼全部應用,要麼全部不應用)。在secondary節點同步的過程中,拉取了一批oplog後準備應用時,會在這個集合中寫入這批oplog的時間戳區間。即将集合的optime更新成這批oplog的結束optime,另外再增加一個『begin』字段辨別這批oplog的起始時間戳。當這一批oplog被成功應用完畢後,會将這個『begin』字段移除。如果在一批oplog應用途中程序crash了,下次重新開機時會通過『begin』字段檢測到這是一次不完整的batch apply oplog操作,會将oplog截斷到『begin』字段辨別的optime之前,以将已應用的部分oplog删除掉。之是以要這麼做是因為因為secondary在apply一批oplog的時候是并發進行的,當中可能産生一些中間狀态,需要保證全部apply完畢後才能對外可見。
如果secondary節點在選擇同步源的時候發現自己已經落後太多,已經跟不上其他節點,也會修改minvalid集合,将缺失的oplog時間區間(從自己的最新一條oplog的時間戳到看到的其他節點最舊的oplog時間戳)寫到minvalid集合中,并進入維護模式,變為recovering狀态。從recovering狀态重新回到secondary狀态時也會檢查是否已應用完了minvalid集合中記錄的optime對應的oplog。