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

警告
目前 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. 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 后,将读取不到新插入的行。
