必须直连各分片mongod执行db.runcommand({dbstats:1,scale:1048576})并结合du统计wiredtiger/log/、journal/和*.wt文件,才能获得真实磁盘占用,因db.stats()在mongos上返回的storagesize仅为逻辑值且不包含日志等实际占盘项。

直接在 mongos 上执行 db.stats() 或 db.collection.stats(),看到的 storageSize 不是各分片真实磁盘占用 —— 它只反映 primary shard 的局部值,或根本没聚合,不能用于容量评估。
sh.getShardDistribution() 只能看文档分布,不反映磁盘空间
这个函数返回每 shard 的 docs、dataSize、storageSize,但要注意:storageSize 是 WiredTiger 压缩后的逻辑大小,不含日志、检查点、journal 等实际占盘文件。它适合快速判断数据倾斜,但不能替代磁盘用量审计。
- 输出里的
storageSize单位是字节,未自动换算,容易误读为 MB/GB - 若某 shard 网络临时不可达,该函数跳过它且不报错,结果缺失但无提示
- 它底层调用的是
collStats命令,不是dbStats,所以无法拿到单分片的数据库级指标(如 freeStorageSize)
必须直连每个分片 mongod 才能查真实磁盘占用
mongos 无法透传 db.runCommand({dbStats: 1}) 到所有分片;你得逐个连接到各 shard 的 mongod 实例(不是 mongos),再执行命令。否则看到的全是 config server 或 primary shard 的伪值。
- 先用
sh.status()或db.adminCommand({listShards: 1})拿到 shard 列表和 host 地址 - 对每个 shard,用
mongo --host <shard_host>:<port> -u <user> -p <pass> --authenticationDatabase admin</pass></user></port></shard_host>连入 - 执行
db.runCommand({ dbStats: 1, scale: 1048576 }),结果中storageSize和fsUsedSize单位才是 MB - 注意:如果启用了 journal,
fsUsedSize仍不含wiredTiger/log/目录,需额外du -sh wiredTiger/log/
WiredTiger 日志和检查点会严重拉高 du -sh 结果
运维常发现 du -sh /data/db 比 dbStats.storageSize 大 2–3 倍,这不是压缩比异常,而是日志和检查点没被统计进去。
-
wiredTiger/log/默认保留最后 10 个日志文件,大写入场景下单个可达 100MB+,积压后轻松占几十 GB -
WiredTiger.turtle和WiredTiger.wt是检查点元数据,每次 checkpoint 会生成新版本,旧版不会立即删除 -
journal/目录(若启用)独立于 WiredTiger 日志,也计入磁盘但不出现在任何 MongoDB 命令结果里 - 压缩配置
storage.wiredTiger.engineConfig.journalCompressor(默认 snappy)只压缩日志内容,不减少文件数量或清理策略
真正要评估分片磁盘压力,得把 dbStats.storageSize、du -sh wiredTiger/log/、du -sh journal/、du -sh *.wt 四块加总 —— 缺一不可。很多人只看 storageSize 就扩容,结果发现日志目录吃掉一半空间,白买了机器。











