阿里雲數據庫MongoDB版清理oplog日志和compact命令詳解


1、問題描述:

今天看到公司mongodb的oplog有點大,看到雲數據庫MongoDB版日志清理策略。

MongoDB數據庫在長期頻繁地刪除/寫入數據或批量刪除了大量數據,將產生很多物理空間碎片。

這些碎片將占用磁盤空間,降低磁盤利用率。

您可以對集合中的所有數據和索引進行重寫和碎片整理,釋放未使用的空間,提升磁盤利用率和查詢性能。

下圖說明:

2、前提條件

mongo實例的存儲引擎為WiredTiger。

3、詳細信息

  • 用戶禁止使用  db.repairDatabase命令。
  • 日志占用空間過大時,會觸發自動清理策略。

4、注意事項

  • 執行該操作前,建議對數據庫進行備份
  • 執行該操作會導致集合所屬的數據庫被鎖定,且該數據庫的讀寫操作將被阻塞,請在業務低峰期操作。
  • 說明:執行物理空間回收命令(compact)所需的時間與集合數據量、系統負載等因素有關。

5、remove與drop的區別

MongoDB 里刪除一個集合里所有文檔,有兩種方式

  • db.collection.remove({}, {multi: true}),逐個文檔從 btree 里刪除,最后所有文檔被刪除,但文件物理空間不會被回收
  • db.collection.drop() 刪除集合的物理文件,空間立即被回收

multi:可選,mongodb 默認是false,只更新找到的第一條記錄,如果這個參數為true,就把按條件查出來多條記錄全部更新。

總的來說:

新寫入的數據將會使用未被回收的物理空間,所以在數據持續寫入的場景中,不需要頻繁執行compact命令整理物理空間碎片。

有的場景,remove 了大量的數據后,后續的寫入可能並不多,這時如果想回收空間,就需要顯式的調用 compact。

6、compact 具體做了什么?

Compact 動作最終由存儲引擎 WiredTiger 完成,WiredTiger 在執行 compact 時,會不斷將集合文件后面的數據往前面空閑的空間寫,

然后逐步 truancate 文件回收物理空間。每一輪 compact 前,WT 都會先檢查是否符合 comapact 條件。

  1. 前面80%的空間里,是否有20%的空閑空間,用於寫入文件后面20%的數據,或者
  2. 前面90%的空間里,是否有10%的空閑空間,用於寫入文件后面10%的數據

如果上面都不滿足,說明執行compact肯定無法回收10%的物理空間,此時 compact 就回退出。

所以有時候遇到對一個大集合進行 compact,compact立馬就返回ok:1,集合的物理空間也沒有變化,就是因為 WiredTiger 認為這個集合沒有 compact 的必要。

7、預估回收的物理空間

1、連接mongo實例parmary或scondary

2、切換至集合所在的數據庫。

use <database_name>

3、執行下列命令查詢預估回收空間。

db.<collection_name>.stats().wiredTiger["block-manager"]["file bytes available for reuse"]

4、執行結果示例:

整理單節點實例/副本集實例的碎片

1、通過mongo shell連接MongoDB實例的Primary節點

2、切換至集合所在的數據庫。

use <database_name>

3、執行db.stats()命令查看碎片整理前數據庫占用的磁盤空間。

4、執行以下命令,對某個集合進行碎片整理。

db.runCommand({compact:"<collection_name>",force:true})

5、等待執行,返回{ "ok" : 1 }代表執行完成。

6、碎片整理完畢后,可通過db.stats()命令查看碎片整理后數據庫占用的磁盤空間

本案例碎片整理前后的對比如下圖所示:

參數說明:

<database_name>:數據庫名。
<collection_name>:集合名。
force為可選項,如您需要在副本集實例的Primary節點執行該命令,需要設置force的值為true。
compact操作不會傳遞給Secondary節點,當實例為副本集實例時,請重復上述步驟通過mongo shell連接至Secondary節點,執行碎片整理命令。

整理分片集群實例的碎片

1、通過mongo shell連接分片集群實例中的任一mongos節點

2、執行db.stats()命令查看碎片整理前數據庫占用的磁盤空間。

3、執行以下命令,對Shard節點中的Primary節點進行集合的碎片整理。

db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>",force:true}})

4、執行以下命令,對Shard節點中的Secondary節點進行集合的碎片整理。

db.runCommand({runCommandOnShard:"<Shard ID>","command":{compact:"<collection_name>"},queryOptions: {$readPreference: {mode: 'secondary'}}})

參數說明:

<Shard ID>:Shard節點ID。
<collection_name>:集合名。

碎片整理完畢后,可通過db.runCommand({dbstats:1}) 命令查看碎片整理后數據庫占用的磁盤空間。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM