PingKai Logo下载

使用 TiDB 读取 TiFlash 副本

本文介绍了如何使用 TiDB 读取 TiFlash 副本。

TiDB 提供了三种方式来读取 TiFlash 副本。如果你添加了 TiFlash 副本且没有进行引擎配置,默认使用的是 CBO(基于成本的优化)模式。

智能选择

对于具有 TiFlash 副本的表,TiDB 优化器会根据成本估算自动判断是否使用 TiFlash 副本。你可以使用 desc 或 explain analyze 语句来检查是否选择了 TiFlash 副本。例如:

desc select count(*) from test.t;
+--------------------------+---------+--------------+---------------+--------------------------------+
| id                       | estRows | task         | access object | operator info                  |
+--------------------------+---------+--------------+---------------+--------------------------------+
| StreamAgg_9              | 1.00    | root         |               | funcs:count(1)->Column#4       |
| └─TableReader_17         | 1.00    | root         |               | data:TableFullScan_16          |
|   └─TableFullScan_16     | 1.00    | cop[tiflash] | table:t       | keep order:false, stats:pseudo |
+--------------------------+---------+--------------+---------------+--------------------------------+
3 rows in set (0.00 sec)
explain analyze select count(*) from test.t;
+--------------------------+---------+---------+--------------+---------------+----------------------------------------------------------------------+--------------------------------+-----------+------+
| id                       | estRows | actRows | task         | access object | execution info                                                       | operator info                  | memory    | disk |
+--------------------------+---------+---------+--------------+---------------+----------------------------------------------------------------------+--------------------------------+-----------+------+
| StreamAgg_9              | 1.00    | 1       | root         |               | time:83.8372ms, loops:2                                              | funcs:count(1)->Column#4       | 372 Bytes | N/A  |
| └─TableReader_17         | 1.00    | 1       | root         |               | time:83.7776ms, loops:2, rpc num: 1, rpc time:83.5701ms, proc keys:0 | data:TableFullScan_16          | 152 Bytes | N/A  |
|   └─TableFullScan_16     | 1.00    | 1       | cop[tiflash] | table:t       | tiflash_task:{time:43ms, loops:1, threads:1}, tiflash_scan:{...}     | keep order:false, stats:pseudo | N/A       | N/A  |
+--------------------------+---------+---------+--------------+---------------+----------------------------------------------------------------------+--------------------------------+-----------+------+

cop[tiflash] 表示该任务会被发送到 TiFlash 进行处理。如果你没有选择 TiFlash 副本,可以尝试使用 analyze table 语句更新统计信息,然后再用 explain analyze 查看结果。

注意,如果一个表只有单个 TiFlash 副本且相关节点无法提供服务,在 CBO 模式下的查询会反复重试。在这种情况下,你需要指定引擎或使用手动提示从 TiKV 副本读取数据。

引擎隔离

引擎隔离是通过配置相应变量,指定所有查询都使用指定引擎的副本。可选的引擎有 "tikv"、"tidb"(表示 TiDB 的内部内存表区域,存储一些 TiDB 系统表,用户不能主动使用)和 "tiflash"。

你可以使用以下语句指定引擎:

set @@session.tidb_isolation_read_engines = "engine list separated by commas";

或者

set SESSION tidb_isolation_read_engines = "engine list separated by commas";

如果查询的表没有指定引擎的副本(例如,配置为 "tiflash" 但该表没有 TiFlash 副本),查询会返回错误。

手动提示

手动提示可以在满足引擎隔离的前提下,强制 TiDB 对特定表或语句使用指定的副本。以下是使用手动提示的示例:

select /*+ read_from_storage(tiflash[table_name]) */ ... from table_name;

如果在查询语句中为表设置了别名,必须在包含提示的语句中使用别名,提示才会生效。例如:

select /*+ read_from_storage(tiflash[alias_a,alias_b]) */ ... from table_name_1 as alias_a, table_name_2 as alias_b where alias_a.column_1 = alias_b.column_2;

上述语句中,tiflash[] 提示优化器读取 TiFlash 副本。你也可以使用 tikv[] 提示优化器读取 TiKV 副本。关于提示语法的详细信息,请参考 READ_FROM_STORAGE。

如果提示指定的表没有对应引擎的副本,提示会被忽略并报告警告。此外,提示仅在引擎隔离的前提下生效。如果提示中指定的引擎不在引擎隔离列表中,也会被忽略并报告警告。

智能选择、引擎隔离和手动提示的关系

在上述三种读取 TiFlash 副本的方式中,引擎隔离定义了引擎副本的整体范围;在此范围内,手动提示提供了更细粒度的语句级和表级引擎选择;最终,优化器会在指定的引擎列表中,根据成本估算自动选择更优的引擎副本。