首先,我知道这个问题:
我的问题不是关于缩小数据库文件大小,而是更多关于重用已删除空间的问题。假设我在一个集合中有 100K 文档,然后我删除了其中的 50K。Mongo 会重复使用已删除文档释放的数据文件中的空间吗?还是他们只是“标记”为已删除?
我不太关心磁盘上文件的实际大小,它更多的是关于“它只是不断增长”。
首先,我知道这个问题:
我的问题不是关于缩小数据库文件大小,而是更多关于重用已删除空间的问题。假设我在一个集合中有 100K 文档,然后我删除了其中的 50K。Mongo 会重复使用已删除文档释放的数据文件中的空间吗?还是他们只是“标记”为已删除?
我不太关心磁盘上文件的实际大小,它更多的是关于“它只是不断增长”。
更新(2015 年 3 月):从 3.0 版本开始, MongoDB 中提供了多个存储引擎。这个答案适用于 MMAP 存储引擎(在 MongoDB 3.0 中仍然是默认的),其他引擎(例如 WiredTiger)的答案是完全不同的,很可能是可调和可调的。因此,如果您使用其他引擎,请阅读该存储引擎的相关文档以确定您的空间重用默认值和选项。
使用 MMAP 存储引擎,当文档被删除时,留下的空间被放入空闲列表中。但是,要使用该空间,稍后需要插入类似大小的文档,并且 MongoDB 需要在特定时间范围内为该文档找到合适的空间(一旦查看列表超时,它将只是追加)否则空间再利用不会经常发生。此删除是在数据文件中完成的,因此这里不会发生磁盘空间回收——所有这些都是在现有数据文件内部完成的。
如果您随后进行了修复,或从头开始重新同步辅助服务器,则数据文件将被重写并且磁盘上的空间将被回收(文档上的任何填充也将被删除)。这是您将在磁盘上看到实际空间回收的地方。对于任何其他操作(包括紧凑型),磁盘使用量不会改变,甚至可能会增加。
在 2.2+ 中,您现在可以使用collMod 命令和usePowersOf2Sizes选项来使删除空间的重复使用更有可能(请注意,这是 2.6+ 中的默认设置)。这意味着文档的初始空间分配效率稍低(例如 400 字节文档为 512 字节),但意味着当插入新文档时,它更有可能重新使用该空间。如果您要删除(或增长并因此移动)大量文档,那么从长远来看,这将更有效率。
对于任何感兴趣的人,其中一位编写了大量存储代码的人 ( Mathias Stearn ) 对存储内部进行了精彩的介绍,可以在此处找到