GridFS真实磁盘占用需分别执行collStats查fs.chunks和fs.files的storageSize并相加,因db.stats()、du、mongostat及mongodb_exporter均无法准确反映含padding与碎片的物理存储;小文件场景下还需额外估算索引体积。

不能靠 db.stats() 或系统级 du 粗略估算 GridFS 真实磁盘占用——它会漏掉 fs.chunks 的 padding、碎片和索引膨胀,且 fs.files 的元数据开销在小文件场景下可能反超数据本身。
直接执行 collStats 查 fs.chunks 和 fs.files
GridFS 实际空间由两个集合共同构成,必须分别查,不能只看数据库总大小。注意:命令必须在对应数据库上下文中运行,否则报 ns does not exist。
- 先
use myapp_db(替换为你的 GridFS 所在库名) - 运行
db.runCommand({collStats: "fs.chunks", scale: 1024}),提取storageSize字段(单位 KB) - 再运行
db.runCommand({collStats: "fs.files", scale: 1024}),同样取storageSize - 两者相加才是 GridFS 当前真实磁盘占用(不含索引额外开销,但已含 WiredTiger padding 和空闲 slot)
为什么不用 mongostat 或 mongodb_exporter
这两个工具根本不会暴露 storageSize——mongostat 只统计文档操作频次,mongodb_exporter 默认不采集集合级物理存储指标,即使开启 collect.collection,返回的也只是 avgObjSize 和文档数,无法反映磁盘块实际占用。
-
mongodb_exporter暴露的mongodb_mongod_storage_data_size_bytes是引擎层逻辑数据量,不是 GridFS 文件落地后的物理空间 -
mongostat的insert/query列对 GridFS 完全失真:上传 100MB 文件触发约 400 次insert(fs.chunks),但这些计数和字节无直接换算关系 - 试图用
du -sh /path/to/mongodb/data/myapp_db/会混入其他集合、journal、WiredTiger cache 文件,误差常达 ±30%
小文件场景下必须额外加索引体积估算
当单个文件 fs.files 和 fs.chunks 的索引开销会主导总空间。默认索引 {files_id: 1, n: 1} 和 {uploadDate: 1} 不是免费的。
- 用
db.fs.chunks.stats().indexDetails查索引实际size(字节数),重点看files_id_1_n_1条目 - 用
db.fs.files.stats().indexDetails查uploadDate_1索引大小;若你按filename查询频繁,还得加上filename_1索引 - 实测:百亿级 1KB 文件下,
fs.chunks索引体积可达其storageSize的 1.5 倍以上
真正关键的是:不要等 storageSize 明显大于 size 才警觉——WiredTiger 的空间释放是懒惰的,删除大量旧文件后,storageSize 不会自动回落,得手动 db.runCommand({compact: "fs.chunks"})(注意:该操作阻塞写入,且仅支持 WiredTiger 引擎)。


















