config server故障导致集群只读,必须恢复副本集写能力:需人工强制重配置使存活节点成为primary,清空宕机节点数据目录后以相同参数加回,并核对mongos的--configdb参数是否包含当前存活节点。

Config Server 故障导致集群只读,必须恢复 config server 副本集的写能力——不能靠重启单节点或 db.repairDatabase() 解决,核心是让至少一个节点重新成为 PRIMARY 并完成元数据同步。
确认 config server 是否已降为只读状态
只读表现不是“连不上”,而是写操作直接报错:not master、not primary and secondaryOk() is false,或执行 sh.status() 时提示 config database is read-only。关键判断依据是:
- 连接任意 config server 节点后运行
rs.status(),若所有成员stateStr都不是PRIMARY(比如全是SECONDARY、RECOVERING或STARTUP2),说明选举失败,集群元数据无法写入 - 执行
db.runCommand({ismaster: 1})返回"ismaster" : false且"secondary" : true,但没配rs.slaveOk()——这本身不致命,但叠加无 PRIMARY 就构成只读 - 检查
mongos日志,频繁出现Failed to refresh config database: NotMaster或类似Failed to load config data错误
强制重配置副本集以恢复 PRIMARY
当只剩一个健康 config server 节点(其他两个宕机或网络隔离),它无法自行触发选举(缺多数票),必须人工干预。此时不能等,也不能删库重搭——要保留现有 config 库数据:
- 先连上那个存活节点:
mongo --host 10.0.1.100:27019 - 执行
cfg = rs.conf()拿到当前配置,然后把已确认宕机节点的votes和priority全设为0(例如cfg.members[1].votes = 0; cfg.members[1].priority = 0) - 再执行
rs.reconfig(cfg, {force: true})——{force: true}是必须的,否则会因“非 majority 状态”拒绝变更 - 等待几秒后运行
rs.status().myState,返回1表示该节点已成为PRIMARY;再查rs.status().members,确认其stateStr为PRIMARY - 此时
config库立刻可写,mongos会在 30 秒内自动刷新缓存,分片迁移、chunk 拆分等功能立即恢复
修复后加回宕机节点的注意事项
恢复写能力只是第一步,长期稳定需要补全副本集。但加回节点不是简单 rs.add(),容易引发元数据冲突:
- 被加回的节点必须清空原
dbpath目录(不能复用旧数据),否则 WiredTiger 会报Invalid argument: unable to read config.system.sessions - 启动参数必须与现存节点完全一致:相同
--replSet名、相同端口、相同--bind_ip,否则它会自建一个孤立副本集 - 加节点命令中 IP:port 格式必须和
rs.conf()里其他成员一致(比如都用域名或都用 IP,端口不能漏) - 加完后观察
rs.status().members[n].stateStr是否变为SECONDARY,且syncingTo指向当前PRIMARY;若卡在STARTUP2超过 5 分钟,大概率是 oplog 不足,需检查PRIMARY的local.oplog.rs大小是否够覆盖同步窗口
最易被忽略的一点:config server 副本集的 PRIMARY 切换后,mongos 不会立刻感知新主节点的地址变更——它只依赖启动时 --configdb 参数里的列表做轮询。只要列表里还有那个刚升主的节点,就能连上;但如果列表里全是宕机地址,哪怕 config server 已恢复,mongos 仍会持续报错。务必核对 mongos 启动参数中的 --configdb 值是否包含当前存活节点。











