删了大半数据,磁盘占用为什么没变?这篇用 12 万个文档的集合,对比 deleteMany 前后的 dataSize、storageSize、磁盘文件大小和可复用空闲空间,再看 compact 和 drop 各自能还多少。
文档数 dataSize storageSize 磁盘文件 可复用空闲 索引总大小 插入后 120,000 39,720,000 40,747,008 40,747,008 16,384 2,625,536
12 万个文档约 39.7 MB,磁盘文件 40.7 MB,几乎没有可复用空闲。
delete_many 删除 108,000 个,耗时 0.3 s
文档数 dataSize storageSize 磁盘文件 可复用空闲 索引总大小
删除后 12,000 3,972,000 45,527,040 45,527,040 40,726,528 3,284,992
磁盘文件 40,747,008 → 45,527,040(变化 +4,780,032 字节);可复用空闲 16,384 → 40,726,528删掉 90% 后 dataSize 降到约 4 MB,磁盘文件却没变小(反而 +4.8 MB),多出来的 40.7 MB 变成“可复用空闲”留在文件里。
文档数 dataSize storageSize 磁盘文件 可复用空闲 索引总大小 再插入 10 万个后 112,000 37,072,000 45,522,944 45,522,944 6,574,080 3,284,992 磁盘文件 45,527,040 → 45,522,944(-4,096 字节);可复用空闲 40,726,528 → 6,574,080
再插入 10 万个文档,文件大小几乎不变,可复用空闲降到 6.6 MB:删除的空间留给了后来的写入。
又删除了 90,000 个
文档数 dataSize storageSize 磁盘文件 可复用空闲 索引总大小
删除后 22,000 7,282,000 45,522,944 45,522,944 36,401,152 3,297,280
compact 返回 {'bytesFreed': 36347904, 'ok': 1.0}(耗时 0.2 s)
compact 后 22,000 7,282,000 9,175,040 9,175,040 53,248 3,297,280
磁盘文件 45,522,944 → 9,175,040(减少 36,347,904 字节,80%);索引总大小 3,297,280 → 3,297,280compact 把空闲空间还给操作系统:文件从 45.5 MB 降到 9.2 MB。这个实验里索引总大小在 compact 前后没有变化。
compact 期间(含前后各 0.5 s)的 read: 6018 次,中位数 0.11 ms,最大 5 ms compact 期间(含前后各 0.5 s)的 write: 6018 次,中位数 0.10 ms,最大 1 ms compact 本身耗时 0.4 s;期间工作线程的错误数: 0 []
在这个 12,000 文档的小集合上,compact 0.4 s,期间同一个集合的读写没有错误,最大延迟 5 ms。大集合上的影响没有测。
t3 插入 50,000 个: 磁盘文件 16,289,792
deleteMany({}) 之后: 文档数 0,磁盘文件 16,293,888,可复用空闲 16,285,696
drop 之后文件还在吗: FalsedeleteMany({}) 之后文件还在,全是空闲空间;drop 才会立刻删文件。