从节点卡在STARTUP2或RECOVERING状态表明初始同步失败,常见原因为网络不通、bindIp配置错误或oplog断层;清空数据目录并重启是唯一可靠解法,调参或reconfig无效。

从节点卡在 STARTUP2 或 RECOVERING 状态
这说明它根本没进入正常同步流程,不是“慢”,而是初始同步(initial sync)失败。常见表现是 rs.status().members[n].stateStr 长期停在这两个状态,lastHeartbeatMessage 里反复出现 Failed to fetch missing oplog entries 或 Cannot read from oplog。
- 先确认该节点能否连通 PRIMARY:在它本地执行
telnet primary-ip 27017和nc -zv primary-ip 27017,必须双向通 - 检查
bindIp配置——如果写成127.0.0.1,其他节点根本连不进来,但本机mongo能连,极具迷惑性 - 清空数据目录是唯一可靠解法:停掉
mongod,rm -rf /var/lib/mongodb/*(包括所有*.wt文件),再重启 - 不要试图用
rs.reconfig()强行刷新配置——网络不通时多数派不可达,命令会直接被拒绝
从节点 optimeDate 明显落后且日志报 could not find base oplog entry
这不是延迟,是 oplog 断层:从节点想拉的起始位置,主节点上已经没了。此时自动同步彻底失效,任何调参、重启都无效。
- 验证方式:在从节点运行
db.oplog.rs.findOne({ts: {$lt: ObjectId("...")}}),其中ObjectId来自主节点rs.status().members[0].optime.ts;返回null即证实断层 -
--oplogSize对已卡住的节点完全无效——它只影响新启动节点的行为 - 4.4+ 版本可在线扩容:在 PRIMARY 上执行
db.adminCommand({replSetResizeOplog: 1, size: 10240})(单位 MB),但仅对当前节点生效,且不能缩小 - 扩容后仍需清空故障节点数据目录并重启,才能触发新 oplog 窗口下的 initial sync
同步源(syncSource)为空或频繁切换
rs.status().members[n].syncSourceHost 为空,或 stateStr 在 RECOVERING 和 SECONDARY 间跳变,本质是心跳失败,不是配置错。
- 重点看
lastHeartbeat和lastHeartbeatRecv时间差:持续 >2 秒说明网络抖动严重;为 0 或never表示心跳包根本没发出去或没收着 - 检查防火墙出向规则——常被忽略:允许入向 27017 不代表允许本机主动连其他节点的 27017
- 跨 AZ 部署时,RTT 若长期 >500ms,可能触发
heartbeatTimeoutSecs(默认 10 秒)连续超时判定 - 用
mongostat --host rs0/primary-ip:27017测试整个副本集连通性,比单点telnet更贴近真实同步路径
同步缓慢但状态看似正常
stateStr 是 SECONDARY,health 是 1,但 optimeDate 持续落后几分钟甚至小时——80% 是 oplog 太小,而非磁盘或网络瓶颈。
- 查主节点
db.getReplicationInfo(),关注timeDiffHours:若 - 估算所需大小:按业务峰值写入量 × 保留时长(建议至少 24 小时,高写入场景用 48–72 小时)
- 别碰
numInitialSyncAttempts:它只控制 initial sync 失败重试次数,不影响日常 oplog 拉取性能 - 真正瓶颈常在 apply 阶段:观察
db.serverStatus().metrics.repl.apply.queued是否持续堆积,同时检查 WiredTiger cache 使用率
ps aux | grep mongod 必须为空,否则残留进程会锁住文件,导致后续 initial sync 失败或数据损坏。


















