配置延迟节点必须同时满足hidden: true、votes: 0和slaveDelay为1–3600秒正整数,缺一不可;仅设slaveDelay无效,否则节点可能意外升主或无法延迟同步。

只设 slaveDelay 不起作用,必须同时满足 hidden: true、votes: 0 和 slaveDelay 为正整数,否则节点可能意外升主或同步不延迟。
配置延迟节点必须满足的三项硬性条件
延迟节点不是加个参数就生效的“开关”,MongoDB 要求三个字段严格共存:
-
hidden: true:让该节点不出现在连接字符串中,应用无法路由到它 -
votes: 0:确保它不参与选举投票——注意,priority: 0不够,仍可能因票数变化被推举为主 -
slaveDelay为正整数秒(范围 1–3600),且只能在rs.add()时一次性声明
漏掉任意一项,比如只配 priority: 0 + slaveDelay: 3600,节点状态可能变成 PRIMARY,误删操作立刻同步过去,根本没缓冲窗口。
不能用 rs.reconfig() 动态修改 slaveDelay
MongoDB 明确拒绝运行中修改 slaveDelay,执行 rs.reconfig() 会直接报错:Cannot modify slaveDelay on a running member。
想改延迟时间?只能走完整移除再重建流程:
- 先
rs.remove("backup-node:27017") - 再
rs.add({ host: "backup-node:27017", priority: 0, votes: 0, hidden: true, slaveDelay: 7200 })
新节点需完成 initial sync 进入 SECONDARY 状态后,slaveDelay 才开始计时。别指望配置一写完就“慢一小时”,它得先把全量数据拉完,才开始按 oplog 时间戳往后拖。
oplog 容量必须覆盖 slaveDelay 时长
slaveDelay 不是凭空延迟,它靠回放 oplog 实现。如果 oplog 太小,节点会卡在 STARTUP2 或 RECOVERING 状态,永远进不了 SECONDARY。
检查当前 oplog 容量:
db.getReplicationInfo()
看 maxSize(字节)和 timeDiff(覆盖时长)。经验公式:oplog 至少保留 slaveDelay + 2 小时的写入量。扩容需停机操作——删除 local.oplog.rs 并重建固定集合,线上慎为。
真实延迟 ≠ slaveDelay 设定值
设置 slaveDelay: 3600,不代表你能稳稳抢救 3600 秒。真实延迟 = slaveDelay + 网络传输耗时 + oplog 回放耗时。尤其当主库批量写入、从节点磁盘 IO 跟不上,或网络抖动时,rs.printSecondaryReplicationInfo() 显示的 lag 可能远超设定值。
它只对写入类误操作(如 deleteMany({})、updateMany)有缓冲作用;DDL 操作(如 dropDatabase())同样会被复制,只是晚到。它不是备份替代方案,也无法恢复被 compact 清掉的数据。


















