MongoDB compact 命令詳解【轉載】

爲什麼需要 compact

一圖勝千言

1

remove 與 drop 的區別

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

  • db.collection.remove({}, {multi: true}),逐個文檔從 btree 裏刪除,最後所有文檔被刪除,但文件物理空間不會被回收

  • db.collection.drop() 刪除集合的物理文件,空間立即被回收

總的來說,remove 會產生邏輯的空閒空間,這些空間能立即用於寫入新數據,但文件佔用的總物理空間不會立即回收;通常只要持續在寫入數據,有物理空間碎片問題並不大,不需要去 compact 集合,有的場景,remove 了大量的數據後,後續的寫入可能並不多,這時如果想回收空間,就需要顯式的調用 compact。

compact 命令對讀寫的影響

compact 一個集合,會加集合所在DB的互斥寫鎖,會導致該DB上所有的讀寫請求都阻塞;因爲 compact 執行的時間可能很長,跟集合的數據量相關,所以強烈建議在業務低峯期執行,避免影響業務。

compact 具體做了什麼?

Compact 動作最終由存儲引擎 WiredTiger 完成,WiredTiger 在執行 compact 時,會不斷將集合文件後面的數據往前面空閒的空間寫,然後逐步 truancate 文件回收物理空間。每一輪 compact 前,WT 都會先檢查是否符合 comapact 條件。

  1. 前面80%的空間裏,是否有20%的空閒空間,用於寫入文件後面20%的數據,或者

  2. 前面90%的空間裏,是否有10%的空閒空間,用於寫入文件後面10%的數據

如果上面都不滿足,說明執行compact肯定無法回收10%的物理空間,此時 compact 就回退出。所以有時候遇到對一個大集合進行 compact,compact立馬就返回ok,集合的物理空間也沒有變化,就是因爲 WiredTiger 認爲這個集合沒有 compact 的必要。

如何預估compact能回收多少空間?

The amount of empty space available for reuse by WiredTiger is reflected in the output of db.collection.stats() under the heading wiredTiger.block-manager.file bytes available for reuse.

mymongo:PRIMARY> db.coll.stats().wiredTiger["block-manager"]["file bytes available for reuse"]
5033984

執行 compact

執行前請確保你已經讀懂了上面的內容,知道compact命令的原理、影響

// compact somedb.somecollection
 use somedb
 db.runCommnd({compact: "somecollection"})

 // compact oplog,在副本集primary上執行需要加 force 選項
 use local
 db.runCommnd({compact: "somecollection", force: true})

參考資料

作者簡介

張友東,阿里雲高級技術專家,主要關注分佈式存儲與數據庫等技術領域,先後參與淘寶分佈式文件系統TFS、阿里雲數據庫(PolarDB、MySQL、MongoDB、Redis)等項目的開發工作,致力於讓開發者用上最好的雲數據庫服務。

原文地址: http://mongoing.com/archives/26907



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