MongoDB 更改 Oplog Size 大小

MongoDB 的副本集同步中 Oplog 佔了非常關鍵的作用。


Oplog Size 可不可以隨意更改?

https://docs.mongodb.com/manual/reference/configuration-options/#replication.oplogSizeMB
官方配置文檔說明

replication.oplogSizeMB
	Type: integer

	The maximum size in megabytes for the replication operation log (i.e., the oplog).
	Starting in MongoDB 4.0, the oplog can grow past its configured size limit to avoid deleting the majority commit point.
	By default, the mongod process creates an oplog based on the maximum amount of space available. For 64-bit systems, the oplog is typically 5% of available disk space.
	Once the mongod has created the oplog for the first time, changing the replication.oplogSizeMB option will not affect the size of the oplog.
	To change the oplog size of a running replica set member, use the replSetResizeOplog administrative command. replSetResizeOplog enables you to resize the oplog dynamically without restarting the mongod process.
	
	See Oplog Size for more information.
	The replication.oplogSizeMB setting is available only for mongod.

其中,默認oplog 大小如無配置指定,則默認爲當前磁盤空間的 5% 在 64位操作系統上。

一次生成 oplog 空間則終生有效,後續通過更改 mongod.conf 配置文件並重啓服務,均不生效。

在 MongoDB 3.6+ 版本中新增可以動態調整副本集 Oplog Size 的指令,無需重啓 mongod 服務。


查看當前 mongod 服務中分配的 Oplog Size 大小

查看當前已經分配的 oplog size 大小有幾個類似的指令

sh1:PRIMARY> rs.printReplicationInfo()
configured oplog size:   12958.975341796875MB
log length start to end: 938secs (0.26hrs)
oplog first event time:  Thu Apr 11 2019 15:03:05 GMT+0800 (CST)
oplog last event time:   Thu Apr 11 2019 15:18:43 GMT+0800 (CST)
now:                     Thu Apr 11 2019 15:18:43 GMT+0800 (CST)


sh2:PRIMARY> rs.printReplicationInfo()
sh2:PRIMARY> db.printReplicationInfo()
sh2:PRIMARY> db.getReplicationInfo()
{
        "logSizeMB" : 102400,
        "usedMB" : 905.03,
        "timeDiff" : 4704,
        "timeDiffHours" : 1.31,
        "tFirst" : "Thu Apr 11 2019 13:54:30 GMT+0800 (CST)",
        "tLast" : "Thu Apr 11 2019 15:12:54 GMT+0800 (CST)",
        "now" : "Thu Apr 11 2019 15:12:54 GMT+0800 (CST)"
}

logSizeMB / configured oplog size當前已配置的空間大小,單位 MB
usedMB: 當前已使用空間大小,單位 MB。
tFirst / oplog first event time: 當前 oplog 最開始的記錄時間。
tLast / oplog last event time: 當前 oplog 最新的更改記錄時間。
timeDiff / log length start to end: 當前mongod中當前更改記錄時間 - 最開始記錄時間,單位 秒。
timeDiffHours / log length start to end: 當前mongod中當前更改記錄時間 - 最開始記錄時間,單位 小時。


規劃需要更改的 oplog size 大小

根據業務場景不同,在高峯期獲取 mongod 實例的寫入量

sh1:PRIMARY> rs.printReplicationInfo()
configured oplog size:   12958.975341796875MB
log length start to end: 938secs (0.26hrs)
oplog first event time:  Thu Apr 11 2019 15:03:05 GMT+0800 (CST)
oplog last event time:   Thu Apr 11 2019 15:18:43 GMT+0800 (CST)
now:                     Thu Apr 11 2019 15:18:43 GMT+0800 (CST)

如上面所示,項目大多都是 insert、update 等更新操作,所以 12G 的 oplog 空間,在業務高峯只能夠存儲最近 900 秒的變更操作日誌。

如果需要使 oplog 保留更長的週期,那麼需要合理規劃更大的 oplog.rs 空間大小。


更改 oplog size 大小

概述

oplog在內部作爲上限集合存在,因此您無法在正常操作過程中修改其大小。
在大多數情況下,默認的oplog大小是可接受的大小;
但是,在某些情況下,您可能需要更大或更小的oplog。
例如,如果應用程序在短時間內執行大量多次更新或刪除,則可能需要更改oplog大小。

爲了修改oplog大小,我們需要以此爲複製集中的每個節點進行維護手動操作。該過程需要:停止 mongod 進程,並以非單節點方式啓動,修改oplog大小,再重啓該節點。

[重要]
請確保我們從副本集的從節點(Secondary)開始維護,並最後維護主節點(Primary)。

流程

  • 以單節點模式重啓節點

    在 Primary 節點上可以使用 rs.stepDown() 指令來強制手動切換爲Secondary 節點。

  • 並保留就的 oplog 的條目作爲查詢條件,清空 oplog.rs 集合並重新建立指定大小的 oplog.rs 集合。

  • 以副本集模式啓動 mongod 實例。


1. 首先在 secondary 節點上關閉 mongod 實例。比如通過 db.shutdownServer() 命令來關閉:

> db.shutdownServer()

在其他端口上以單節點模式(不包含 --replSet 參數)重新啓動 mongod 實例。命令如下:

# sudo -u mongod mongod --port 37017 --dbpath /var/lib/mongo

2. 複製現有 Oplog (可選)
我們可以選擇備份現有結點的 oplog 來以防萬一,命令如下:

mongodump --port 37017 --db local --collection 'oplog.rs'

3. 以新的大小和 Seed Entry 重建 oplog
保存 oplog 中最新的條目。例如,連接進入 mongo Shell,並通過如下命令進入 local 數據庫:

> use local

在 mongo Shell 窗口中,我們也可以使用如下命令來設置 db:

> db = db.getSiblingDB('local')

確保 local.temp 集合爲空的:

> db.temp.drop()

使用 natural order 排序來找到 oplog 中最後一條數據,並通過 db.collection.save() 命令插入 local.temp 集合中:

> db.temp.save(db.oplog.rs.find({}, {ts: 1, h: 1}).sort({$natural: -1}).limit(1).next())

檢驗 local.temp 集合中保存的最後一條 oplog 數據:

> db.temp.find()

4. 刪除已存在老的 Oplog 集合
通過如下命令在 local 庫中刪除老的oplog.rs 集合:

> db = db.getSiblingDB('local')
> db.oplog.rs.drop()

結果會返回 true

5. 建立新的 Oplog 集合大小
通過 create 命令來建立新的 oplog(新的大小)。指定 size(單位是 bytes)。下面的命令會建立一個大小爲 20 * 1024 * 1024 * 1024 也就是 20G 的 oplog 集合:

> db.runCommand({create: "oplog.rs", capped: true, size: (20 * 1024 * 1024 * 1024)})

命令執行成功後會返回如下內容:

{ "ok" : 1 }

6. 將之前保存在 local.temp 集合中的老的最後一條 oplog 數據插入到新的 oplog 集合中。 例如:

> db.oplog.rs.save( db.temp.findOne() )

通過如下命令來確認:

> db.oplog.rs.find()

7. 結束,以副本集模式重啓 mongod 實例。

> db = db.getSiblingDB('admin')
> db.shutdownServer()
# service mongod restart

該複製集將會恢復並會在其成爲主節點之前 “catch up” 數據。

8. 重複以上操作在所有我們希望修改 oplog 大小的機器上。最後再在主節點上進行該操作。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章