暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

tidb-Dashboard中TOP SQL里频繁出现EXPLAIN FORMAT语句来源

原创 like052 2天前
16

问题简介

Dashboard中TOP SQL里一直有一条explain format的select语句,任何时间段都存在,call/sec=0.7,寻找其来源。

环境说明

tidb v8.5.4

三节点混合部署

问题详细说明

Dashboard中TOP SQL里一直有一条explain format的select语句,最开始认为可能是代码有bug,但是后面观察其对应的ticdc从库top SQL里也有该SQL,但是ticdc从库时只读的,也无业务连接。

当下怀疑方向及其分析措施如下:

1)上游有不停执行explain语句,导致下游也不停重放--排除

:ticdc只是会同步kv log,不会同步explain语句,且explain format本身的SQL并不会实际执行;

:从库启用general log,也未发现该explain sql的执行记录。

:由于从库有该SQL,基本排除了应用程序的bug,应该就是系统类的问题。

2)top SQL里存在,但对应的“SQL语句分析”没有该SQL“。

:根据top SQL里提供的SQL模板ID到INFORMATION_SCHEMA.CLUSTER_STATEMENTS_SUMMARY表中查询,无该SQL信息。

3)有什么系统表被同步到从库?从库采用的是主库的数据??

解决方案

结论:

这条 SQL 是 TiDB SQL Plan Management(SPM,SQL 计划基线 / Binding)模块的内部受限 SQL,

由 bindinfo.getHintsForSQL() 在加载/创建执行计划基线时发出。

它不是用户/应用发出的 SQL,因此:

  • 出现在 Top SQL:Top SQL 基于 CPU 采样,会采样正在运行的 goroutine 当前 SQL(含内部 SQL)。

  • 不在 Statement Summary(cluster_statement_summary):内部 SQL 默认被排除(tidb_stmt_summary_internal_query=off)。

  • 不在 general log:该函数在 :590-594 显式置 InRestrictedSQL=true,刻意隐藏该内部 EXPLAIN 不被审计/通用日志记录。

  • 下游也出现:上游 mysql.bind_info 的基线被 TiCDC 同步到下游(或下游对同一负载独立做了基线捕获),下游 TiDB 加载这些 binding 时重放同样的内部 EXPLAIN FORMAT='hint'。

下游ticdc出现的原因

EXPLAIN FORMAT='hint' 的触发条件是:TiDB 加载/创建一条 SQL 计划基线(binding)。触发路径:newBinding()(global_handle.go:554)→ prepareHints() → getHintsForSQL() → 内部 EXPLAIN。

下游出现同一 SQL 的两条可能链路(任一成立即可):

  1. mysql.bind_info 被 TiCDC 同步:TiCDC 默认 filter 多为 *.*,会把 mysql 系统表(含 bind_info、stats_*、user 等)的变更一并同步到下游。下游 TiDB 加载这些被同步来的 binding → 重放同样的内部 EXPLAIN。

  2. 下游独立做了 SPM 自动捕获:下游承接了与上游相同的业务负载(读副本/双活),若下游也开启了tidb_capture_plan_baselines 或基线演进,会对相同 SELECT 生成 binding → 同样触发内部 EXPLAIN。

验证

1)查看当前是否有绑定

show global bindings;

select * from mysql.bind_info;

2)SPM自动捕获/演进是否开启

> show variables like '%plan_baselines';

+-----------------------------+-------+

| Variable_name | Value |

+-----------------------------+-------+

| tidb_capture_plan_baselines | OFF |

| tidb_evolve_plan_baselines | OFF |

3)临时打开内部SQL记录,查看statement_summary是否有记录

SET GLOBAL tidb_stmt_summary_internal_query = ON;

根据指定的SQL模版ID可以正常从该表中获取到SQL。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论