Now let me proceed with KB Step A and Step B in parallel while fetching cluster metadata.**KB Step A 完成:** 集群类型为 `dedicated`,使用 `cluster_id` 访问所有组件指标(TiDB/TiKV/PD/TiFlash/node),不需要 `parent_id`。 **KB Step B 完成:** pitfall ic-001/ic-002 — 注意 ANALYZE 不是默认根因,missing index 优先于 stale stats。 现在将时间窗口转换为 Unix epoch 并收集证据:日志摘要显示 error/warn/info 均为 0,这与用户询问的 goroutine panic 告警不符。让我直接查询 Loki 日志,专门搜索 panic 相关记录:找到了关键证据!让我获取完整日志详情:已获取全部关键证据。现在进行完整分析。让我再查询一下完整的 stack trace:所有关键证据已收集完整。现在可以做出最终分析: --- ## 分析报告:集群 10518506906906971664 — Recoverable Goroutine Panic 告警 --- ### Root Cause **告警真实,但为预期的可恢复 panic(非进程崩溃):** TiDB 并行 Hash 聚合算子的 worker goroutine 因查询超过 `max_execution_time` 限制,触发 `executor:3024` 中断信号,该信号以 panic 形式传播给并行聚合 worker,由 `recoveryHashAgg` 和 `WithRecovery` 机制捕获并安全恢复,进程未崩溃,仅查询返回报错。 --- ### Key Evidence 1. **直接 panic 日志(misc.go:95,21:50:00 UTC):** ``` [2026/04/19 21:50:00.323] [ERROR] [misc.go:95] ["panic in the recoverable goroutine"] [r="[executor:3024]Query execution was interrupted, maximum statement execution time exceeded"] [stack trace="github.com/pingcap/tidb/pkg/util.WithRecovery.func1 ..."] instance: db-2006015162468798464-fc67a2f2-tidb-5 ``` 2. **并行 Hash Agg 恢复日志(agg_util.go:93,多实例,共 ~13 条):** ``` [WARN] [agg_util.go:93] ["parallel hash aggregation panicked"] [error="[executor:3024]Query execution was interrupted, maximum statement execution time exceeded"] [stack="github.com/pingcap/tidb/pkg/executor/aggregate.recoveryHashAgg ..."] instances: db-2006015162468798464-fc67a2f2-tidb-5 (4条), tidb-0 (5条), tidb-2 (1条) 时间段: 21:50:00 ~ 21:52:16 UTC ``` 3. **告警期间集群完全稳定:** - 所有组件实例数不变(tidb 24, tikv 54, pd 3, ticdc 4) - 无任何 TiDB/TiKV/PD ERROR/FATAL log - TiDB P99 延迟正常(最高 46ms),TiDB CPU 最高 30%,基础设施全部 CLEAR 4. **关联查询特征:** statementlog 中 PANIC 标记的 SQL 均为多表 JOIN + 聚合的复杂分析查询(如 `dh_active_bet_total`、`dh_promote_myteam_*` 等),执行时间跨越 30 分钟窗口(statement summary `begin~end` 间隔达 1800s),明显超出 `max_execution_time` 阈值。 --- ### Causality **长执行时间复杂聚合 SQL → 触发 max_execution_time 超时 → 以 panic 形式中断并行 Hash Agg worker goroutine → `recoveryHashAgg`/`WithRecovery` 捕获 panic → 查询返回 `[executor:3024]` 错误 → 告警系统检测到 "panic in the recoverable goroutine" 日志 → 触发告警** --- ### Panic 类型和严重性判断 | 维度 | 判断 | |------|------| | **panic 来源** | `executor:3024` — 查询语句超时中断,属于业务层触发 | | **是否进程崩溃** | **否**。由 `WithRecovery.func1` + `recoveryHashAgg` 双层捕获,goroutine 安全退出 | | **是否 TiDB Bug** | 否。这是 TiDB 并行聚合算子的设计行为:超时信号通过 panic 向 worker 传播,属于正常终止机制 | | **对集群影响** | 仅影响该 SQL 请求本身,调用方收到错误返回;集群整体无中断、无重启 | | **告警真实性** | **告警真实**,日志确实存在;但属于可控的预期行为,不代表系统故障 | **严重性:Low(业务层警告,非系统故障)** --- ### Ruled Out / Not Relevant 无 TiDB/TiKV/PD 进程崩溃、重启或 OOM;基础设施(EBS/磁盘 IO)全部正常;TiKV gRPC P99 局部热点(db-tikv-21/46/49)与 panic 无关,属于独立的聚合查询负载压力。 --- ### Severity **Low** — 进程级别无影响,仅受影响 SQL 返回超时错误。若此类查询超时频繁触发并影响业务,可升级为 Medium。 --- ### Recommendations 1. **定位超时查询(P0):** 关注 `statementlog` 中标记的 SQL digest(如 `83a9a630`、`c974bf5f`、`b643ccdc` 等),这些均为执行跨越 30min 时间窗口的大型分析查询。评估是否合理,建议在 Clinic Slow Query 中查看完整 SQL 和执行计划。 2. **审查 `max_execution_time` 设置:** 确认当前 session/global `max_execution_time` 值是否符合这类分析查询的预期执行时间,必要时对特定业务查询单独配置或走离线任务处理。 3. **优化并行聚合查询:** 涉及 `dh_active_bet_total`、`dh_promote_myteam_direct` 等大表的聚合 SQL,可分析是否存在缺失索引或执行计划不优,减少执行时间从源头避免触发超时。 4. **告警调优(可选):** 若希望区分"可恢复 panic"和"进程崩溃"告警,可在告警规则中增加组件重启次数(component restarts)联动条件,避免此类误报干扰。