MongoDB oplog詳解

MongoDB oplog詳解

1:oplog簡介html

oplog是local庫下的一個固定集合,Secondary就是經過查看Primary 的oplog這個集合來進行復制的。每一個節點都有oplog,記錄這從主節點複製過來的信息,這樣每一個成員均可以做爲同步源給其餘節點。sql

 Oplog 能夠說是Mongodb Replication的紐帶了。mongodb

2:副本集數據同步的過程shell

副本集中數據同步的詳細過程:Primary節點寫入數據,Secondary經過讀取Primary的oplog獲得複製信息,開始複製數據而且將複製信息寫入到本身的oplog。若是某個操做失敗(只有當同步源的數據損壞或者數據與主節點不一致時纔可能發生),則備份節點中止從當前數據源複製數據。若是某個備份節點因爲某些緣由掛掉了,當從新啓動後,就會自動從oplog的最後一個操做開始同步,同步完成後,將信息寫入本身的oplog,因爲複製操做是先複製數據,複製完成後再寫入oplog,有可能相同的操做會同步兩份,不過MongoDB在設計之初就考慮到這個問題,將oplog的同一個操做執行屢次,與執行一次的效果是同樣的。數據庫

  • 做用:

  當Primary進行寫操做的時候,會將這些寫操做記錄寫入Primary的Oplog 中,然後Secondary會將Oplog 複製到本機並應用這些操做,從而實現Replication的功能。
  同時因爲其記錄了Primary上的寫操做,故還能將其用做數據恢復。
  能夠簡單的將其視做Mysql中的binlog。安全

3:oplog的增加速度網絡

oplog是固定大小,他只能保存特定數量的操做日誌,一般oplog使用空間的增加速度跟系統處理寫請求的速度至關,若是主節點上每分鐘處理1KB的寫入數據,那麼oplog每分鐘大約也寫入1KB數據。若是單次操做影響到了多個文檔(好比刪除了多個文檔或者更新了多個文檔)則oplog可能就會有多條操做日誌。db.testcoll.remove() 刪除了1000000個文檔,那麼oplog中就會有1000000條操做日誌。若是存在大批量的操做,oplog有可能很快就會被寫滿了。數據結構

  • 大小:

  Oplog 是一個capped collection。
  在64位的Linux, Solaris, FreeBSD, and Windows 系統中,Mongodb默認將其大小設置爲可用disk空間的5%(默認最小爲1G,最大爲50G)或也能夠在mongodb複製集實例初始化以前將mongo.conf中oplogSize設置爲咱們須要的值app

  local.oplog.rs 一個capped collection集合.可在命令行下使用--oplogSize 選項設置該集合大小尺寸.
  可是因爲Oplog 其保證了複製的正常進行,以及數據的安全性和容災能力。post

4:oplog注意事項:

local.oplog.rs特殊的集合。用來記錄Primary節點的操做

爲了提升複製的效率,複製集中的全部節點之間會相互的心跳檢測(ping)。每一個節點均可以從其餘節點上獲取oplog。

oplog中的一條操做。無論執行多少次效果是同樣的

5:oplog的大小

第一次啓動複製集中的節點時,MongoDB會創建Oplog,會有一個默認的大小,這個大小取決於機器的操做系統

rs.printReplicationInfo()     查看 oplog 的狀態,輸出信息包括 oplog 日誌大小,操做日誌記錄的起始時間。

db.getReplicationInfo()   能夠用來查看oplog的狀態、大小、存儲的時間範圍。

oplog的大小

capped collection是MongoDB中一種提供高性能插入、讀取和刪除操做的固定大小集合,當集合被填滿的時候,新的插入的文檔會覆蓋老的文檔。

因此,oplog表使用capped collection是合理的,由於不可能無限制的增加oplog。MongoDB在初始化副本集的時候都會有一個默認的oplog大小:

  • 在64位的Linux,Solaris,FreeBSD以及Windows系統上,MongoDB會分配磁盤剩餘空間的5%做爲oplog的大小,若是這部分小於1GB則分配1GB的空間
  • 在64的OS X系統上會分配183MB
  • 在32位的系統上則只分配48MB

oplog的大小設置是值得考慮的一個問題,若是oplog size過大,會浪費存儲空間;若是oplog size太小,老的oplog記錄很快就會被覆蓋,那麼宕機的節點就很容易出現沒法同步數據的現象。

好比,基於上面的例子,咱們停掉一個備份節點(port=33333),而後經過主節點插入如下記錄,而後查看oplog,發現之前的oplog已經被覆蓋了。

經過MongoDB shell鏈接上這個節點,會發現這個節點一直處於RECOVERING狀態

解決方法:

數據同步

在副本集中,有兩種數據同步方式:

  • initial sync(初始化):這個過程發生在當副本集中建立一個新的數據庫或其中某個節點剛從宕機中恢復,或者向副本集中添加新的成員的時候,默認的,副本集中的節點會從離它最近的節點複製oplog來同步數據,這個最近的節點能夠是primary也能夠是擁有最新oplog副本的secondary節點。
    • 該操做通常會從新初始化備份節點,開銷較大
  • replication(複製):在初始化後這個操做會一直持續的進行着,以保持各個secondary節點之間的數據同步。

initial sync

當遇到上面例子中沒法同步的問題時,只能使用如下兩種方式進行initial sync了

  • 第一種方式就是中止該節點,而後刪除目錄中的文件,從新啓動該節點。這樣,這個節點就會執行initial sync
    • 注意:經過這種方式,sync的時間是根據數據量大小的,若是數據量過大,sync時間就會很長
    • 同時會有不少網絡傳輸,可能會影響其餘節點的工做
  • 第二種方式,中止該節點,而後刪除目錄中的文件,找一個比較新的節點,而後把該節點目錄中的文件拷貝到要sync的節點目錄中

經過上面兩種方式中的一種,均可以從新恢復"port=33333"的節點。改變一直處於RECOVERING狀態的錯誤。

 

6:oplog數據結構

下面來分析一下oplog中字段的含義,經過下面的命令取出一條oplog:

db.oplog.rs.find().skip(1).limit(1).toArray()
  • ts: 8字節的時間戳,由4字節unix timestamp + 4字節自增計數表示。這個值很重要,在選舉(如master宕機時)新primary時,會選擇ts最大的那個secondary做爲新primary
  • op:1字節的操做類型
    • "i": insert
    • "u": update
    • "d": delete
    • "c": db cmd
    • "db":聲明當前數據庫 (其中ns 被設置成爲=>數據庫名稱+ '.')
    • "n": no op,即空操做,其會按期執行以確保時效性
  • ns:操做所在的namespace
  • o:操做所對應的document,即當前操做的內容(好比更新操做時要更新的的字段和值)
  • o2: 在執行更新操做時的where條件,僅限於update時纔有該屬性

查看oplog的信息

經過"db.printReplicationInfo()"命令能夠查看oplog的信息

字段說明:

  • configured oplog size: oplog文件大小
  • log length start to end: oplog日誌的啓用時間段
  • oplog first event time: 第一個事務日誌的產生時間
  • oplog last event time: 最後一個事務日誌的產生時間
  • now: 如今的時間

查看slave狀態

經過"db.printSlaveReplicationInfo()"能夠查看slave的同步狀態

副本節點中執行db.printSlaveReplicationInfo()命令能夠查看同步狀態信息

  • source——從庫的IP及端口
  • syncedTo——當前的同步狀況,延遲了多久等信息

當咱們插入一條新的數據,而後從新檢查slave狀態時,就會發現sync時間更新了

參考文章

相關文章
相關標籤/搜索