在每個MongoDB(版本 3.2.9) Instance中,都有一個本地資料庫(local),用於存儲 Replication 進程的信息和本地數據。local 資料庫的特性是:位於local資料庫中的數據和集合不會被 Replication 進程複製到其他MongoDB instance上。如果 ...
在每個MongoDB(版本 3.2.9) Instance中,都有一個本地資料庫(local),用於存儲 Replication 進程的信息和本地數據。local 資料庫的特性是:位於local資料庫中的數據和集合不會被 Replication 進程複製到其他MongoDB instance上。如果實例上有些collection 和 data不計劃被覆制到其他MongoDB Instance,可以將這些collection 和 data 存儲在local 資料庫中。
MongoDB shell提供一個全局變數rs,是資料庫命令的包裝器(wrapper),用於維護Replica Set。
一,Replica Set的配置
1,查看Replica Set的配置信息
MongoDB 將Replica Set的配置信息存儲在local.system.replset 集合中,在同一個Replica Set中所有成員local.system.replset是相同的,不能直接修改該集合,必須通過rs.initiate()來初始化,通過 rs.reconfig()來重新配置,對Replica Set 增加或刪除成員都會相應的修改Replica Set的配置信息。
rs.config() use local db.system.replset.find()
配置信息重要信息主要有兩部分:Replica Set的 id 值 和 member 數組。
{ _id: "replica set name", members: [ { _id: <int>, host: "host:port", arbiterOnly: <boolean>, buildIndexes: <boolean>, hidden: <boolean>, priority: <number>, slaveDelay: <int>, votes: <number> }, ... ], ... }
成員的配置文檔:
priority:表示一個成員被選舉為Primary節點的優先順序,預設值是1,取值範圍是從0到100,將priority設置為0有特殊含義:Priority為0的成員永遠不能成為Primary 節點。Replica Set中,Priority最高的成員,會優先被選舉為Primary 節點,只要其滿足條件。
hidden:將成員配置為隱藏成員,要求Priority 為0。Client不會向隱藏成員發送請求,因此隱藏成員不會收到Client的Request。
slaveDelay:單位是秒,將Secondary 成員配置為延遲備份節點,要求Priority 為0,表示該成員比Primary 成員滯後指定的時間,才能將Primary上進行的寫操作同步到本地。為了數據讀取的一致性,應將延遲備份節點的hidden設置為true,避免用戶讀取到明顯滯後的數據。Delayed members maintain a copy of the data that reflects the state of the data at some time in the past.
votes:有效值是0或1,預設值是1,如果votes是1,表示該成員(voting member)有許可權選舉Primary 成員。在一個Replica Set中,最多有7個成員,其votes 屬性的值是1。
arbiterOnly:表示該成員是仲裁者,arbiter的唯一作用是就是參與選舉,其votes屬性是1,arbiter不保存數據,也不會為client提供服務。
buildIndexes:表示實在在成員上創建Index,該屬性不能修改,只能在增加成員時設置該屬性。如果一個成員僅僅作為備份,不接收Client的請求,將該成員設置為不創建index,能夠提高數據同步的效率。
2,重新配置Replica Set
對Replica Set重新配置,必須連接到Primary 節點;如果Replica Set中沒有一個節點被選舉為Primary,那麼,可以使用force option(rs.reconfig(config,{force:true})),在Secondary 節點上強制對Replica Set進行重新配置。
The force parameter allows a reconfiguration command to be issued to a non-primary node. If set as { force: true }, this forces the replica set to accept the new configuration even if a majority of the members are not accessible. Use with caution, as this can lead to rollback situations.
示例,在primary 節點中,重新配置成員的優先順序屬性(priority)。
cfg = rs.conf() cfg.members[0].priority = 1 cfg.members[1].priority = 1 cfg.members[2].priority = 5 rs.reconfig(cfg)
3,增加成員
3.1,該使用預設的配置增加成員
--增加一個成員,用於存儲數據
rs.add("host:port")
--增加一個arbiter,用於選舉
rs.add("host:port",true)
3.2,使用配置文檔增加成員
示例,為Replica Set增加一個延遲備份的隱藏節點,滯後Primary節點1hour,該節點不參與投票,也不創建index,僅僅作為數據備份。
rs.add( { _id:4, host: "host:port", priority: 0, hidden:true, slaveDelay:3600, votes:0, buildIndexes:true, arbiterOnly:false } )
4,刪除成員
rs.remove("host")
5,對replica set重新配置,能夠增加成員,刪除成員,並能同時修改成員的屬性
二,對Replica Set的成員進行操作
1,凍結當前成員,使當前成員在指定的時間內沒有資格成為Primary,即當前成員在一定時間內保持Secondary身份
Makes the current replica set member ineligible to become primary for the period specified.
rs.freeze(seconds)
2,強制 Primary 節點退化為Secondary節點
rs.stepDown()使當前Primary節點退化為Secondary 節點,並激發選舉Primary的事件。該函數使當前的Primary 節點在指定的時間內,不能成為Primary節點。在一定的時間內,如果有 Secondary 節點滿足條件,那麼該Secondary節點被選舉為Primary 節點;如果沒有 Secondary 節點滿足條件,那麼原Primary節點參與選舉。stepDown函數,使Primary節點退化為Secondary,併在一段時間內不能參與選舉。
Forces the primary of the replica set to become a secondary, triggering an election for primary. The method steps down the primary for a specified number of seconds; during this period, the stepdown member is ineligible from becoming primary.
rs.stepDown(stepDownSecs, secondaryCatchUpPeriodSecs)
3,強制當前成員從指定成員同步數據
rs.syncFrom("host:port");
4,使當前的Secondary 節點能夠讀取數據
預設情況下,Secondary 節點是不能讀取數據的
rs.slaveOk()
三,查看Replica Set的狀態
set欄位:Replica Set的name
stateStr:成員狀態的描述信息
name:該成員的host 和 埠
syncTo:該成員從哪個成員同步數據,可以使用rs.syncFrom()強制同步的Path,從指定的 Target 成員同步數據。
{ "set" : "rs0", "myState" : 1, "heartbeatIntervalMillis" : NumberLong(2000), "members" : [ { "_id" : 0, "name" : "cia-sh-05:40004", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 240973, "optime" : { "ts" : Timestamp(1473336939, 1), "t" : NumberLong(5) }, "optimeDate" : ISODate("2016-09-08T12:15:39.000Z"), "lastHeartbeat" : ISODate("2016-09-10T04:39:55.041Z"), "lastHeartbeatRecv" : ISODate("2016-09-10T04:39:56.356Z"), "pingMs" : NumberLong(0), "syncingTo" : "cia-sh-06:40001" }, ..... ] }
三,Replica Set的操作日誌
MongoDB的Replication實際上是基於操作日誌(operation log)的複製。Replication進程的整個過程是:Replication 將Primary節點中執行的寫操作記錄到oplog集合中,Secondary成員讀取Primary 成員的oplog集合,重做(redo)oplog中記錄的寫操作,最終,Replica Set中的各個成員達到數據的一致性。
oplog集合中記錄的操作是基於單個doc的,也就是說,如果一條命令隻影響一個doc,那麼Replication向oplog集合中插入一個操作命令;如果一個命令影響多個doc,那麼Replication將該命令拆分成多個等效的操作命令,每個操作命令只會影響一個doc,最終向oplog集合中插入的是多個操作命令。
1,oplog 集合
oplog集合是一個特殊的固定集合,存儲的是Primary節點的操作日誌,每個Replica Set的成員都一個oplog的副本:local.oplog.rs,該集合存儲在每個成員的local資料庫中。Replica Set中的每個成員都有一個oplog集合,用於存儲當前節點的操作記錄,其他成員能夠從任何一個成員的oplog中同步數據。
The oplog (operations log) is a special capped collection that keeps a rolling record of all operations that modify the data stored in your databases. MongoDB applies database operations on the primary and then records the operations on the primary’s oplog. The secondary members then copy and apply these operations in an asynchronous process. All replica set members contain a copy of the oplog, in the local.oplog.rs collection, which allows them to maintain the current state of the database.
2,oplog的大小
oplog集合是一個固定集合,其大小是固定的,在第一次開始Replica Set的成員時,MongoDB創建預設大小的oplog。在MongoDB 3.2.9 版本中,MongoDB 預設的存儲引擎是WiredTiger,一般情況下,oplog的預設大小是數據文件所在disk 空閑空間(disk free space)的5%,最小不會低於990 MB,最大不會超過50 GB。
3,修改oplog的大小
修改的過程主要分為三步:
- 以單機模式重啟mongod
- 啟動之後,重新創建oplog,並保留最後一個記錄作為種子
- 以複製集方式重啟mongod
詳細過程是:
step1:以單機模式重啟mongod
對於Primary成員,首先調用stepDown函數,強制Primary成員轉變為Secondary成員
rs.stepDown()
對於secondary成員,調用shutdownServer()函數,關閉mongod
use admin
db.shutdownServer()
啟動mongod實例,不要使用replset參數
mongod --port 37017 --dbpath /srv/mongodb
step2:創建新的oplog
有備無患,備份oplog文件
mongodump --db local --collection 'oplog.rs' --port 37017
將oplog中最後一條有效記錄保存到temp 集合中,作為新oplog的seed
use local db.temp.drop() db.temp.save( db.oplog.rs.find( { }, { ts: 1, h: 1 } ).sort( {$natural : -1} ).limit(1).next() )
db.oplog.rs.drop()
重建新的oplog集合,並將temp集合中一條記錄保存到oplog中,size的單位是Byte
db.runCommand( { create: "oplog.rs", capped: true, size: (2 * 1024 * 1024 * 1024) } ) db.oplog.rs.save( db.temp.findOne() )
step3:以複製集模式啟動 mongod,replset參數必須制定正確的Replica Set的名字
db.shutdownServer()
mongod --replSet rs0 --dbpath /srv/mongodb
三,查看mongod 的開機日誌
在local.startup_log 集合中,存儲mongod 每次啟動時的開機日誌
參考文檔: