先执行rs.isMaster()确认节点角色和连接状态,重点关注ismaster、secondary字段及primary指向;再查oplog.ts时间戳比对同步延迟;最后手动写入并读取验证实时同步。

检查当前节点角色和连接状态
先确认你连的是哪个节点,以及它当前在副本集里的身份。执行 rs.isMaster() 最直接——它会返回完整角色信息,包括 ismaster、secondary、hosts、arbiters 和 passives 字段。重点关注 ismaster 或 secondary 是否为 true,以及 primary 字段是否指向某个地址。
常见误判点:
- 连上却显示
"ismaster": false, "secondary": false→ 该节点可能没成功加入副本集,或配置未生效 -
hosts数量少于预期 → 某些节点网络不通或bind_ip配置错误(比如写成了127.0.0.1而非实际监听 IP) -
lastHeartbeatMessage出现Connection refused→ 对端 mongod 未运行,或防火墙拦截了端口
查看 oplog 同步延迟和最新时间戳
同步是否及时,不能只看“有没有数据”,要看 oplog 的时间差。切到 local 库执行:use local,再运行 db.oplog.rs.find().sort({$natural: -1}).limit(1)。结果里 ts 字段是 BSON timestamp,格式为 { "t": <time_t>, "i": <increment> }</increment></time_t>,其中 t 是 Unix 秒级时间戳。
对比不同节点的 t 值就能算出延迟秒数。例如:
- Primary 上
t: 1734781200(对应 2026-10-21 10:20:00) - Secondary 上
t: 1734781140(对应 10:19:00)→ 延迟 60 秒
注意:如果 Secondary 的 ts 完全没更新(比如停在几小时前),说明同步已中断,不是慢,而是卡住了。
验证写入是否被从节点实时拉取
手动触发一次写操作,再立刻查从节点,是最朴素也最有效的验证方式。步骤如下:
- 在 Primary 节点执行:
use test→db.foo.insertOne({x: 1, ts: new Date()}) - 立刻切换到 Secondary 节点(用新
mongosh连接),执行:use test→db.foo.findOne({x: 1}) - 如果查不到,等 2–3 秒再试;若超过 5 秒仍查不到,且
oplog.ts也没推进 → 同步链路异常
关键提醒:Secondary 默认不接受读请求,必须显式开启。否则 db.foo.findOne() 会报错 not master and slaveOk=false。解决方法是执行 rs.secondaryOk()(仅本次会话生效),或连接时加参数 --readPreference=secondary。
识别延迟节点和隐藏节点的特殊表现
如果你配置了 secondaryDelaySecs 或 hidden: true,它们的表现和普通 Secondary 不同,容易误判为故障:
- 延迟节点的
db.oplog.rs.find().sort(...).limit(1)返回的ts.t一定比 Primary 小固定秒数(如设了 3600,就恒定差 1 小时) - 隐藏节点不会出现在
rs.isMaster().hosts列表里,但会出现在rs.conf().members中,且字段含"hidden": true和"priority": 0 - 延迟节点 + 隐藏节点组合下,
rs.status()里它的optime时间戳看起来“落后”,这是正常行为,不是 bug
真正要警惕的是:延迟节点的 optimeDate 停滞不动,或者 stateStr 变成 RECOVERING 或 ARBITER —— 那说明它已脱离同步轨道,得人工介入。


















