应使用sh.getShardDistribution()统计各分片数据量,它会主动向所有shard发起collStats并汇总结果;db.collection.stats()仅返回primary shard的局部统计,非全局数据。

直接在 mongos 上执行 db.collection.stats() 看到的不是全量数据分布,而是单个分片(通常是 primary shard)的局部统计 —— 这是最常被误判的点。
用 sh.getShardDistribution() 快速查各分片文档数和空间占用
这是 mongos 提供的开箱即用方法,会主动向所有 shard 发起 collStats 并汇总结果,输出直观、无需手动拼接。
- 必须在 mongos shell 中执行,且连接的是 mongos(不是单个 shard 的 mongod)
- 要求 MongoDB ≥ 4.2;低于该版本此函数不存在
- 执行前确保目标集合已启用分片,否则返回空或报错
collection is not sharded - 输出中
docs是实际文档数,dataSize是压缩前原始数据字节数,storageSize是磁盘实际占用(含 padding 和索引) - 若某 shard 临时不可达,该函数跳过并警告,不影响其余分片统计
用 sh.getShardedDataDistribution() 查带孤立文档的细粒度分布(MongoDB 6.0.3+)
这是更精细的替代方案,专为识别“孤儿文档”(orphaned docs)设计,适用于需排查数据不一致或 chunk 迁移残留的场景。
- 仅支持 MongoDB ≥ 6.0.3,且必须从 mongosh 连接 mongos 执行
- 返回结构包含
numorphaneddocs和ownedsizebytes,能区分“本该属于该 shard”的数据和迁移残留 - Atlas 的 M0 / Flex 集群不支持该命令,社区版和企业版可用
- 对时间序列集合,
numowneddocuments统计的是 measurement bucket 数,不是原始文档数
手动调用 collStats 命令(兼容老版本或需自定义字段)
当需要获取 avgObjSize、nindexes 等 db.collection.stats() 有但 sh.getShardDistribution() 不返回的字段时,就得自己连每个 shard 执行 collStats。
- 不能在 mongos 上直接运行
collStats,必须用db.getMongo().getDB("admin").runCommand(...)连接到每个 shard 的 mongod 实例 - 先通过
db.adminCommand({listShards: 1})或sh.status()获取 shard 列表及地址 - 注意
collStats的命名空间格式是"db.collection"(带点号),不是db.collection - scale 参数(如
scale: 1024)影响单位换算,不加则返回字节,加了按 KiB/MiB 显示,但所有 shard 必须用相同 scale 才可横向对比
为什么 db.collection.stats() 在分片集群里几乎没用
它只是把命令透传给某个分片(默认是 primary shard),不聚合、不路由、不重试 —— 本质是“查一个分片”,不是“查整个集合”。
- 即使集合已分片且 chunk 分布在多个节点,
stats()仍只返回 primary shard 上的数据,其余分片数据完全不可见 - 唯一例外:集合未真正分片(即
shardCollection没执行或失败),此时stats()返回全量,但已脱离“分片集群统计”前提 - 想确认是否真分片,优先跑
sh.status()或sh.getShardDistribution(),别信stats().sharded字段 —— 它只表示“是否启用过分片”,不表示“当前有数据分布在多分片”
真正容易被忽略的点是:分片数据分布 ≠ chunk 分布。chunk 数量均衡不代表数据量或文档数均衡 —— 比如小文档扎堆在一个 chunk,大文档单独占一个 chunk,sh.getShardDistribution() 的 dataSize 和 docs 才是关键指标,别只盯着 chunks 数看。


















