sh.isBalancerRunning() 返回true或false,仅表示Balancer进程是否启用并运行中,不反映是否有chunk正在迁移;true不代表有迁移进行,false也不代表迁移已停止。

sh.isBalancerRunning() 返回什么,代表什么状态?
sh.isBalancerRunning() 是一个 shell 函数,它只返回 true 或 false,**不代表迁移是否在进行中,只表示 Balancer 进程本身是否处于“启用并运行中”的状态**。很多人误以为它能告诉你“当前有没有 chunk 正在迁移”,其实不能——Balancer 可能开着,但没活干;也可能刚被手动停掉,而迁移还在收尾。
常见错误现象:sh.isBalancerRunning() 返回 true,但 sh.status() 显示没有 pending migration;或者返回 false,却发现某个 shard 上的 moveChunk 命令仍在执行(这是合法的,迁移一旦开始就不会被 Balancer 状态中断)。
- 它不反映迁移队列长度、chunk 移动速度、卡住的迁移任务
- 它不受单次
moveChunk手动操作影响——那些是绕过 Balancer 的直接命令 - 如果 Balancer 被禁用(
sh.stopBalancer()),它返回false;启用后需等待下一轮调度周期(默认 5 秒)才可能真正运行
真正能查迁移进度的命令有哪些?
要看实时迁移动作,得盯住后台正在执行的 moveChunk 操作,以及分片元数据变更。核心手段有三个:
- 查正在运行的迁移任务:
db.adminCommand({ "currentOp": { "secs_running": { "$gt": 0 }, "secs_running": { "$lt": 3600 }, "active": true, "ns": "config.*", "secs_running": { "$gt": 10 } } }),重点过滤moveChunk和commitChunkMigration操作 - 查迁移历史和卡点:
db.changelog.find({ "what": "moveChunk" }).sort({ "_id": -1 }).limit(5),注意from/to字段和time,失败记录里常带errmsg - 看实时 chunk 分布变化:
sh.status({ verbose: true })中的chunks行,对比前后两次输出的各 shard chunk 数,差值 > 0 表示迁移已生效;若某 shard 的size长时间不更新,说明迁移卡在 commit 阶段
为什么 sh.status() 里的 “balancer is running” 不等于迁移正在进行?
sh.status() 输出顶部那句 balancer is running,本质就是调用了 sh.isBalancerRunning(),它只是读取 config.settings 集合中 _id: "balancer" 文档的 stopped 字段(false 表示启用)。这个字段控制 Balancer 是否会在下次调度时拉取待迁移 chunk,但完全不感知当前是否有活跃迁移。
典型误导场景:
- Balancer 启用中,但所有 shard 的 chunk 分布已均衡(
diff - 你刚执行
sh.moveChunk("db.coll", { _id: 1 }, "shard01"),这个迁移不会出现在 Balancer 日志里,也不会触发sh.isBalancerRunning()的任何变化 - 迁移因网络超时失败,Balancer 会重试(默认 5 次),但
sh.isBalancerRunning()仍为true,你得去changelog查失败原因
生产环境建议监控哪几个关键指标?
靠单一函数判断迁移进度风险很高。实际运维应组合采集以下信号:
-
db.changelog.countDocuments({ "what": "moveChunk", "time": { "$gt": ISODate(Date.now() - 5 * 60 * 1000) } }):过去 5 分钟发起的迁移数,突增可能意味着自动均衡启动或手动干预 -
db.currentOp().inprog.filter(op => op.secs_running > 30 && op.what === "moveChunk"):运行超 30 秒的迁移,大概率异常(如锁冲突、磁盘慢、目标 shard 内存不足) -
db.getSiblingDB("config").shards.find().toArray()中各 shard 的host连通性 +db.getSiblingDB("config").databases.findOne({ _id: "db" }).primary是否指向预期 shard - 操作系统层监控:源/目标 shard 的磁盘 IO wait、网络丢包率、mongod 进程 RSS 内存——迁移期间
moveChunk会大量读写数据文件,这些指标比 Balancer 状态更能提前预警
最容易被忽略的是:迁移完成不等于数据立即可读。新 chunk 在目标 shard 上写入后,config server 更新路由表有短暂延迟(通常 StaleConfig 错误——这不属于 Balancer 监控范畴,得靠驱动日志或 mongos 的 getShardVersion 调用来确认。


















