Config Server磁盘满会导致mongos拒绝路由,因其用WiredTiger持久化config库,磁盘满触发全局写锁,使集群不可用;需停写、独立磁盘部署、迁移日志路径、清理过期sessions,并重启前验证恢复状态与version一致性。

Config Server磁盘满后mongos直接拒绝路由
Config Server不是只存元数据的“轻量组件”,它用WiredTiger引擎持久化config库,日志、检查点、历史快照全堆在/data/configdb里。一旦磁盘写满,WiredTiger会触发全局写锁,所有mongos立刻无法读取分片映射,表现为“集群不可用”而非报错——你连sh.status()都执行不了。
- 别指望
db.runCommand({compact: "config.system.sessions"})能救急:WiredTiger compact需要额外110%空闲空间,满盘时直接失败 - 紧急时先停掉所有
mongos和应用写入,否则WiredTiger后台线程还在刷脏页,磁盘占用可能继续涨 - Config Server必须用独立磁盘,不能和分片节点共用同一块SSD——这是线上事故高频原因
WiredTiger日志文件不自动清理的真相
WiredTiger默认把日志写进wiredTigerLog.*文件,但不会像MySQL binlog那样按大小或时间滚动删除。它只在checkpoint成功后才删旧日志,而checkpoint失败(比如磁盘满、内存不足)就会卡住,日志越积越多。
- 检查是否卡住:
ls -lt /data/configdb/wiredTigerLog.* | head -5,如果最老的日志文件时间戳超过2小时,基本就是checkpoint挂了 - 强制触发checkpoint:
db.runCommand({fsync: 1, lock: true})(仅限单节点Config Server;副本集需先切primary再操作) - 长期方案:在
mongod.conf里加wiredTiger.engineConfig.logPath: /var/log/mongodb/wt-logs,把日志挪到单独挂载点
config.system.sessions集合暴涨的隐形推手
每个mongos连接都会在config.system.sessions里留一条文档,TTL索引默认7天过期,但WiredTiger压缩率低+大量短连接会导致这个集合物理体积远超预期——实测单个Config Server上该集合占满20GB很常见。
- 确认是否异常:
db.getSiblingDB("config").system.sessions.stats().size,如果返回值 > 5GB,就得动手 - 安全清理:先停写,再运行
db.getSiblingDB("config").system.sessions.deleteMany({lastUse: {$lt: new Date(Date.now() - 1000 * 60 * 60 * 24)}})(删3天前的) - 别动TTL索引本身:
db.getSiblingDB("config").system.sessions.getIndexes()里那个lastUse_1索引删了就再也清不干净
重启Config Server前必须验证的三件事
直接systemctl restart mongod风险极高——WiredTiger恢复时若发现日志不完整,会回滚到上一个可用checkpoint,可能导致分片路由信息丢失,集群彻底分裂。
- 检查WiredTiger恢复状态:
grep -i "recovery" /var/log/mongodb/mongod.log | tail -3,必须看到Recovery complete - 确认
config.version没倒退:db.getSiblingDB("config").version.findOne(),重启前后lastMod字段不能变小 - 副本集成员要逐个重启,且每次只动一个,等
rs.status().members[n].stateStr === "PRIMARY"稳定后再动下一个
WiredTiger的“自动”背后全是条件触发,磁盘空间是硬边界,跨过就不是慢,是停摆。配监控时别只盯disk.space.available,得加一条告警:当wiredTigerLog.*文件数持续>50且最老文件年龄>1小时,立刻人工介入。










