mongostat和mongotop无法监控副本集实时状态,因二者仅连接单个实例且不感知复制集角色、心跳、选举或同步延迟;真正可用的是mongo shell中的rs.status()和rs.printSlaveReplicationInfo()。

mongostat 和 mongotop 不能监控 MongoDB 副本集节点的实时状态——它们只连接单个 mongod 实例,且完全不感知复制集角色(PRIMARY/SECONDARY/ARBITER)、心跳、选举或同步延迟。
mongostat 只显示本地实例基础指标,不反映副本集健康
它通过 serverStatus 获取每秒的简单计数器(如 ops、mem、net),但:
- 不查询
rs.status(),因此看不到stateStr(如 "SECONDARY")、optimeDate、lastHeartbeat或syncSourceHost - 当连接到 SECONDARY 节点时,默认拒绝读请求(除非显式加
--eval "db.getMongo().setReadPreference('primaryPreferred')"),但 mongostat 本身不支持该参数,容易卡在“not master”错误 - 输出中的
net_in/net_out是网络层字节数,和 oplog 同步流量无直接关系;无法判断是否落后 PRIMARY 多少秒
示例:运行 mongostat --host rs1.example.com:27017 -u admin -p pwd --authenticationDatabase admin,你只会看到该节点自身的操作速率,不会出现“同步延迟:8.2s”这类关键字段。
mongotop 显示集合级读写热点,但对复制滞后毫无意义
mongotop 统计的是当前实例上各集合每秒的读/写毫秒耗时(基于 top 命令采集),但它:
- 完全忽略复制相关指标:不显示 oplog 队列长度(
replication.replSetGetStatus.members[n].optime.dts)、fetcher 队列(metrics.repl.buffer.count)或应用延迟(repl.apply.batches.num) - 在 SECONDARY 上执行时,统计的是本地查询(如应用直连 SECONDARY 做报表读),而非同步线程的 oplog 应用行为
- 若节点处于 RECOVERING 或 ROLLBACK 状态,
mongotop仍照常输出“正常”数据,掩盖严重问题
比如某 SECONDARY 的 mongotop --host node2:27017 显示 local.oplog.rs: 120ms read,这其实是它自己读 oplog 的开销,不是同步慢的证据——真正要看的是 rs.status().members[n].optimeDate 与 PRIMARY 的差值。
真正能查副本集实时状态的只有 mongo shell + rs.status() 和 rs.printSlaveReplicationInfo()
必须用交互式 shell 或脚本调用复制集命令,原因很直接:
-
rs.status()返回完整 JSON,含每个成员的state、uptime、lastHeartbeat、optimeDate、syncSourceHost、health等字段,是诊断故障的第一手依据 -
rs.printSlaveReplicationInfo()专为同步延迟设计,直接算出各 SECONDARY 落后 PRIMARY 的秒数(基于optimeDate差值),比人工比对快得多 - 可配合
watch实现准实时刷新:watch -n 2 'mongo --quiet --eval "rs.status().members.forEach(m => print(m.name + \" \" + m.stateStr + \" \" + (new Date() - m.optimeDate)/1000 + \"s\"))"'
注意:所有这些命令都要求连接到 PRIMARY(或启用 readPreference=primaryPreferred),否则可能报 not master and slaveOk=false。这不是权限问题,而是复制集元数据只在 PRIMARY 上权威可读。
别被工具名误导——mongostat 和 mongotop 的 “mongo” 前缀只代表它们属于 MongoDB 工具链,不表示它们理解复制集语义。真正做副本集巡检时,你得亲手敲 rs.status(),并看懂其中每个字段的时间戳含义。同步延迟不是靠猜出来的,是靠两个 Date 对象相减算出来的。











