能,但 config.collections 只记录显式分片的集合,未分片集合不出现;最稳方式是 use 数据库后执行 db.collection.stats().sharded,返回 false 即未分片。

直接查 config.collections 能看到未分片集合吗?
能,但结果容易误读。该集合只记录「显式分片过」的集合(即执行过 sh.shardCollection 的),而未分片集合根本不会出现在 config.collections 里。所以你用 db.collections.find({ "dropped": { $ne: true } }) 查到的,全是已分片的;空结果 ≠ 没有未分片集合,只是它们不登记在这里。
db.collectionName.stats().sharded 是最稳的判断方式
这是唯一在 mongos 上就能直接、准确获取状态的方法,不依赖 config 库权限或 shard 连接。执行前必须先 use 到对应数据库:
use mydb db.mycoll.stats().sharded
返回 true 表示已分片,false 就是未分片(哪怕集合为空)。注意:sharded 字段只反映分片状态,和数据量、索引、是否启用分片库无关。
- 如果返回
undefined或报错not found,说明集合不存在 - 对不存在的集合调用
.stats()不会自动创建它 - 该命令在 mongos 和单节点 mongod 上行为一致,适合脚本批量检查
为什么不能靠 db.getCollectionNames() + 猜?
因为 db.getCollectionNames() 在 mongos 上能列出所有集合名,包括未分片的,但它完全不提供分布信息。你以为“列出来了就说明存在”,但其实:这些未分片集合物理上全挤在 primary shard 上,其他 shard 根本没它们的任何数据。常见误判场景:
- 用
sh.status()看到某个 shard 磁盘使用率远高于其他,却查不到大集合 —— 很可能就是几十个未分片小集合全堆在 primary shard 上 - 在 mongos 上执行
db.mycoll.countDocuments({})有结果,就以为数据已跨 shard —— 实际只查了 primary shard 的副本集主节点 - 误信“启用了分片库(
partitioned: true)= 所有集合都分片了” —— 完全错误,这只是允许你后续对集合执行shardCollection
审计未分片集合时,最容易漏掉的两个点
一是系统库(如 admin、config、local)默认不支持分片,里面所有集合天然未分片,但常被忽略;二是新创建的数据库,即使执行过 sh.enableSharding("newdb"),只要没对具体集合跑 sh.shardCollection,里面所有集合仍是未分片状态,且全部落在该库绑定的 primary shard 上 —— 这个绑定关系不会随时间自动变化,也不会因写入压力触发迁移。











