MongoDB主节点正常但无法写入,单从节点故障排查
MongoDB集群主节点可读不可写问题分析与解决
问题场景
我部署了一个包含1个主节点(Primary)和2个从节点(Secondary)的3节点MongoDB集群,其中一个Secondary已故障下线,Primary与另一个Secondary仍处于运行状态,但Primary仅支持读操作,无法执行写入。
连接字符串:
mongodb://custom-pvc-mongodb-0.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017/admin
rs.status()输出(中文翻译版)
{ "副本集名称": "custom-pvc-mongodb", "当前时间": ISODate("2022-12-07T12:04:12.543Z"), "当前节点状态": 1, "任期编号": NumberLong(3), "同步源主机": "", "同步源ID": -1, "心跳间隔(毫秒)": NumberLong(2000), "多数派投票数": 2, "写操作多数派确认数": 2, "投票成员总数": 3, "可写投票成员总数": 3, "操作时间戳": { "最后提交操作时间": { "时间戳": Timestamp(1670301216, 1), "任期": NumberLong(3) }, "最后提交操作墙钟时间": ISODate("2022-12-06T04:33:36.252Z"), "读关注多数派操作时间": { "时间戳": Timestamp(1670301216, 1), "任期": NumberLong(3) }, "已应用操作时间": { "时间戳": Timestamp(1670414650, 1), "任期": NumberLong(3) }, "持久化操作时间": { "时间戳": Timestamp(1670414650, 1), "任期": NumberLong(3) }, "最后应用操作墙钟时间": ISODate("2022-12-07T12:04:10.025Z"), "最后持久化操作墙钟时间": ISODate("2022-12-07T12:04:10.025Z") }, "最后稳定恢复时间戳": Timestamp(1670301216, 1), "选举候选指标": { "上次选举原因": "选举超时", "上次选举时间": ISODate("2022-11-25T07:35:27.387Z"), "选举任期": NumberLong(3), "选举时最后提交操作时间": { "时间戳": Timestamp(0, 0), "任期": NumberLong(-1) }, "选举时最后看到的操作时间": { "时间戳": Timestamp(1669361650, 1), "任期": NumberLong(1) }, "所需投票数": 2, "选举时优先级": 1, "选举超时(毫秒)": NumberLong(10000), "追赶操作数": NumberLong(0), "新任期开始时间": ISODate("2022-11-25T07:35:27.410Z"), "写多数派可用时间": ISODate("2022-11-25T07:35:28.101Z") }, "副本集成员": [ { "成员ID": 0, "成员地址": "custom-pvc-mongodb-0.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017", "健康状态": 1, "节点状态": 1, "节点状态描述": "PRIMARY", "在线时长(秒)": 1052969, "操作时间": { "时间戳": Timestamp(1670414650, 1), "任期": NumberLong(3) }, "操作时间对应日期": ISODate("2022-12-07T12:04:10Z"), "最后应用操作墙钟时间": ISODate("2022-12-07T12:04:10.025Z"), "最后持久化操作墙钟时间": ISODate("2022-12-07T12:04:10.025Z"), "同步源主机": "", "同步源ID": -1, "信息消息": "", "选举时间": Timestamp(1669361727, 1), "选举日期": ISODate("2022-11-25T07:35:27Z"), "配置版本": 1, "配置任期": 3, "是否当前节点": true, "最后心跳消息": "" }, { "成员ID": 1, "成员地址": "custom-pvc-mongodb-1.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017", "健康状态": 0, "节点状态": 8, "节点状态描述": "(无法访问/不健康)", "在线时长(秒)": 0, "操作时间": { "时间戳": Timestamp(0, 0), "任期": NumberLong(-1) }, "持久化操作时间": { "时间戳": Timestamp(0, 0), "任期": NumberLong(-1) }, "操作时间对应日期": ISODate("1970-01-01T00:00:00Z"), "持久化操作时间对应日期": ISODate("1970-01-01T00:00:00Z"), "最后应用操作墙钟时间": ISODate("2022-12-06T04:33:36.252Z"), "最后持久化操作墙钟时间": ISODate("2022-12-06T04:33:36.252Z"), "最后发送心跳时间": ISODate("2022-12-07T12:04:11.496Z"), "最后接收心跳时间": ISODate("2022-12-06T04:33:41.424Z"), "延迟(毫秒)": NumberLong(0), "最后心跳消息": "连接到custom-pvc-mongodb-1.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017失败 :: 原因 :: 无法找到custom-pvc-mongodb-1.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017的地址: SocketException: 主机未找到(权威)", "同步源主机": "", "同步源ID": -1, "信息消息": "", "配置版本": 1, "配置任期": 3 }, { "成员ID": 2, "成员地址": "custom-pvc-mongodb-2.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017", "健康状态": 1, "节点状态": 2, "节点状态描述": "SECONDARY", "在线时长(秒)": 1052905, "操作时间": { "时间戳": Timestamp(1670301216, 1), "任期": NumberLong(3) }, "持久化操作时间": { "时间戳": Timestamp(1670301216, 1), "任期": NumberLong(3) }, "操作时间对应日期": ISODate("2022-12-06T04:33:36Z"), "持久化操作时间对应日期": ISODate("2022-12-06T04:33:36Z"), "最后应用操作墙钟时间": ISODate("2022-12-06T04:33:36.252Z"), "最后持久化操作墙钟时间": ISODate("2022-12-06T04:33:36.252Z"), "最后发送心跳时间": ISODate("2022-12-07T12:04:12.099Z"), "最后接收心跳时间": ISODate("2022-12-06T17:34:23.114Z"), "延迟(毫秒)": NumberLong(0), "最后心跳消息": "", "同步源主机": "", "同步源ID": -1, "信息消息": "", "配置版本": 1, "配置任期": 3 } ], "操作结果": 1, "$集群时间": { "集群时间": Timestamp(1670414650, 1), "签名": { "哈希": BinData(0,"kmVIlznkue1ffD6Se8Ztbzc22j0="), "密钥ID": NumberLong("7169853219500195844") } }, "操作时间": Timestamp(1670414650, 1) }
问题原因
从状态输出可以明确两个核心问题:
- 写多数派条件不满足:副本集配置要求
writeMajorityCount=2,但当前仅Primary节点处于正常同步状态,另一个Secondary(成员ID:2)虽然健康,但心跳已中断近19小时,且数据同步停留在2022-12-06T04:33:36,无法确认是否能接收并提交新的写操作。 - 投票成员数配置与实际在线节点不匹配:副本集投票成员总数为3,但1个节点故障不可达,1个节点失联,仅Primary在线,无法凑够多数派确认。
解决步骤
步骤1:尝试恢复正常Secondary节点的同步
- 检查成员ID:2的Secondary节点与Primary之间的网络连通性,确认DNS解析、端口是否正常。
- 重启该Secondary节点,观察
rs.status()中的心跳接收时间和opTime是否更新,若恢复同步,Primary将自动恢复写入能力。
步骤2:调整副本集配置,移除故障/失联节点
若Secondary无法恢复,需修改副本集配置,移除无效节点:
- 连接到Primary节点:
mongo "mongodb://custom-pvc-mongodb-0.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017/admin" - 执行移除命令:
// 移除故障节点 rs.remove("custom-pvc-mongodb-1.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017") // 移除失联的Secondary节点 rs.remove("custom-pvc-mongodb-2.custom-pvc-mongodb-svc.mongo-3033.svc.cluster.local:27017") - 执行
rs.status()确认配置更新后,votingMembersCount变为1,此时Primary可满足写多数派条件(单节点默认允许写入),恢复写入能力。
步骤3:重新构建高可用集群(可选)
待业务恢复后,建议添加新的Secondary节点到副本集,恢复3节点高可用架构:
rs.add("new-secondary-node-address:27017")
内容的提问来源于stack exchange,提问作者ajsg
相关产品推荐
相关产品推荐

