MongoDB-compact-命令详解

32次阅读

共计 1337 个字符,预计需要花费 4 分钟才能阅读完成。

为什么需要 compact

一图胜千言

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})

参考资料

  • MongoDB compact command

本文作者:张友东

阅读原文

本文为云栖社区原创内容,未经允许不得转载。

正文完
 0