正常执行计划的SQL突然变慢

社区问题 1057818(v8.5.4 慢 SQL IndexLookUp)根因结论

一、根因(一句话)

TiKV coprocessor 在 “tracker 之外” 的调度段(gRPC handler → unified-read-pool 排队 + parse_request + region cache 查询)累计 ~518ms,叠加 gRPC 往返 ~429ms;TiKV 自身计算/锁/snapshot/IO 都不是瓶颈。混部 3 台环境是放大器。

二、铁证三段 gap 拆解

IndexRangeScan_13 cop_task:

公式 耗时 性质
gap A(网络/gRPC 往返) rpc_time − tikv_wall_time 429ms TiDB ↔ TiKV 链路
gap B(TiKV tracker 之外) tikv_wall_time − (proc+wait+snapshot) 518ms 调度/排队/parse_request
tracker 内部 tot_proc + tot_wait + get_snapshot 108µs TiKV 真实处理

三、关键排除

  • :x: raftstore scheduler:coprocessor 不走 raftstore
  • :x: snapshot/read index:get_snapshot_time=9.48µs / wait_time=28.6µs 都是 µs 级
  • :x: 磁盘 IO:block_cache_hit_count=8 全命中,proc_keys=1
  • :x: 计算慢:tot_proc=79.6µs

四、源码层定位(@tidb源码解读 铁证)

tikv_wall_time 计时区间:kv.rs:1466 begin_instant:1560-1607 handle_measures_for_batch_commands;tracker 在 endpoint.rs:622 才创建。gap B 必然落在这两段 tracker 之外

  • front:future_copr → Tracker::new(parse_request + region cache)
  • back:tracker.on_finish_all_items → batch_commands measure(batch 组装 + gRPC 调度)

五、KB 先例

六、给社区的验证建议(按优先级)

  1. TiKV-Details → Thread CPU → unified-read-pool CPU:是否打满
  2. TiKV-Details → Time Used By Level:区分 busy vs wait(核心面板,不看 CPU usage)
  3. TiKV-Details → gRPC message duration (Coprocessor) P99:gap A 验证
  4. TiKV-Details → Unified Read Pool Wait Duration:gap B front 验证
  5. TiDB-Details → Region Cache hit/refresh:是否频繁触发 PD RPC

七、临时缓解 + 长期建议

  • 临时:调大 readpool.unified.max-thread-count;cgroup 隔离 TiKV CPU;检查网络
  • 长期:解混部(TiKV 对 CPU/IO 延迟敏感);启用 Resource Control(注意 #18939);升级 v8.5.x 最新 patch

八、给社区的可直接回复段落

tikv_wall_time=518mstotal_process_time + total_wait_time ≈ 108µs,时间不在 TiKV 计算和锁。scan_detail 显示 block_cache_hit_count=8 全命中无 IO,get_snapshot_time=9.48µstotal_wait_time=28.6µs 都是 µs 级,排除 snapshot/read index/磁盘。源码上 tikv_wall_time 覆盖 begin_instant(gRPC handler 接收)到响应组装完成,而 tracker 只捕获到 unified-read-pool 内部处理段,所以 gap 必然在 tracker 之外——即 gRPC handler → unified-read-pool 的调度排队 + parse_request/region cache 查询,以及 batch_commands 响应组装。混部环境下最大嫌疑是 unified-read-pool CPU 争抢 + gRPC batch 调度。建议看 TiKV-Details 的 Thread CPU(unified-read-pool)Time Used By Level 面板,必要时调大 readpool.unified.max-thread-count 或解混部。


@ticket-Walterwj 根因分析结构完整(gap 三段拆解 + 五候选排除 + 验证/缓解/长期),@wiki_ticket KB 反查扎实,@tidb源码解读 源码边界铁证。三方交叉印证一致。