sh.getbalancerstate()返回false并非自动关闭,而是因手动执行sh.stopbalancer()、activewindow时段外、重启后未启用或mongos缓存过期所致。

它不会自动关闭——如果你观察到 balancer 状态为 false,大概率是被人手动停了,或者配置了均衡窗口限制了运行时段。
sh.getBalancerState() 返回 false 的真实原因
很多人看到 sh.getBalancerState() 返回 false 就以为“它自己关了”,其实 MongoDB 的 balancer 没有自停逻辑。常见真实原因包括:
- 有人执行过
sh.stopBalancer(),且未再调用sh.startBalancer() - 配置了
activeWindow,当前时间不在窗口内(比如设成"start": "02:00", "stop": "04:00",其余时间 balancer 就不启动) - 集群刚完成一次重启,但没执行
sh.startBalancer()—— MongoDB 不会持久化 balancer 运行状态 - 连接的 mongos 节点缓存了旧状态,
sh.getBalancerState()读的是本地 config 数据库缓存,不是实时 config server 主节点值
为什么 sh.isBalancerRunning() 有时卡住或返回 false
sh.isBalancerRunning() 查的是 balancer 进程是否正在迁移 chunk,不是开关状态。它返回 false 的典型场景有:
- 没有 chunk 需要迁移(数据已均衡,或所有分片都空)
- 存在 jumbo chunk:balancer 遇到标记为
jumbo的 chunk 会跳过整个集合,不再尝试迁移 - 目标分片磁盘空间不足:moveChunk 失败后会退避重试,但重试间隔越来越长,看起来像“停了”
- config server 主节点选举刚完成,balancer 还没在新主上拉起(通常几秒内恢复)
检查 balancer 真实状态该看哪几个命令
单靠一个命令容易误判,必须组合验证:
-
sh.getBalancerState():确认是否允许 balancer 运行(开关) -
sh.isBalancerRunning():确认此刻是否有迁移任务在执行(进程) -
db.adminCommand({ balancerStatus: 1 }):返回详细状态,含最近迁移时间、失败原因、jumbo chunk 列表 -
sh.status(true):重点看每个分片的chunks数和是否有jumbo标记
最容易被忽略的是:即使 sh.getBalancerState() 是 true,只要存在一个 jumbo chunk,对应集合就彻底退出均衡流程,且不会报错提示——它只是安静地跳过。











