通过系统变量 tidb_external_ts 读取历史数据

为了支持读取历史版本数据,TiDB 从 v6.4.0 起引入了一个新的系统变量 tidb_external_ts。本文档介绍如何通过该系统变量读取历史数据,其中包括具体的操作流程。

使用系统变量tidb_external_ts 读取历史数据 - 图1

警告

目前 Stale Read 特性无法和 TiFlash 一起使用。如果你在查询时将 tidb_enable_external_ts_read 设置为 ON,并且 TiDB 可能从 TiFlash 副本读取数据,你可能会遇到 ERROR 1105 (HY000): stale requests require tikv backend 报错信息。

要解决该问题,你需要为使用 Stale Read 特性的查询禁用 TiFlash 副本。要禁用 TiFlash 副本,你可以使用以下任一方法:

  • 通过设置 tidb_isolation_read_engines 变量来禁用 TiFlash 副本 SET SESSION tidb_isolation_read_engines='tidb,tikv'
  • 使用 READ_FROM_STORAGE hint 强制 TiDB 从 TiKV 读取数据。

场景介绍

通过配置让 TiDB 能够读取某一固定时间点的历史数据对于 TiCDC 等数据同步工具非常有用。在数据同步工具完成了某一时间点前的数据同步之后,可以通过设置下游 TiDB 的 tidb_external_ts 系统变量,使得下游 TiDB 的请求能够读取到该时间点前的数据。这将避免在同步过程中,下游 TiDB 读取到尚未完全同步而不一致的数据。

功能介绍

系统变量 tidb_external_ts 用于指定启用 tidb_enable_external_ts_read 时,读取历史数据使用的时间戳。

系统变量 tidb_enable_external_ts_read 控制着是否在当前会话或全局启用读取历史数据的功能。默认值为 OFF,这意味着该功能关闭,并且设置 tidb_external_ts 没有作用。当该变量被全局地设置为 ON 时,所有的请求都将读取到 tidb_external_ts 指定时间之前的历史数据。如果 tidb_enable_external_ts_read 仅在某一会话被设置为 ON,则只有该会话中的请求会读取到历史数据。

tidb_enable_external_ts_read 被设置为 ON 时,TiDB 会进入只读模式,任何写请求都会失败并且返回错误 ERROR 1836 (HY000): Running in read-only mode

示例

以下是一个使用该功能的示例:

  1. 创建一个表后,在表中插入几行数据:

    1. CREATE TABLE t (c INT);
    1. Query OK, 0 rows affected (0.01 sec)
    1. INSERT INTO t VALUES (1), (2), (3);
    1. Query OK, 3 rows affected (0.00 sec)
  2. 查看表中的数据:

    1. SELECT * FROM t;
    1. +------+
    2. | c |
    3. +------+
    4. | 1 |
    5. | 2 |
    6. | 3 |
    7. +------+
    8. 3 rows in set (0.00 sec)
  3. tidb_external_ts 设置为 @@tidb_current_ts

    1. START TRANSACTION;
    2. SET GLOBAL tidb_external_ts = @@tidb_current_ts;
    3. COMMIT;
  4. 插入新的一行并确认新的一行已经被插入:

    1. INSERT INTO t VALUES (4);
    1. Query OK, 1 row affected (0.001 sec)
    1. SELECT * FROM t;
    1. +------+
    2. | id |
    3. +------+
    4. | 1 |
    5. | 2 |
    6. | 3 |
    7. | 4 |
    8. +------+
    9. 4 rows in set (0.00 sec)
  5. tidb_enable_external_ts_read 设置为 ON 后,再次查询表中的数据:

    1. SET tidb_enable_external_ts_read = ON;
    2. SELECT * FROM t;
    1. +------+
    2. | c |
    3. +------+
    4. | 1 |
    5. | 2 |
    6. | 3 |
    7. +------+
    8. 3 rows in set (0.00 sec)

    因为 tidb_external_ts 被设置为插入这一行之前的时间,在启动 tidb_enable_external_ts_read 后,将读取不到新插入的行。