Mongodb
mongodb compact 什麼都不做 - mongodb.log 中沒有條目,db.currentOp() 中沒有任何內容
我們有空間問題。實際數據大小只有 5 GB,但由於刪除了文件,磁碟大小為 15 GB。MongoDB (3.0.6) 在我們無法擴展卷的 docker 容器中執行。
# tail -f mongod.log 2016-04-26T14:43:59.631+0000 I STORAGE [FileAllocator] allocating new datafile /data/work/mongodb/data/opWNFbyNlGQ6xShT.11, filling with zeroes... 2016-04-26T14:43:59.632+0000 I STORAGE [FileAllocator] FileAllocator: posix_fallocate failed: errno:28 No space left on device falling back 2016-04-26T14:43:59.632+0000 I STORAGE [FileAllocator] error: failed to allocate new file: /data/work/mongodb/data/opWNFbyNlGQ6xShT.11 size: 2146435072 failure creating new datafile; lseek failed for fd 40 with errno: errno:2 No s^C
磁碟
/dev/vdh 16G 15G 553M 97% /data/a6a186a3-dc98-4f47-83f3-96e953c18b69
repairDatabase 不起作用,因為沒有暫存空間
> db.runCommand( { repairDatabase: 1 } ); { "ok" : 0, "errmsg" : "Cannot repair database opWNFbyNlGQ6xShT having size: 14975762432 (bytes) because free disk space is: 578928640 (bytes)", "code" : 14031 }
所以我嘗試了
> db.runCommand ( { compact: 'accounts', paddingFactor: 1.1 } ) { "ok" : 1 }
我沒有看到任何進展
> db.currentOp() { "inprog" : [ ] } > db.currentOp() { "inprog" : [ ] } > db.currentOp() { "inprog" : [ ] }
沒有
mongodb.log
關於緊湊操作的條目您可以通過查看 mongod 日誌文件或在另一個 shell 實例中執行 db.currentOp() 來查看中間進度。
為什麼緊湊失敗?
是我們做轉儲/刪除/恢復的唯一解決方案嗎?
由於您使用的是 MMAP 儲存引擎,因此需要注意以下幾個因素:
- 該
compact
命令僅對 MMAP 中的數據文件和索引進行碎片整理;它不會向作業系統釋放未使用的空間。執行對於減少碎片compact
和鼓勵可用空間重用仍然有用,但如果您的磁碟空間非常低,則無濟於事。compact
MMAP 中的命令在壓縮操作期間需要額外的磁碟空間(最多 2GB) 。- 在 MongoDB 3.2 中,
compact
是一個阻塞命令(用於壓縮的集合的數據庫級鎖定)。在 MMAPv1 中回收預分配空間的方法是通過重新同步(推薦用於副本集)或修復(獨立部署的唯一選項)來重建數據庫。
repairDatabase 不起作用,因為沒有暫存空間
您可以使用命令行選項
--repairpath
或配置文件選項storage.repairPath
在修復過程中為工作空間提供額外的儲存空間(即第二個卷):mongod --repair --repairpath /path/to/extraspace --dbpath ...
修復過程完成後,重建的數據文件將駐留在 中,
dbpath
並且repairpath
應該為空。WiredTiger 儲存引擎
如果您將來可以選擇升級到 WiredTiger 儲存引擎,它比 MMAP 有許多改進:
- 預設情況下壓縮數據文件和索引(使用可配置的壓縮選項,可以全域設置或按集合設置)。
- 該
compact
命令可以將儲存釋放到 O/S (MongoDB 3.2.3+)。- 為了執行該
compact
命令,應該需要最少的額外空間。