新节点卡在STARTUP2是因初始同步阻塞于选择同步源;需确保网络连通、源节点未设slaveDelay或priority:0,必要时显式指定syncFrom,且dbpath必须为空。

能加,但默认会卡在 STARTUP2 —— 不是命令错了,是初始同步卡在找同步源上,必须人工干预才能进 SECONDARY。
rs.add() 后新节点一直停在 STARTUP2 怎么办
这是生产环境最常遇到的现象:执行 rs.add() 后,新节点状态长期卡在 STARTUP2,日志里反复刷 “waiting for initial sync” 或 “no sync source available”。它根本没开始拉数据,只是在等一个可选的同步源(sync source)。
- 用
mongo --host new-node:27017登进去,执行rs.status()确认当前状态和lastHeartbeatMessage字段,常能看到 “Could not find member to sync from” - 检查所有现有成员是否都可达:新节点必须能连通主节点 + 至少一个 SECONDARY(
ping和telnet host port都要通) - 确认候选源节点没被排除:
slaveDelay > 0或priority: 0的节点不会被自动选为初始同步源 - 跨可用区或网络分区时,直接显式指定源:在新节点 shell 中立刻运行
db.adminCommand({ replSetSyncFrom: "source-host:27017" }),比等自动发现快得多
初始同步前 dbpath 必须为空,否则同步失败
哪怕只残留一个 _mdb_catalog.wt 文件,mongod 启动后也会拒绝进入复制流程,状态卡在 STARTUP 或 STARTUP2,且不报明显错误。这不是权限或配置问题,是 MongoDB 的硬性校验。
- 不要手动清空子目录;直接删整个
dbpath目录(比如/data/mongodb/db0),再重启mongod - 如果之前执行过
rs.add()又回滚了,务必检查该路径是否存在残留进程锁文件(如mongod.lock) - 启动命令中必须带
--replSet参数,且值与现有副本集名称严格一致(大小写敏感)
同步期间主节点或源节点 CPU / IO 飙升怎么缓解
初始同步不是走 oplog 回放,而是源节点遍历所有集合、压缩传输全量数据(类似内置 mongodump),对磁盘和 CPU 是真实压力,尤其当集合 >100GB 或索引 >50 个时。
- 避开业务高峰操作;若必须上线,优先让新节点从负载最低、
optimeDate最新的 SECONDARY 同步,而不是默认找 PRIMARY - 源节点的
storage.journal.enabled必须为true(默认开启),否则 journal 写入会和同步读竞争 IO - 监控进度别看新节点:在源节点上执行
db.printSlaveReplicationInfo(),对比syncedTo时间戳和当前时间差,比rs.status()里的optime更准 - 如果副本集已有 7 个 voting 成员,新节点必须设
votes: 0,否则rs.add()直接报错 “cannot add more than 7 voting members”
添加后验证 SECONDARY 是否真正可用
状态变成 SECONDARY 不代表就完事了——它可能刚同步完快照,但还没来得及回放 oplog,此时查不到最新写入的数据,甚至 db.isMaster().ismaster 返回 false 也不代表异常。
- 检查
rs.status().members[n].stateStr === "SECONDARY"且lastAppliedWallTime和主节点差距 - 在新节点上执行
rs.slaveOk(),然后跑一条真实查询(比如db.foo.findOne({ ts: { $gt: ISODate("...") } })),确认能返回最近写入的数据 - 特别注意 “Oplog is empty” 错误:说明源节点 oplog 太小,存不下新节点加入前的操作,需调大
storage.oplogSizeMB并重启源节点(无法在线改)
真正麻烦的从来不是加节点这个动作,而是初始同步阶段那些不报错却卡死的静默等待——网络连通性、同步源资格、dbpath 清理、oplog 容量,四个点漏掉任意一个,都会让节点永远停在 STARTUP2。


















