必须手动执行flushrouterconfig命令,因为mongos不自动同步config server的分片变更,仅依赖默认30秒以上且易卡住的缓存刷新机制;sh.addshard()成功仅更新config server元数据,mongos本地路由表仍为旧列表,导致shardnotfound或空查询结果。

mongos 执行 sh.addShard() 成功但查不到新分片
这不是配置失败,而是 mongos 没刷新本地路由缓存。它只依赖默认 30 秒以上、且容易卡住的后台轮询机制同步 config server 变更。sh.addShard() 成功仅表示 config server 的 config.shards 集合已写入,mongos 自己的路由表仍是旧的。现象是应用查询返回空结果或报 ShardNotFound 错误。
验证方式:连到 mongos 后执行 db.runCommand({getShardMap: 1}),检查返回的 shards 字段是否包含新分片。别查 config.shards ——那只是 config server 的状态,不是 mongos 当前看到的视图。
必须手动执行 flushRouterConfig 才能生效
命令极简,但执行位置和权限错不得:
- 必须连接到 mongos 实例执行(不能连 config server 或 shard)
- 命令是
db.runCommand({flushRouterConfig: 1}),无参数、不支持选项 - 需
clusterAdmin角色权限;若失败,常见原因是权限不足或 mongos 正忙(重试即可) - 成功返回
{"ok": 1},该 mongos 进程立即重载全部路由信息(分片列表、zones、chunk 范围),毫秒级完成
以下操作后都必须人工刷一次:sh.addShard() / sh.removeShard()、手动调用 sh.splitAt() 或 sh.moveChunk()、config server 主从切换/重启恢复后、MongoDB 升级后首次启动 mongos。
DNS 解析慢会掩盖真实问题
很多“mongos 找不到分片”的 case 其实是 DNS 卡在解析 shard 地址上。mongos 默认调用系统 getaddrinfo(),若 DNS 返回 AAAA 记录或响应慢,单次路由决策可能多耗 1–3 秒,导致超时或连接失败,让人误以为是分片未注册。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
排查与实操建议:
- 启动 mongos 时加
--bind_ip 127.0.0.1,并在配置中显式写死所有 shard 的 IP(而非域名),彻底绕过 DNS - 若必须用域名,确保 DNS 服务器快速响应 A 记录,并在
/etc/gai.conf中加precedence ::ffff:0:0/96 100禁用 IPv6 回退 - 用
strace -e trace=getaddrinfo,connect -p $(pgrep mongos)抓实际行为,确认是否真卡在 DNS
防火墙或安全组策略常被忽略
即使 mongos 能 ping 通 shard IP,也不代表端口可达。mongos 到 shard 的通信走的是数据端口(如 27018),不是 config server 端口(27019)。常见漏配点:
- 云厂商安全组只放行了 mongos → config server 的 27019,忘了开 mongos → shard 的 27018
- 企业内网防火墙策略按服务名过滤,而 shard 地址用了别名或动态域名,规则未覆盖
- telnet 测试时用了错误端口(比如 telnet shard-host 27019 成功,但实际该连 27018)
务必用 telnet <shard-ip><shard-port></shard-port></shard-ip> 直接测试 mongos 所在机器到每个 shard 数据端口的连通性。别信 ping,也别只测 config server 端口。
真正卡住的往往不是 sh.addShard() 是否成功,而是 flushRouterConfig 是否被执行、DNS 是否静默拖慢、以及防火墙是否只开了半截链路——这三个点全验完,90% 的“找不到分片”问题就定位清楚了。










