sh.addShard() 添加分片后需手动启用均衡器并确保副本集健康,否则数据不会自动迁移;参数必须为完整副本集连接串,且新分片须状态正常、端口与角色配置正确。

直接用 sh.addShard() 命令就能加,但加完不等于立刻可用——数据不会自动流过去,得等均衡器开始迁移 chunk,而这个过程可能卡住或拖很久。
sh.addShard() 的参数必须是副本集连接字符串
不是随便一个 mongod 地址都能加。新分片必须是已初始化、状态健康的副本集,且连接串格式严格:
-
sh.addShard("rs2/mongodb1.example.net:27018,mongodb2.example.net:27018,mongodb3.example.net:27018")—— 正确:含副本集名 + 至少一个可连通的成员 -
sh.addShard("mongodb1.example.net:27018")—— 错误:单节点地址,会被拒绝,报错no replica set configured -
sh.addShard("rs2/mongodb1.example.net:27018")—— 可行但有风险:只写一个成员,若该节点宕机,addShard会超时失败
务必提前在目标副本集上执行 rs.status() 确认状态为 PRIMARY 或 SECONDARY,且无 STARTUP / RECOVERING 等异常状态。
添加后 chunk 迁移常卡在 “balancing” 阶段
执行完 sh.addShard(),运行 sh.status() 查看分片列表和每个分片的 chunk 数。常见现象是新分片长期显示 chunks: 0,旧分片 chunk 数不变。
- 检查
sh.getBalancerState()—— 必须返回true,否则均衡器根本没开 - 检查
sh.isBalancerRunning()—— 返回false表示当前没有迁移任务在跑(可能是刚启动,或被手动停了) - 确认
sh.setBalancerState(true)已执行,且没有设置窗口限制:sh.setBalancingWindow({activeWindow: {start: "22:00", end: "06:00"}})会导致白天不迁移 - 查看
db.printShardingStatus()中的balancer段,留意是否有Currently running: no或Failed to start balancer: ...
Ops Manager 或 Atlas 界面添加时端口和角色容易配错
图形界面看似点点就完事,但后台仍依赖同一套规则。最容易出问题的是:
-
Port填成 27017 —— 如果该主机上已有其他mongod占用此端口(比如 config server),新分片启动失败,日志报Address already in use -
Member类型选错:比如把本该是Default的数据节点设成Arbiter Only,导致副本集无法选举出 primary,sh.addShard()直接失败 -
Votes和Priority全设为 0 —— 节点无法参与选举,副本集 stuck 在STARTUP2,永远进不了PRIMARY状态 - Hostname 填 IP 而非 DNS 名 —— MongoDB 5.0+ 会拒绝启动,报错
hostname validation failed,尤其在跨网络部署时更明显
真正麻烦的不是加分片这一步,而是加完之后看不到数据流动——这时候别急着重试,先盯紧 sh.status() 和 rs.status(),再查 mongos 日志里有没有 moveChunk 相关的 error 或 warning。迁移卡住十次里有八次是因为某个分片磁盘满、oplog 太小,或者网络策略拦了内部心跳包。











