ApsaraDB for MongoDB的oplog相關參數設定不合理可能會導致執行個體主從同步異常、執行個體無法按時間點恢複資料等問題,本文將指導您如何配置oplog相關參數並對相關的風險進行說明。
oplog基本資料
ApsaraDB for MongoDB複本集執行個體的主從複製是通過oplog(operations log
)邏輯日誌來完成的,oplog表(local.oplog.rs
)是一個特殊的限制集合(capped collection
),其中儲存了所有對資料庫中文檔的改動操作。oplog具備以下基礎特性:
在複本集中,寫入操作只會在主節點上完成併產生相應的oplog,其他從節點將非同步複製這些oplog並在自身回放,以保持主從複製狀態。
如果某個操作並不改動任何文檔或者因某種原因失敗,則不會產生相應的oplog記錄。
一條oplog記錄在複本集中所有節點上都完全一致,回放並不會改變oplog表裡的記錄。
oplog表中的每個操作都是等冪的。無論一條oplog記錄被回放了一次還是多次,得到的結果都是相同的。
oplog記錄是與時間相關聯的,oplog裡每一條操作都有唯一的時間戳記欄位(ts)。該欄位由UNIX時間戳記和計數器兩部分組成,因此可以確定任意兩條oplog記錄之間的先後順序。
oplog視窗(
oplog window
)代表著oplog表裡最老的一條oplog記錄和最新的一條oplog記錄之間的時間差。主從複製依賴這個oplog視窗,只有在同步源的oplog視窗找到期望的oplog記錄時,從節點才能正常進行同步。從節點重啟或者新增節點後,也是依賴oplog裡的記錄來確認自己能否成功成為複本集中正常的一員。如果發現自己期望的oplog記錄在同步源中找不到,就會因為
too stale to catch up
的錯誤而變成異常的RECOVERING狀態。
oplog大小
在ApsaraDB for MongoDB中,oplog的預設大小是執行個體磁碟空間的10%(例如您執行個體的磁碟空間為500 GB,則相應的oplog大小就是50 GB)。oplog大小會隨著磁碟擴容而自動調整。
如需調整oplog大小,您可以在控制台對replication.oplogSizeMB
參數進行調整,調整後無需重啟,提交後即生效。如何修改配置參數,請參見設定資料庫參數。
您可使用以下兩種方式查看oplog表的實際大小:
在控制台監控資訊頁面的磁碟空間使用率指標中查看oplog表的實際大小。具體操作,請參見基本監控。
通過用戶端工具(mongo shell或mongosh)串連執行個體後,執行以下命令來查看oplog表的大小以及oplog視窗期。
rs.printReplicationInfo()
樣本的結果如下:
configured oplog size: 192MB log length start to end: 65422secs (18.17hrs) oplog first event time: Mon Jun 23 2014 17:47:18 GMT-0400 (EDT) oplog last event time: Tue Jun 24 2014 11:57:40 GMT-0400 (EDT) now: Thu Jun 26 2014 14:24:39 GMT-0400 (EDT)
在樣本中,oplog大小約為192MB,oplog視窗約為18小時。
oplog最小保留時間
從MongoDB 4.4版本開始,支援了oplog最小保留時間的設定檔項storage.oplogMinRetentionHours,讓您可以直接控制oplog的保留時間來確保足夠的oplog視窗。
預設情況下,該配置項的值為0,表示不設定oplog最小保留時間,此時oplog的清理還是由之前的oplog大小控制。如果設定了該配置項,oplog清理將在以下2個條件均滿足時發生:
oplog超過了配置的
oplogSizeMB
。oplog的時間戳記比oplog最小保留時間還早。
當oplog還沒有達到配置的oplogSizeMB
時(例如執行個體剛初始化,還未寫入太多資料),實際的oplog視窗可能會比設定的oplog最小保留時間大很多,此時oplog表的大小隻受oplogSizeMB
限制;當達到配置的oplogSizeMB
後,oplog表的大小受oplog最小保留時間限制,當oplog產生速度較快時,oplog的總大小可能會比配置的oplogSizeMB
大很多。
如需調整oplog的保留時間,您可以在控制台對storage.oplogMinRetentionHours
參數進行調整,調整後無需重啟,提交後即生效。如何修改配置參數,請參見設定資料庫參數。
如需查看oplog的保留時間,您可以在控制台監控資訊頁面查看oplog保留時間長度指標。具體操作,請參見基本監控。
ApsaraDB for MongoDB記錄備份
ApsaraDB for MongoDB所有執行個體的記錄備份都基於oplog,相關管控服務進程會不斷拉取執行個體上最新的oplog記錄併流式上傳至OSS,形成一系列記錄備份檔案。在按時間點恢複時,這些記錄備份檔案會用來進行oplog回放。
特殊情況下,記錄備份中可能會產生空洞而導致無法按時間點恢複,具體資訊,請參見風險說明。
本文中提到的記錄備份空洞與MongoDB術語中的oplog hole並不是一個概念。
最佳實務
設定合理的oplog大小或oplog保留時間
通常情況下,oplog大小保持預設值即可,但是在以下情境的業務負載下,建議您調大oplog的大小:
經常對文檔進行批次更新
每一個批次更新的操作都會產生多條針對單個文檔的更新操作,這會產生大量的oplog記錄。
反覆地插入和刪除
如果文檔插入一段時間後被刪除,那麼資料庫的磁碟空間並不會有明顯增長,但oplog裡會有很多相關記錄。
針對相同文檔的大量原地更新
如果業務情境中大部分操作是不會增加文檔大小的更新,這些更新會產生大量的oplog記錄,但磁碟上的資料量不會有明顯變化。
如果您的業務負載是以下類型,也可以酌情調小oplog大小,以更充分地利用磁碟空間:
讀多寫少的業務負載。
儲存冷資料。
無論是設定oplog大小還是oplog保留時間,都建議您盡量將MongoDB執行個體的oplog視窗控制在24小時以上。在一些需要額外進行初始化同步(initial sync)的情境,oplog視窗需要覆蓋一個節點完成所有資料同步的時間,該時間通常跟執行個體的整體資料量、庫表總數、執行個體規格等因素相關,oplog視窗可能會需要更長的時間。
關注從節點的延遲情況並配置好相關警示
當從節點出現延遲並且不斷變大時,一旦延遲時間超過了oplog視窗,從節點將會進入異常狀態無法恢複。因此,您需要關注MongoDB執行個體中的從節點延遲情況,並且在延遲不斷增加時及時提交工單聯絡阿里雲支援人員協助解決。
導致從節點出現延遲的原因有很多,包括:
網路延遲、丟包、中斷等。
從節點的磁碟吞吐達到瓶頸。
{w:1}
的writeConcern並且寫入負載比較重。某些核心缺陷導致從節點主從複製被阻塞。
其他未列出的原因。
您可使用以下兩種方式查看從節點的延遲情況:
在控制台監控資訊頁面的主備延遲指標中查看從節點的延遲情況。具體操作,請參見基本監控。
通過用戶端工具(mongo shell或mongosh)串連執行個體後,執行以下命令來查看從節點的延遲情況。
rs.printSecondaryReplicationInfo()
樣本的結果如下:
source: m1.example.net:27017 syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT) 0 secs (0 hrs) behind the primary source: m2.example.net:27017 syncedTo: Thu Apr 10 2014 10:27:47 GMT-0400 (EDT) 0 secs (0 hrs) behind the primary
在樣本中,2個從節點都沒有延遲。
您可以通過控制台的警示規則功能,建立一條針對複寫延遲的CloudMonitor警示,建議警示閾值設定為10秒以上。具體操作,請參見設定閾值警示規則。
風險說明
可能導致記錄備份出現空洞的主要原因有以下兩種。
核心大版本低於3.4
周期性的空操作(periodic noop)是MongoDB核心在3.4大版本引入的,目的是為了適配readPreference的配套參數maxStalenessSeconds
,詳情請參見SERVER-23892。該空操作的目的主要是在沒有業務寫入的情況下,確保oplog依然在不斷向前推進,由此可以判斷複本集中主從節點的落後情況。
當資料庫的核心大版本低於3.4時,如果很長時間都沒有業務寫入的情況,oplog不會再推進。因此,執行個體的記錄備份也擷取不到新的oplog資料而導致出現記錄備份空洞,進而導致出現執行個體無法按時間點恢複的情況。
執行個體寫入速度過快,oplog視窗太短
根據ApsaraDB for MongoDB長期以來積累的執行個體記錄備份資料判斷,當一個執行個體的oplog產生速度達到125GB/h ~ 165GB/h左右時,就很有可能會出現記錄備份無法跟上而導致產生記錄備份空洞。
您可以通過前面提到的oplog大小以及oplog視窗來估算oplog產生速度。例如某個執行個體的oplog大小為20 GB,其oplog視窗為0.06h,則oplog生產速度大概是333.3GB/h。
這樣的工作負載一般都是以下情境:
DTS、mongoShake或其他資料同步工具正在同步資料。
短時間內大量的批量INSERT或UPDATE負載。
灌資料(將大量資料快速匯入到資料庫中)。
壓力測試。
為了避免寫入速度過快而導致產生記錄備份空洞,建議您考慮以下最佳化措施:
使用同步工具時進行適當的限速(比如並發度、批次大小)。
writeConcern使用
{w:"majority"}
而不是{w:1}
。
如果您的工作負載就是會有比較高的oplog生產速度,則應轉而考慮以下最佳化方向:
使用分區叢集執行個體或者增加分區數來降低單個分區上的oplog生產速度。
結合業務情境適當調大oplog大小或者oplog最小保留時間,給記錄備份預留更長的緩衝時間。使得在工作負載降低時記錄備份可以追趕之前落後的oplog記錄。