当由于数据删除以及其他原因导致实际数据大小下降时,MongoDB 不会恢复磁盘空间。在线文档中有一个不错的解释:
为什么我的数据目录中的文件比我的数据库中的数据大?
数据目录中的数据文件,即默认配置中的 /data/db 目录,可能比插入数据库的数据集大。考虑以下可能的原因:
预分配的数据文件。
在数据目录中,MongoDB 将数据文件预分配到特定大小,部分是为了防止文件系统碎片。MongoDB 将第一个数据文件命名为 .0,下一个 .1 等。mongod 分配的第一个文件是 64 兆字节,接下来是 128 兆字节,依此类推,最多 2 GB,此时所有后续文件都是 2 GB。数据文件包括已分配空间但不包含数据的文件。mongod 可能会分配一个 90% 为空的 1 GB 数据文件。对于大多数较大的数据库,与数据库相比,未使用的分配空间很小。
在类 Unix 系统上,mongod 预分配一个额外的数据文件并将磁盘空间初始化为 0。在后台预分配数据文件可防止下一次分配新数据库文件时出现明显延迟。
您可以通过将 preallocDataFiles 设置为 false 来禁用预分配。但是,不要在生产环境中禁用 preallocDataFiles:仅使用 preallocDataFiles 进行测试以及经常删除数据库的小型数据集。
在 Linux 系统上,您可以使用 hdparm 来了解分配的成本可能是多少:
time hdparm --fallocate $((1024*1024)) 测试文件
操作日志。
如果此 mongod 是副本集的成员,则数据目录包含 oplog.rs 文件,该文件是本地数据库中预先分配的上限集合。在 64 位安装中,默认分配约为磁盘空间的 5%,有关更多信息,请参阅 Oplog Sizing。在大多数情况下,您不需要调整 oplog 的大小。但是,如果您这样做,请参阅更改 Oplog 的大小。
日记。
数据目录包含日志文件,这些文件在 MongoDB 将写入操作应用到数据库之前将它们存储在磁盘上。请参阅日记机制。
空记录。
MongoDB 在删除文档和集合时维护数据文件中的空记录列表。MongoDB 可以重用这个空间,但永远不会把这个空间还给操作系统。
要对分配的存储进行碎片整理,请使用 compact,它对分配的空间进行碎片整理。通过对存储进行碎片整理,MongoDB 可以有效地使用分配的空间。compact 需要多达 2 GB 的额外磁盘空间才能运行。如果磁盘空间严重不足,请不要使用 compact。
重要的
compact 仅从 MongoDB 数据文件中删除碎片,并且不会将任何磁盘空间返回给操作系统。
要回收已删除的空间,请使用 repairDatabase,它会重建数据库,对存储进行碎片整理,并可能向操作系统释放空间。repairDatabase 需要多达 2 GB 的额外磁盘空间才能运行。如果磁盘空间严重不足,请不要使用 repairDatabase。
http://docs.mongodb.org/manual/faq/storage/
他们没有告诉您的是恢复/恢复磁盘空间的另外两种方法 - mongodump/mongorestore 就像您所做的那样,或者使用空磁盘将新成员添加到副本集中,以便它从头开始写入它的数据库文件。
如果您对此感兴趣,db.stats() 命令会返回大量有关数据、索引、存储和文件大小的数据:
http://docs.mongodb.org/manual/reference/command/dbStats/