MongoDB之compact操做詳解

摘要: compact操做步驟不少,可是能夠有效減小磁盤使用量。算法

MongoDB與磁盤

Fundebug處理的數據愈來愈多,這致使MongoDB的磁盤使用量愈來愈多,增加也愈來愈快。因而,我開始定時刪除過時數據,優化算法減小冗餘數據。可是,我發現,單純刪除文檔不能減小MongoDB磁盤使用量。這是爲何呢?下面是官方文檔的解釋:mongodb

對於WiredTiger存儲引擎(mongodb 3.2以後默認使用):How do I reclaim disk space in WiredTiger?docker

The WiredTiger storage engine maintains lists of empty records in data files as it deletes documents. This space can be reused by WiredTiger, but will not be returned to the operating system unless under very specific circumstances.數據庫

也就是說,被刪除的文檔所佔用的磁盤空間仍然由MongoDB保留,不會釋放。對於舊版MongoDB的MMAPv1存儲引擎,這一點也是同樣的。這樣作無可厚非,由於數據庫將會不斷存儲新的文檔,它們能夠利用以前保留的磁盤空間。bash

可是,若是你刪除了不少文檔,須要MongoDB釋放磁盤空間,應該如何作呢?正如文檔所述,對於WiredTiger存儲引擎,咱們可使用compact操做來實現。less

To allow the WiredTiger storage engine to release this empty space to the operating system, you can de-fragment your data file. This can be achieved using the compact command.性能

關於compact操做

compact操做會從新整理碎片化的磁盤,釋放多餘的空間。優化

Rewrites and defragments all data and indexes in a collection. On WiredTiger databases, this command will release unneeded disk space to the operating system.this

關於compact操做,我列了幾個簡單的Q&A。spa

  • compact是否會阻塞數據庫讀寫?會!所以不能在高峯期進行compact操做;對於複製集,應該對每一個節點依次進行compact操做。
  • compact是否能夠釋放磁盤空間?對於WiredTiger,是能夠的;可是對於WiredTiger存儲引擎,並不會,多餘的磁盤空間仍然會保留給MongoDB。
  • compact操做是否會佔用額外的磁盤空間?根據個人觀察,基本上不會。
  • paddingFactor應該設爲多少?我設置的值是1.1,這樣能夠爲每一個文檔留一些多餘空間,提升修改性能。這個值能夠根據實際須要進行設置。
  • compact操做須要多少時間?一個400G的複製集節點,我花了不到1個小時。這樣時間應該與數據量大小有關。
  • compact操做效果怎麼樣?減小了接近50%的磁盤空間,這個大小應該與被刪除的文檔數量有關。

compact操做步驟

因爲compact操做會阻塞MongoDB的讀寫操做,所以應該對每一個節點依次進行操做。另外,MongoDB複製集的標準維護流程是將Secodary節點暫定,使用單獨的端口啓動獨立的mongo實例進行操做,這樣能夠複製集徹底隔離。

咱們Fundebug的MongoDB集羣運行在Docker中,所以操做步驟稍微簡單一些,能夠爲你們提供參考。

Secondary節點

  • 關閉mongodb容器
sudo docker stop mongo
複製代碼
  • 啓動獨立的臨時mongodb容器
sudo docker run -it -d -p 37017:27017 -v /data/db:/data/db --name mongo_tmp mongo:3.2
複製代碼
  • 執行compact命令
mongo 127.0.0.1:37017
db.runCommand( { compact : 'events',paddingFactor: 1.1 } )
複製代碼
  • 重啓mongodb節點
sudo docker rm -f mongo_tmp
sudo docker start mongo
複製代碼

Primary節點

  • 將Primary節點變爲Secondary節點
rs.stepDown()
複製代碼
  • 按照secondary節點進行操做

參考

相關文章
相關標籤/搜索