balancer 当前是否运行需综合判断:sh.getbalancerstate() 返回启用开关,sh.isbalancerrunning() 反映瞬时迁移状态,config.locks中_id:"balancer"的state字段(2为锁定,0为空闲)揭示锁态,三者缺一不可。

怎么确认 balancer 当前是开着还是关着
sh.getBalancerState() 返回的是 balancer 的启用开关状态,不是它此刻是否在干活。很多人看到 true 就以为“一切正常”,结果发现 chunk 迁移卡住了——其实 balancer 可能正被别的操作锁住,或者压根没触发迁移条件。
实操建议:
- 先跑
sh.getBalancerState()确认开关是true;再立刻查锁:sh.isBalancerRunning()(返回布尔值)或更可靠地看config.locks集合里_id: "balancer"的state字段 -
sh.isBalancerRunning()是最直接的“此刻是否在迁移”判断,但它有延迟:刚启动迁移时可能还没来得及更新状态 - 如果
sh.getBalancerState()是false,sh.isBalancerRunning()必定是false,但反过来不成立
怎么查 balancer 被谁锁住了
balancer 不工作,90% 是因为 config.locks 里 _id: "balancer" 的文档被占着。常见锁源包括手动 sh.stopBalancer()、正在执行的 moveChunk、集合均衡配置变更、甚至某些驱动的 bulk 操作触发了内部锁。
实操建议:
- 用
db.getSiblingDB("config").locks.findOne({_id: "balancer"})查当前锁文档 - 重点看
state字段:2表示“已获取锁”,0表示“空闲”;再看who字段,通常是"mongos_XXX"或"mongod_XXX",结合when判断是否异常滞留 - 如果
state === 2且who对应进程已下线(比如 mongos 重启过),就得手动清理:db.getSiblingDB("config").locks.updateOne({_id: "balancer"}, {$set: {state: 0}}) - 别直接删锁文档,只改
state;否则可能破坏 config server 一致性
为什么 chunk 迁移停了,但 balancer 显示 running
balancer “running” 只代表它在周期性扫描分片负载,不等于正在迁移。真正迁移需要同时满足:有 chunk 需要搬、目标分片空间够、没有写锁冲突、迁移窗口(如果配置了)处于开放时段。
实操建议:
- 查迁移积压:
sh.status()里看各集合的chunks分布是否明显倾斜;再用db.getSiblingDB("config").chunks.find({ns: "db.coll"}).sort({min: 1}).limit(5)手动抽样 - 检查迁移窗口:
db.getSiblingDB("config").settings.findOne({_id: "balancer"}),看有没有activeWindow配置,且当前时间是否落在其中 - 观察
moveChunk日志:在 mongos 或目标 mongod 的日志里搜"moveChunk",确认是否有 ERROR 或 “waiting for lock” 类提示 - 小集群容易因单个大 chunk 卡住迁移——MongoDB 默认一次只搬一个 chunk,且不允许并发 move 同一集合,这点常被忽略
监控脚本里该盯哪几个关键指标
写自动巡检脚本时,只查 sh.getBalancerState() 是无效的。必须组合多个信号才能判断真实健康度。
实操建议:
- 必查三项:
sh.getBalancerState()(开关)、sh.isBalancerRunning()(瞬时活跃)、config.locks.find({_id:"balancer"}).state(锁态) - 加一层兜底:每 5 分钟跑一次
db.getSiblingDB("config").changelog.find({time: {$gt: ISODate(Date.now()-300000)} , what: "moveChunk"}).count(),确认最近 5 分钟真有迁移发生 - 注意兼容性:
sh.isBalancerRunning()在 4.2+ 才稳定返回,旧版本得靠轮询config.locks+config.migrationHistory - 不要依赖
sh.status()的输出文本做解析——它的格式在不同版本间有细微变化,容易让监控误报
真正难的不是查状态,而是区分“没活干”和“干不了”。锁状态、迁移历史、窗口配置这三块一旦漏掉一个,监控就只剩心理安慰。










