使用 PLAN REPLAYER 保存和恢复集群现场信息

用户在定位排查 TiDB 集群问题时,经常需要提供系统和查询计划相关的信息。为了帮助用户更方便地获取相关信息,更高效地排查集群问题,TiDB 在 v5.3.0 中引入了 PLAN REPLAYER 命令,用于“一键”保存和恢复现场问题的相关信息,提升查询计划问题诊断的效率,同时方便将问题归档管理。

PLAN REPLAYER 主要功能如下:

  • 导出排查现场 TiDB 集群的相关信息,导出为 ZIP 格式的文件用于保存。
  • 在任意 TiDB 集群上导入另一 TiDB 集群现场信息的 ZIP 文件。

使用 PLAN REPLAYER 导出集群信息

你可以使用 PLAN REPLAYER 来保存 TiDB 集群的现场信息。导出接口如下:

  1. PLAN REPLAYER DUMP EXPLAIN [ANALYZE] [WITH STATS AS OF TIMESTAMP expression] sql-statement;

TiDB 根据 sql-statement 整理出以下集群现场信息:

  • TiDB 版本信息
  • TiDB 配置信息
  • TiDB Session 系统变量
  • TiDB 执行计划绑定信息(SQL Binding)
  • sql-statement 中所包含的表结构
  • sql-statement 中所包含表的统计信息
  • EXPLAIN [ANALYZE] sql-statement 的结果
  • 优化器进行查询优化的一些内部步骤的记录

启用历史统计信息时,可以在 PLAN REPLAYER 语句中指定时间来获取对应时间的统计信息。该语法支持直接指定日期时间或指定时间戳。此时,TiDB 会查找指定时间之前的历史统计信息,并导出其中最新的一份。

如果没有找到指定时间之前的历史统计信息,TiDB 会直接导出最新统计信息(和未指定时间时的行为一致),并且在导出的 ZIP 文件中的 errors.txt 中输出错误信息。

保存和恢复集群现场信息 - 图1

注意

PLAN REPLAYER 不会导出表中数据

PLAN REPLAYER 导出示例

  1. use test;
  2. create table t(a int, b int);
  3. insert into t values(1,1), (2, 2), (3, 3);
  4. analyze table t;
  5. plan replayer dump explain select * from t;
  6. plan replayer dump with stats as of timestamp '2023-07-17 12:00:00' explain select * from t;
  7. plan replayer dump with stats as of timestamp '442012134592479233' explain select * from t;

PLAN REPLAYER DUMP 会将以上信息打包整理成 ZIP 文件,并返回文件标识作为执行结果。

保存和恢复集群现场信息 - 图2

注意

ZIP 文件最多会在 TiDB 集群中保存一个小时,超时后 TiDB 会将其删除。

  1. MySQL [test]> plan replayer dump explain select * from t;
  1. +------------------------------------------------------------------+
  2. | Dump_link |
  3. +------------------------------------------------------------------+
  4. | replayer_JOGvpu4t7dssySqJfTtS4A==_1635750890568691080.zip |
  5. +------------------------------------------------------------------+
  6. 1 row in set (0.015 sec)

你同样可以通过 tidb_last_plan_replayer_token 这个会话变量来获取上一次 PLAN REPLAYER dump 执行的结果。

  1. SELECT @@tidb_last_plan_replayer_token;
  1. | @@tidb_last_plan_replayer_token |
  2. +-----------------------------------------------------------+
  3. | replayer_Fdamsm3C7ZiPJ-LQqgVjkA==_1663304195885090000.zip |
  4. +-----------------------------------------------------------+
  5. 1 row in set (0.00 sec)

对于多条 SQL 的情况,你可以通过文件的方式来获取 plan replayer dump 的结果,多条 SQL 语句在文件中以 ; 进行分隔。

  1. plan replayer dump explain 'sqls.txt';
  1. SELECT @@tidb_last_plan_replayer_token;
  1. +-----------------------------------------------------------+
  2. | @@tidb_last_plan_replayer_token |
  3. +-----------------------------------------------------------+
  4. | replayer_LEDKg8sb-K0u24QesiH8ig==_1663226556509182000.zip |
  5. +-----------------------------------------------------------+
  6. 1 row in set (0.00 sec)

因为 MySQL Client 无法下载文件,所以需要通过 TiDB HTTP 接口和文件标识下载文件:

  1. http://${tidb-server-ip}:${tidb-server-status-port}/plan_replayer/dump/${file_token}

其中,${tidb-server-ip}:${tidb-server-status-port} 是集群中任意 TiDB server 的地址。示例如下:

  1. curl http://127.0.0.1:10080/plan_replayer/dump/replayer_JOGvpu4t7dssySqJfTtS4A==_1635750890568691080.zip > plan_replayer.zip

使用 PLAN REPLAYER 导入集群信息

保存和恢复集群现场信息 - 图3

警告

PLAN REPLAYER 在一个 TiDB 集群上导入另一集群的现场信息,会修改导入集群的 TiDB Session 系统变量、执行计划绑定信息、表结构和统计信息。

PLAN REPLAYER 导出的 ZIP 文件后,用户便可以通过 PLAN REPLAYER 导入接口在任意 TiDB 集群上恢复另一集群地现场信息。语法如下:

  1. PLAN REPLAYER LOAD 'file_name';

以上语句中,file_name 为要导入的 ZIP 文件名。

示例如下:

  1. PLAN REPLAYER LOAD 'plan_replayer.zip';

保存和恢复集群现场信息 - 图4

注意

你需要禁止 auto analyze,否则导入的统计信息会被 analyze 覆盖。

你可以通过将 tidb_enable_auto_analyze 系统变量设置为 OFF 来禁用 auto analyze

  1. set @@global.tidb_enable_auto_analyze = OFF;

导入完毕后,该 TiDB 集群就载入了所需要的表结构、统计信息等其他影响构造 Plan 所需要的信息。你可以通过以下方式查看执行计划以及验证统计信息:

  1. mysql> desc t;
  2. +-------+---------+------+------+---------+-------+
  3. | Field | Type | Null | Key | Default | Extra |
  4. +-------+---------+------+------+---------+-------+
  5. | a | int(11) | YES | | NULL | |
  6. | b | int(11) | YES | | NULL | |
  7. +-------+---------+------+------+---------+-------+
  8. 2 rows in set (0.01 sec)
  9. mysql> explain select * from t where a = 1 or b =1;
  10. +-------------------------+---------+-----------+---------------+--------------------------------------+
  11. | id | estRows | task | access object | operator info |
  12. +-------------------------+---------+-----------+---------------+--------------------------------------+
  13. | TableReader_7 | 0.01 | root | | data:Selection_6 |
  14. | └─Selection_6 | 0.01 | cop[tikv] | | or(eq(test.t.a, 1), eq(test.t.b, 1)) |
  15. | └─TableFullScan_5 | 6.00 | cop[tikv] | table:t | keep order:false, stats:pseudo |
  16. +-------------------------+---------+-----------+---------------+--------------------------------------+
  17. 3 rows in set (0.00 sec)
  18. mysql> show stats_meta;
  19. +---------+------------+----------------+---------------------+--------------+-----------+
  20. | Db_name | Table_name | Partition_name | Update_time | Modify_count | Row_count |
  21. +---------+------------+----------------+---------------------+--------------+-----------+
  22. | test | t | | 2022-08-26 15:52:07 | 3 | 6 |
  23. +---------+------------+----------------+---------------------+--------------+-----------+
  24. 1 row in set (0.04 sec)

加载并还原所需现场后,即可在该现场诊断和改进执行计划。

使用 PLAN REPLAYER CAPTURE 抓取目标计划

在用户定位 TiDB 执行计划的部分场景中,目标 SQL 语句与目标计划可能仅在查询中偶尔出现,无法使用 PLAN REPLAYER 直接抓取。此时你可以使用 PLAN REPLAYER CAPTURE 来帮助定向抓取目标 SQL 语句与目标计划的优化器信息。

PLAN REPLAYER CAPTURE 主要功能如下:

  • 在 TiDB 集群内部提前注册目标 SQL 语句与执行计划的 Digest,并开始匹配目标查询。
  • 当目标查询匹配成功时,直接抓取其优化器相关信息,导出为 ZIP 格式的文件用于保存。
  • 针对匹配到的每组 SQL 和执行计划,信息只抓取一次。
  • 通过系统表显示正在进行的匹配任务,以及生成的文件。
  • 定时清理历史文件。

开启 PLAN REPLAYER CAPTURE

PLAN REPLAYER CAPTURE 功能通过系统变量 tidb_enable_plan_replayer_capture 控制。要开启 PLAN REPLAYER CAPTURE,将变量值设为 ON

使用 PLAN REPLAYER CAPTURE 功能

你可以通过以下方式向 TiDB 集群注册目标 SQL 语句和计划的 Digest:

  1. PLAN REPLAYER CAPTURE 'sql_digest' 'plan_digest';

当你的目标 SQL 语句对应多种执行计划,且你想抓取所有执行计划时,你可以通过以下 SQL 语句一键注册:

  1. PLAN REPLAYER CAPTURE 'sql_digest' '*';

查看 PLAN REPLAYER CAPTURE 抓取任务

你可以通过以下方式查看集群中目前正在工作的 PLAN REPLAYER CAPTURE 的抓取任务:

  1. mysql> PLAN PLAYER CAPTURE 'example_sql' 'example_plan';
  2. Query OK, 1 row affected (0.01 sec)
  3. mysql> SELECT * FROM mysql.plan_replayer_task;
  4. +-------------+--------------+---------------------+
  5. | sql_digest | plan_digest | update_time |
  6. +-------------+--------------+---------------------+
  7. | example_sql | example_plan | 2023-01-28 11:58:22 |
  8. +-------------+--------------+---------------------+
  9. 1 row in set (0.01 sec)

查看 PLAN REPLAYER CAPTURE 抓取结果

PLAN REPLAYER CAPTURE 成功抓取到结果后,可以通过以下 SQL 语句查看用于下载的文件标识:

  1. mysql> SELECT * FROM mysql.plan_replayer_status;
  2. +------------------------------------------------------------------+------------------------------------------------------------------+------------+-----------------------------------------------------------+---------------------+-------------+-----------------+
  3. | sql_digest | plan_digest | origin_sql | token | update_time | fail_reason | instance |
  4. +------------------------------------------------------------------+------------------------------------------------------------------+------------+-----------------------------------------------------------+---------------------+-------------+-----------------+
  5. | 086e3fbd2732f7671c17f299d4320689deeeb87ba031240e1e598a0ca14f808c | 042de2a6652a6d20afc629ff90b8507b7587a1c7e1eb122c3e0b808b1d80cc02 | | replayer_Utah4nkz2sIEzkks7tIRog==_1668746293523179156.zip | 2022-11-18 12:38:13 | NULL | 172.16.4.4:4022 |
  6. | b5b38322b7be560edb04f33f15b15a885e7c6209a22b56b0804622e397199b54 | 1770efeb3f91936e095f0344b629562bf1b204f6e46439b7d8f842319297c3b5 | | replayer_Z2mUXNHDjU_WBmGdWQqifw==_1668746293560115314.zip | 2022-11-18 12:38:13 | NULL | 172.16.4.4:4022 |
  7. | 96d00c0b3f08795fe94e2d712fa1078ab7809faf4e81d198f276c0dede818cf9 | 8892f74ac2a42c2c6b6152352bc491b5c07c73ac3ed66487b2c990909bae83e8 | | replayer_RZcRHJB7BaCccxFfOIAhWg==_1668746293578282450.zip | 2022-11-18 12:38:13 | NULL | 172.16.4.4:4022 |
  8. +------------------------------------------------------------------+------------------------------------------------------------------+------------+-----------------------------------------------------------+---------------------+-------------+-----------------+
  9. 3 rows in set (0.00 sec)

下载 PLAN REPLAYER CAPTURE 的文件方法与 PLAN REPLAYER 相同,请参考 PLAN REPLAYER 导出示例

保存和恢复集群现场信息 - 图5

注意

PLAN REPLAYER CAPTURE 的结果文件最多会在 TiDB 集群中保存一周,超时后 TiDB 会将其删除。

移除 PLAN REPLAYER CAPTURE 抓取任务

不再需要某个 PLAN REPLAYER CAPTURE 抓取任务后,你可以通过 PLAN REPLAYER CAPTURE REMOVE 语句将其移除。示例如下:

  1. mysql> PLAN REPLAYER CAPTURE '077a87a576e42360c95530ccdac7a1771c4efba17619e26be50a4cfd967204a0' '4838af52c1e07fc8694761ad193d16a689b2128bc5ced9d13beb31ae27b370ce';
  2. Query OK, 0 rows affected (0.01 sec)
  3. mysql> SELECT * FROM mysql.plan_replayer_task;
  4. +------------------------------------------------------------------+------------------------------------------------------------------+---------------------+
  5. | sql_digest | plan_digest | update_time |
  6. +------------------------------------------------------------------+------------------------------------------------------------------+---------------------+
  7. | 077a87a576e42360c95530ccdac7a1771c4efba17619e26be50a4cfd967204a0 | 4838af52c1e07fc8694761ad193d16a689b2128bc5ced9d13beb31ae27b370ce | 2024-05-21 11:26:10 |
  8. +------------------------------------------------------------------+------------------------------------------------------------------+---------------------+
  9. 1 row in set (0.01 sec)
  10. mysql> PLAN REPLAYER CAPTURE REMOVE '077a87a576e42360c95530ccdac7a1771c4efba17619e26be50a4cfd967204a0' '4838af52c1e07fc8694761ad193d16a689b2128bc5ced9d13beb31ae27b370ce';
  11. Query OK, 0 rows affected (0.01 sec)
  12. mysql> SELECT * FROM mysql.plan_replayer_task;
  13. Empty set (0.01 sec)

使用 PLAN REPLAYER CONTINUOUS CAPTURE

开启 PLAN REPLAYER CONTINUOUS CAPTURE 功能后,TiDB 将以 SQL DIGEST 和 PLAN DIGEST 为维度异步地将业务 SQL 语句以 PLAN REPLAYER 的方式进行记录,对于相同 DIGEST 的 SQL 语句与执行计划,PLAN REPLAYER CONTINUOUS CAPTURE 不会重复记录。

开启 PLAN REPLAYER CONTINUOUS CAPTURE

PLAN REPLAYER CONTINUOUS CAPTURE 功能通过系统变量 tidb_enable_plan_replayer_continuous_capture 控制。要开启 PLAN REPLAYER CONTINUOUS CAPTURE,将变量值设为 ON

查看 PLAN REPLAYER CONTINUOUS CAPTURE 抓取结果

查看 PLAN REPLAYER CONTINUOUS CAPTURE 抓取结果的方法同查看 PLAN REPLAYER CAPTURE 抓取结果