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的狀態、大小、存儲的時間範圍。
capped collection是MongoDB中一種提供高性能插入、讀取和刪除操做的固定大小集合,當集合被填滿的時候,新的插入的文檔會覆蓋老的文檔。
因此,oplog表使用capped collection是合理的,由於不可能無限制的增加oplog。MongoDB在初始化副本集的時候都會有一個默認的oplog大小:
oplog的大小設置是值得考慮的一個問題,若是oplog size過大,會浪費存儲空間;若是oplog size太小,老的oplog記錄很快就會被覆蓋,那麼宕機的節點就很容易出現沒法同步數據的現象。
好比,基於上面的例子,咱們停掉一個備份節點(port=33333),而後經過主節點插入如下記錄,而後查看oplog,發現之前的oplog已經被覆蓋了。
經過MongoDB shell鏈接上這個節點,會發現這個節點一直處於RECOVERING狀態。
解決方法:
在副本集中,有兩種數據同步方式:
當遇到上面例子中沒法同步的問題時,只能使用如下兩種方式進行initial sync了
經過上面兩種方式中的一種,均可以從新恢復"port=33333"的節點。改變一直處於RECOVERING狀態的錯誤。
6:oplog數據結構
下面來分析一下oplog中字段的含義,經過下面的命令取出一條oplog:
db.oplog.rs.find().skip(1).limit(1).toArray()
經過"db.printReplicationInfo()"命令能夠查看oplog的信息
字段說明:
經過"db.printSlaveReplicationInfo()"能夠查看slave的同步狀態
副本節點中執行db.printSlaveReplicationInfo()命令能夠查看同步狀態信息
當咱們插入一條新的數據,而後從新檢查slave狀態時,就會發現sync時間更新了