必须清空dbPath并重启以触发全量同步:停mongod→删dbPath全部内容(含journal和local)→确保网络连通→重启,节点将自动执行initial sync并经历STARTUP2→RECOVERING→SECONDARY状态转换。

SECONDARY卡在STARTUP2或RECOVERING,怎么触发全量同步?
这不是配置问题,而是节点无法完成初始同步(initial sync)的明确信号。常见于磁盘空间不足、oplog不连续、本地数据损坏或网络中断后残留状态未清理。不能靠重启解决,必须人工重置同步起点。
- 停掉该节点的
mongod进程(用db.shutdownServer()或系统命令确保完全退出) - 清空其
dbPath目录下所有内容(journal、_mdb_catalog.wt等全部删掉;mongod.lock可删) - 确认该节点能连通 PRIMARY,且防火墙放行 27017 及内部通信端口(如 27018)
- 重启
mongod,它会自动进入 initial sync 流程:拉取快照 + 回放 oplog
注意:rs.status().members[n].stateStr 会依次显示 STARTUP2 → RECOVERING → SECONDARY;若卡在 STARTUP2 超过 30 分钟,检查日志是否出现 Failed to fetch missing oplog entries 或 Cannot read from oplog —— 这说明同步源不可靠,需换节点或调大 oplog。
执行前必须删掉 local 数据库吗?
是的,但仅限于从备份恢复或手动重置场景。MongoDB 在 initial sync 过程中会自动截断并重建 local.oplog.rs,但如果 local 目录里残留了旧的 replset.minvalid 或损坏的 startup_log,会导致同步失败或卡住。
- 如果节点是从文件系统快照恢复的,启动前必须删除整个
local目录(或连接后运行use local; db.dropDatabase()) - 如果是清空
dbPath后重启,local会被重建,无需额外操作 - 切勿保留旧
local中的oplog.rs:它可能包含已失效的游标位置,引发could not find base oplog entry
为什么 rs.printSlaveReplicationInfo() 显示延迟 0 却查不到新写入?
这通常不是同步问题,而是你连到了一个尚未完成 initial sync 的节点,或者该节点刚完成同步但还没建立稳定的 tailable cursor。此时 optimeDate 可能和 PRIMARY 一致,但实际数据没应用完。
- 检查
rs.status().members[n].stateStr是否为SECONDARY(而非RECOVERING) - 查
rs.status().members[n].lastAppliedWallTime和lastSyncSourceWallTime,差值超过 5 秒说明还在追赶 - 运行
db.getProfilingStatus(),确认没有慢查询阻塞 oplog 应用线程 - 避免在同步刚完成时立刻读取,等 30 秒再验证;WiredTiger 引擎下索引构建可能滞后于数据拷贝
调大 oplog 能避免重新同步吗?
只能缓解复制延迟,不能绕过已发生的 oplog gap。当日志出现 could not find base oplog entry,说明所需 oplog 已被覆盖,自动同步彻底失效 —— 此时 resize oplog 无效,必须全量重同步。
- 在 PRIMARY 上执行:
db.adminCommand({replSetResizeOplog: 1, size: 10240})(单位 MB,仅 WiredTiger 有效) - resize 不会立即生效,需等待 oplog 自动轮转;生产环境建议至少保留 2 小时 oplog window
- oplog 太小常因写入突增或磁盘 I/O 延迟导致,单纯调大治标不治本,要结合监控
diskQueue和extra_info.page_faults
真正容易被忽略的是:重同步过程会占用大量磁盘 IO 和网络带宽,且期间目标节点完全不可读;务必避开业务高峰,并确认同步源节点本身负载正常 —— 否则新节点刚起步就拖垮整个副本集。











