分片集群 balancer 时间窗口需通过 config.settings 更新 activewindow 字段配置,且 balancer 必须显式启用并验证状态。操作须经 mongos、使用 clusteradmin 权限,start/stop 为本地时区闭区间 "hh:mm" 格式,禁用窗口须 $unset 而非删除文档。

分片集群的 balancer 默认全天运行,但实际运维中常需避开业务高峰——设置时间窗口是最直接、最安全的控制方式。只要在 config 数据库里更新 settings 集合,就能生效,无需重启服务。
连接 mongos 并切换到 config 数据库
必须通过 mongos 实例操作,不能直连 config server;认证用户需有 clusterAdmin 或 root 角色权限。
- 使用
mongosh连接任意mongos:mongosh "mongodb://user:pass@mongos-host:27017" - 执行
use config切换数据库 - 确认当前状态:
sh.getBalancerState()和sh.getBalancerWindow()先看是否已启用及是否有旧窗口
用 db.settings.update 设置 activeWindow
这个操作本质是 upsert,_id: "balancer" 是固定键名,activeWindow 字段格式严格:start/stop 必须是 "HH:MM" 格式,且 stop 时间不能早于 start(跨日不支持)。
- 示例:凌晨 2 点到 5 点运行:
db.settings.update({ _id: "balancer" }, { $set: { activeWindow: { start: "02:00", stop: "05:00" } } }, { upsert: true }) - 注意:
start和stop都是闭区间,即 02:00:00 开始,05:00:00 结束(含该秒) - 如果之前没设过
balancer文档,{ upsert: true }会自动创建;已有则只更新activeWindow字段
启动 balancer 后窗口才生效
设置窗口本身不会自动开启 balancer,必须显式调用 sh.setBalancerState(true) 或 sh.startBalancer()。否则即使配置了窗口,balancer 仍处于关闭状态。
-
sh.startBalancer()是辅助方法,返回快但不反馈实际状态变化;推荐用sh.setBalancerState(true)更可靠 - 设置了窗口后,
sh.startBalancer()仍会返回{"ok": 1},但若 balancer 当前未运行,它不会真正启动——这是最容易被忽略的坑 - 验证是否生效:运行
sh.getBalancerWindow()应返回刚设的 start/stop;再查sh.getBalancerState()确认是true
删除或禁用窗口的正确方式
想恢复全天运行,不能删文档,也不能设空对象,必须用 $unset 清除 activeWindow 字段。否则 balancer 会持续按旧窗口判断。
- 执行:
db.settings.update({ _id: "balancer" }, { $unset: { activeWindow: "" } }) - 之后可立即调用
sh.setBalancerState(true),balancer 就不再受时间限制 - 如果误删了整个文档,需重新 upsert 并确保
_id是"balancer",否则 balancer 可能行为异常
窗口配置看似简单,但容易卡在“设了却没生效”上——核心在于三步缺一不可:写对 config.settings、确认 balancer 处于开启态、用 sh.getBalancerWindow() 实时验证。跨时区部署时,所有时间都按 mongos 所在服务器本地时区解析,这点常被忽略。











