Secondary延迟飙升是因各节点独立建索引而非复制,且索引构建抢占I/O与CPU资源,导致oplog应用受阻;需通过currentOp、iostat及复制配置排查具体瓶颈。

分片集群中给某个集合建索引,主节点可能几分钟就完成了,但你发现某个shard的secondary节点延迟持续飙升到数分钟甚至十几分钟,【此时不是索引没同步完,而是该secondary正在本地独立构建同一索引】,它根本没从oplog里“复制”索引——这个动作必须每个节点自己干。
索引创建不走复制链路,是各节点独立执行
副本集内索引创建命令不会被记录进oplog并广播;每个节点收到createIndex指令后,各自启动构建流程。分片集群中,mongos把命令下发到所有shard的primary,primary建完后并不通知secondary,secondary仍需自行触发构建——它要么靠定时轮询发现元数据变更,要么等下一次全量配置刷新才感知。
这一步没有统一调度机制,secondary启动时机不可控,可能比primary晚几十秒甚至几分钟才开始建,导致延迟数字不断跳涨。
Secondary构建索引时,复制线程被彻底挤占
方法一:用db.currentOp()确认阻塞源头
登录延迟高的secondary节点,执行db.currentOp({secs_running: {$gt: 5}})。如果返回大量状态为"indexBuild"的操作,同时穿插着若干"applier"或"replExec"类型任务,说明索引构建线程和oplog应用线程正在争抢CPU与磁盘I/O。
方法二:检查iostat输出判断带宽瓶颈
运行iostat -x 1,重点关注await值。若await持续高于60ms,而%util未达100%,说明I/O请求排队严重——索引构建频繁刷盘,直接卡住了oplog拉取所需的磁盘带宽。
【WiredTiger引擎在后台构建索引时默认启用fsync,每写入一批key就强制落盘,这是secondary延迟暴涨的物理层根源】
分片集群中Secondary压力是双重叠加的
第一步:确认该secondary是否同时承担业务读流量
执行rs.conf()查看members[n].tags,若包含"nodeType":"readReplica"或类似标签,且应用连接字符串中设置了readPreference=secondaryPreferred,则该节点正同时处理用户查询和本shard全部oplog重放。
第二步:检查syncSourceHost是否指向另一个secondary
运行rs.printSlaveReplicationInfo(),观察syncSourceHost字段。如果它指向的是另一个secondary(而非primary),再查那个节点的延迟——若它也高,就形成级联拖累:A节点从B节点同步,B节点又从C节点同步,C节点一卡,整条链全堵死。
第三步:验证复制带宽是否被聚合查询抢占
执行db.currentOp({$or: [{secs_running: {$gt: 10}}, {operation: "getMore"}, {operation: "aggregate"}]})。只要返回结果里有3个以上活跃的聚合或游标拉取操作,就能断定业务读正在吃掉复制所需的网络和CPU资源。


















