sh.addshard() 必须在mongos实例上执行,用于将分片副本集添加到分片集群;若返回“not master”错误,通常因误连secondary节点或配置服务器不可达,需确认连接对象为mongos、config server健康且网络与权限配置正确。

sh.addShard() 返回 "not master" 错误
这是最常见的情况:你连的是某个分片副本集的从节点(secondary),但 sh.addShard() 必须由 mongos 执行,且该 mongos 必须能正常连接配置服务器(config server)并获得写权限。错误本身不是在分片上抛出的,而是 mongos 向配置服务器写入元数据失败时回传的误导性提示。
检查步骤如下:
- 确认你连接的是
mongos进程,不是某个mongod(比如没加--host直接连了本地 27017,结果连上了分片节点);可用db.runCommand({isMaster: 1})看返回里有没有"msg": "isdbgrid"字段,有才是 mongos - 用
sh.status()确认配置服务器是否可达、状态是否为"configServerStatus": "OK";若报错或超时,说明 config server 副本集有问题 - 检查配置服务器副本集是否健康:
mongo --host configReplSet/config0.example.com:27019后执行rs.status(),确保主节点(stateStr: "PRIMARY")存在且多数成员在线 - 确认配置服务器的
bindIp允许mongos所在主机访问,防火墙未拦截 27019(默认端口)
新分片副本集无法被识别
sh.addShard("rs1/host:27018") 报 "no host described in new configuration" 或 "failed to connect to...",说明 mongos 根本解析不了你写的地址,或者目标 mongod 拒绝连接。
关键点不在“能不能 ping 通”,而在 mongos 进程能否用完全相同的字符串建立 MongoDB 协议连接:
- 地址必须可被
mongos主机 DNS 解析 —— 不要用localhost或127.0.0.1,必须用其他节点能解析的主机名或真实 IP(如shard01-node1.internal:27018) - 目标
mongod必须启动时带--shardsvr参数,否则拒绝作为分片加入 - 目标
mongod的net.bindIp配置需包含其对外服务的 IP,不能只绑127.0.0.1 - 用
mongo --host shard01-node1.internal --port 27018 --eval "db.runCommand({isMaster:1})"在mongos所在机器上手动测试连通性
添加后 sh.status() 不显示新分片
命令看似成功(返回 { "ok" : 1 }),但 sh.status() 里没有新分片,也没有迁移日志,说明元数据写入成功但分片未真正“激活”。
本质是副本集名称不匹配或初始化未完成:
- 确保
sh.addShard()中的副本集名(rs1)和目标mongod启动时的--replSet rs1完全一致(大小写敏感) - 目标副本集必须已执行过
rs.initiate(),且rs.status().members中至少有一个成员状态为"stateStr": "PRIMARY"或"SECONDARY";仅启动进程但未初始化副本集,mongos会静默忽略该分片 - 检查配置服务器上的
config.shards集合:use config; db.shards.find(),确认新分片文档已写入;若存在但sh.status()不显示,可能是mongos缓存未刷新,尝试重启mongos - 注意:添加分片后不会立即触发数据迁移,只有对已分片集合执行操作(如插入)或等待均衡器下一次运行时才会开始搬数据块
添加过程中集群卡住或迁移停滞
新分片显示在 sh.status() 里,但 "balancer" : "ON" 下长期无迁移动作,或 chunks 数量始终为 0,常见于配置或资源瓶颈。
重点排查以下几项:
- 确认目标分片的
mongod进程日志中没有"sharding not enabled"或"not authorized"类报错;若启用了认证,mongos和分片间需配置 keyfile 或 x.509,并在mongos启动时用--keyFile指定 - 检查分片磁盘空间:新分片
dbpath所在磁盘剩余空间不足 10%,均衡器会跳过该分片 - 查看
sh.getBalancerState()和sh.isBalancerRunning(),确认均衡器确实开启且活跃;有时因 DDL 操作(如reshardCollection)正在执行,addShard会被排队等待,但不会报错 - 如果集群刚添加完分片就立刻执行了
reshardCollection,注意该操作期间addShard实际是挂起状态,直到重分片完成才真正生效
真正麻烦的不是命令输错,而是所有组件都“看起来正常”,但元数据、网络可达性、角色权限、磁盘水位这四个层面只要有一处隐性不匹配,sh.addShard() 就会静默失效或半途卡死。











