mongos上查不到慢查询是因为其仅路由请求而不执行查询,profile日志实际存储在各shard的mongod中;需通过sh.status()定位shard,直连对应mongod并为system.profile创建ts索引,调低slowms阈值,重点分析docsExamined与nreturned比值及planSummary识别广播查询。
在分片集群里查慢查询,system.profile 只存在于各 mongod shard 节点上,mongos 上查不到——这不是配置错了,是设计如此。
mongos 不执行任何查询逻辑,只做路由和结果合并。调用 db.setProfilingLevel() 后返回 {"ok": 0, "errmsg": "no profiling information available"} 是正常现象,不是权限或连接问题。
mongod 实例(即每个 shard)上,profile 数据只会写入对应节点的 system.profile
mongos 的 system.profile 均为空或不可用,连上去也查不到业务查询记录mongos 上浪费时间建索引或调阈值,它根本不会写 profile先确认查询到底打到了哪些 shard,再挨个连过去查。不能靠猜,也不能只看负载高就直奔 primary。
mongos 上运行 sh.status(),重点看目标集合的 chunks 分布和 shards 列表,记下 host 字符串(如 shard02/10.0.1.20:27018,10.0.1.21:27018)db.getSiblingDB("config").shards.find() 拿到每个 shard 的完整地址列表,挑出你怀疑的节点(比如日志里频繁出现 "planSummary":"SHARD_MERGE" 的那个)mongo --host 10.0.1.21:27018 -u user -p pwd --authenticationDatabase admin,避免在 primary 上加额外压力刚连上别急着 find,不处理这三项,查起来要么慢、要么漏、要么压根找不到。
db.system.profile.createIndex({ ts: -1 }),否则 find({millis: {$gte: 50}}).sort({ts: -1}) 会全表扫描,几秒变几十秒slowms:db.setProfilingLevel(1, {slowms: 50}),分片环境下单个 shard 执行可能只有 10–20ms,但叠加网络、合并后总耗时超 300ms,不调低就记录不到db.getProfilingStatus() 返回 "was": 1 且 "slowms": 50,才算真正启用别只盯着 millis 数值。一个 320ms 的请求在 mongos 日志里出现,但在 shard 的 system.profile 里可能只看到几个 millis: 7 的记录——这是正常的,因为 shard 只记自己干的那部分活。
docsExamined > nreturned * 10 的记录,比如 docsExamined: 50000, nreturned: 25,说明索引没走或者失效planSummary:出现 "COLLSCAN" 或 "IXSCAN" 但 keysExamined: 0,基本等于没索引explain("executionStats") 复现,特别注意 shards 字段下是否列出了多个节点——如果是,说明触发了广播查询,大概率缺分片键最容易被忽略的是:profile 数据默认只保留最近 1MB 或 30 分钟(取决于 capped size),等出问题再开 profiler,早就覆盖掉了。得提前在关键 shard 上常驻开启,并定期检查索引是否还在。