主节点无法写入不等于宕机,可能是伪主、磁盘满、权限错或配置误;需通过optimes比对、rs.conf校验、ismaster探测、磁盘检查及writeconcern验证交叉确认。

主节点无法写入,不等于它挂了——更可能是它被降级为“伪主”、磁盘已满、权限错配或配置失当。直接查 rs.status() 看状态没用,得交叉验证。
确认是否真主节点(别信 rs.status() 的表面 stateStr)
副本集脑裂时,rs.status() 可能在两个节点上都返回 "stateStr" : "PRIMARY",但只有多数派节点能真正处理写入。关键看三件事:
- 运行
db.runCommand({ replSetGetStatus: 1 }),比对各节点的optimes.lastCommittedOpTime:差距超过几秒的节点大概率是孤立伪主 - 检查
rs.conf()中每个成员的votes和priority:有没有人意外配置了"votes": 2或多个节点priority > 0且投票数凑够“多数” - 用
db.runCommand({ isMaster: 1 })查返回里的ismaster和hosts字段:如果hosts只返回 1 个地址,说明该节点已被网络隔离
检查磁盘空间是否耗尽(常见但易被忽略)
磁盘写满后,MongoDB 实例会进入“锁定中”状态,此时所有写操作均失败,但错误提示常是误导性的 "not authorized" 或 WriteCommandError,而非明确的空间不足。
- 登录 MongoDB 控制台,在“基本信息”页查看磁盘使用率——注意采集粒度是 5 分钟,可能滞后
- 在 mongosh 中执行
db.runCommand({ dbStats: 1, scale: 1024 }),对比fsUsedSize与fsTotalSize - 若确认满盘,不要尝试删日志或 oplog(可能触发复制异常),优先扩容;临时缓解可清理
system.profile或过期的 TTL 索引数据
验证 writeConcern 是否实际生效(w: "majority" 不等于安全)
w: "majority" 写入成功,不代表数据不会回滚。若部分节点未开启 journal(storage.journal.enabled: false),MongoDB 仍认为满足 majority,但崩溃后这些节点会丢失已确认的写入。
- 检查每个节点的配置:运行
db.getSiblingDB("local").system.replset.findOne()或直接读取配置文件中的storage.journal.enabled - 确认集群级写关注默认值:
writeConcernMajorityJournalDefault必须为true,否则w: "majority"会绕过 journal 强制要求 - 应用层写操作必须显式指定
w: "majority",不能依赖驱动默认的w: 1,否则可能静默写入少数派节点
排查频繁选举导致的主节点反复降级
如果主节点频繁切换(一小时内多次 "transition to PRIMARY from SECONDARY"),写入中断就不是单点故障,而是系统性不稳定。
- 查日志里是否有密集的
ELECTION组件消息,尤其是"看不到该设立的大多数,放弃主节点"——这指向网络分区或心跳超时 - 确认所有节点间
ping延迟 net.maxIncomingConnections 足够(尤其在高并发连接场景下) - 检查
settings.electionTimeoutMillis是否被误设过小(如 - 禁用非必要节点的投票权:对备份节点或延迟从库,设
"votes": 0和"priority": 0,避免干扰多数派判定
最麻烦的情况是:节点看似健康、磁盘充足、配置无误,但写入仍卡在 NotMaster。这时要盯住驱动层——它不会自动剔除伪主,只会轮询连接。必须靠心跳探测 + isMaster 校验 + 主动剔除逻辑兜底,否则每次连上假主都要等 30 秒超时才重试。











