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

rs.add() 能加节点,但加不进去、卡在 STARTUP2 或进不了 SECONDARY 是常态——不是命令写错了,而是初始同步被阻塞了。
新节点卡在 STARTUP2 怎么办
这是最常遇到的问题:执行 rs.add() 后,新节点日志里反复出现 STARTUP2,状态一直不更新。它根本没开始复制,卡在「找同步源」这一步。
- 用
mongo --host new-node:27017连一下新节点,再执行rs.status()确认它是否能连通主节点和其他SECONDARY - 检查你打算让它同步的源节点(比如某个
SECONDARY)是否设置了slaveDelay或priority: 0—— 这类节点默认不会被选为 initial sync 源 - 如果网络跨可用区或延迟高,别等自动选源,立刻在新节点上手动指定:
db.adminCommand({ replSetSyncFrom: "source-node:27017" }) -
dbpath目录必须为空;之前失败过就删掉整个目录再重启mongod
为什么全量同步期间主节点负载飙升
初始同步不是靠回放 oplog,而是源节点遍历所有数据 + 压缩传输,相当于一次隐式 mongodump。所以 CPU、磁盘 IO 和网络带宽都会突增。
- 避开业务高峰执行
rs.add(),否则可能触发主节点慢查询甚至连接超时 - 如果有多个
SECONDARY,优先让新节点从optimeDate最近、负载最低的那个同步,而不是默认找PRIMARY - 源节点若没开
syncdelay,它得边读数据边写 journal,IO 更重——没法关,但可以换一台 journal 写入压力小的节点做源 - 监控进度别只看新节点状态,去源节点跑
db.printSlaveReplicationInfo(),看syncedTo时间戳更准
rs.add() 后进不了 SECONDARY,报 “Oplog is empty”
这说明新节点完成全量同步后,想回放 oplog 追平,却发现 oplog 里最早的操作时间比它快照截止时间还晚——oplog 不够长,或者副本集刚初始化还没写入过数据。
- 检查源节点的 oplog 大小:
db.getSiblingDB("local").oplog.rs.stats().maxSize,确认它能覆盖从快照生成到当前的时间差 - 如果副本集是新建的、几乎没写入,先在
PRIMARY上执行几条写操作(比如db.test.insert({x:1})),再让新节点同步 - 扩容前可提前调大 oplog:用
replSetResizeOplog命令(MongoDB 4.4+),或重建 oplog(需停机)
添加节点时 priority 和 votes 怎么设
新节点默认有投票权和选举权重,但生产环境通常不希望它参与主节点选举,尤其刚加入还没同步完时。
- 加节点时显式设
priority: 0和votes: 0,避免干扰选举:rs.add({ host: "new-node:27017", priority: 0, votes: 0 }) - 如果副本集已有 7 个投票成员(上限),再加就必须设
votes: 0,否则rs.add()会直接报错 - 后续想让它参与选举,得用
replSetReconfig修改配置,且只能一次改一个 voting 成员
STARTUP2,而你得知道该去哪查日志、该换哪个源、该清哪个目录。











