Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tidb: add document for external timestamp read #11583

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions TOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
- [Stale Read 使用场景介绍](/stale-read.md)
- [使用 `AS OF TIMESTAMP` 语法读取历史数据](/as-of-timestamp.md)
- [使用系统变量 `tidb_read_staleness` 读取历史数据](/tidb-read-staleness.md)
- [使用系统变量 `tidb_external_ts` 读取历史数据](/tidb-external-ts.md)
- [使用系统变量 `tidb_snapshot` 读取历史数据](/read-historical-data.md)
- 最佳实践
- [TiDB 最佳实践](/best-practices/tidb-best-practices.md)
Expand Down
4 changes: 3 additions & 1 deletion stale-read.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ summary: 介绍 Stale Read 功能和使用场景。

## 使用方法

TiDB 提供语句级别与会话级别的 Stale Read 使用方式,具体使用方法如下:
TiDB 提供语句级别、会话级别以及全局级别的 Stale Read 使用方式,具体使用方法如下:

- 语句级别:
- 指定一个精确的时间点(**推荐**):如需 TiDB 读取一个时间点上保证全局事务记录一致性的数据并且不破坏隔离级别,你可以指定这个时间点对应的时间戳。要使用该方式,请参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。
- 指定时间范围:如需 TiDB 读取在一个时间范围内尽可能新的数据并且不破坏隔离级别,你可以指定一个时间范围。在指定时间范围内,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证在所访问的可用副本上可执行读取操作而且不会被阻塞。要使用该方式,请参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。
- 会话级别:
- 指定时间范围:在会话级别中,如需 TiDB 在后续的查询中读取一个时间范围内尽可能新的数据并且不破坏隔离级别,你可以通过设置一个 session 变量 `tidb_read_staleness` 来指定一个时间范围。要使用该方式,请参阅[通过系统变量 `tidb_read_staleness` 读取历史数据](/tidb-read-staleness.md)。

除此以外,你也可以通过设置系统变量 [`tidb_external_ts`](/system-variables.md#tidb_external_ts-从-v640-版本开始引入) 来在某一会话或全局范围读取某一时间点前的历史数据。要使用该方式,请参阅[通过系统变量 `tidb_external_ts` 读取历史数据](/tidb-external-ts.md)。
18 changes: 17 additions & 1 deletion system-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数
- 作用域:GLOBAL
- 是否持久化到集群:是
- 默认值:`ON`
- 这个变量用于控制是否让 TiDB 使用并发 DDL 语句。在开启并发 DDL 语句后,DDL 语句的执行流程有所改变,DDL 语句不容易被其他 DDL 语句阻塞,并且能够同时添加多个索引。
- 这个变量用于控制是否让 TiDB 使用并发 DDL 语句。在开启并发 DDL 语句后,DDL 语句的执行流程有所改变,DDL 语句不容易被其他 DDL 语句阻塞,并且能够同时添加多个索引。

### `tidb_enable_ddl`

Expand All @@ -1135,6 +1135,22 @@ MPP 是 TiFlash 引擎提供的分布式计算框架,允许节点之间的数
- `RESTRICTED_VARIABLES_ADMIN`:能够在 `SHOW [GLOBAL] VARIABLES` 和 `SET` 命令中查看和设置包含敏感内容的变量。
- `RESTRICTED_USER_ADMIN`:能够阻止其他用户更改或删除用户帐户。

### `tidb_enable_external_ts_read` <span class="version-mark">从 v6.4.0 版本开始引入</span>

- 作用域:SESSION | GLOBAL
- 是否持久化到集群:是
YangKeao marked this conversation as resolved.
Show resolved Hide resolved
- 类型:布尔型
- 默认值:`OFF`
- 当此变量设置为 `ON` 时,TiDB 会读取 [`tidb_external_ts`](#tidb_external_ts-从-v640-版本开始引入) 指定时间戳前的历史数据。

### `tidb_external_ts` <span class="version-mark">从 v6.4.0 版本开始引入</span>

- 作用域:GLOBAL
- 是否持久化到集群:是
YangKeao marked this conversation as resolved.
Show resolved Hide resolved
- 类型:整数
- 默认值:`0`
- 当 [`tidb_enable_external_ts_read`](#tidb_enable_external_ts_read-从-v640-版本开始引入) 设置为 `ON` 时,TiDB 会依据该变量指定的时间戳读取历史数据。

### `tidb_restricted_read_only` <span class="version-mark">从 v5.2.0 版本开始引入</span>

- 作用域:GLOBAL
Expand Down
122 changes: 122 additions & 0 deletions tidb-external-ts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
title: 通过系统变量 `tidb_external_ts` 读取历史数据
summary: 了解如何通过系统变量 `tidb_external_ts` 读取历史数据。
---

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

为了支持读取历史版本数据,TiDB 从 v6.4.0 起引入了一个新的系统变量 [`tidb_external_ts`](/system-variables.md#tidb_external_ts-从-v640-版本开始引入)。本文档介绍如何通过该系统变量读取历史数据,其中包括具体的操作流程。

> **警告:**
>
> 目前 Stale Read 特性无法和 TiFlash 一起使用。如果你在查询时将 [`tidb_enable_external_ts_read`](/system-variables.md#tidb_enable_external_ts_read-从-v640-版本开始引入) 设置为 `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`](/optimizer-hints.md#read_from_storagetiflasht1_name--tl_name--tikvt2_name--tl_name-) hint 强制 TiDB 从 TiKV 读取数据。

## 场景介绍

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

## 功能介绍

系统变量 [`tidb_external_ts`](/system-variables.md#tidb_external_ts-从-v640-版本开始引入) 用于指定启用 `tidb_enable_external_ts_read` 时,读取历史数据使用的时间戳。

系统变量 [`tidb_enable_external_ts_read`](/system-variables.md#tidb_enable_external_ts_read-从-v640-版本开始引入) 控制着是否在当前会话或全局启用读取历史数据的功能。默认值为 `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. 创建一个表后,在表中插入几行数据:

```sql
CREATE TABLE t (c INT);
```

```
Query OK, 0 rows affected (0.01 sec)
```

```sql
INSERT INTO t VALUES (1), (2), (3);
```

```
Query OK, 3 rows affected (0.00 sec)
```

2. 查看表中的数据:

```sql
SELECT * FROM t;
```

```
+------+
| c |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
```

3. 将 `tidb_external_ts` 设置为 `@@tidb_current_ts`:

```sql
START TRANSACTION;
SET GLOBAL tidb_external_ts = @@tidb_current_ts;
COMMIT;
```

4. 插入新的一行并确认新的一行已经被插入:

```sql
INSERT INTO t VALUES (4);
```

```
Query OK, 1 row affected (0.001 sec)
```

```sql
SELECT * FROM t;
```

```
+------+
| id |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
4 rows in set (0.00 sec)
```

5. 将 `tidb_enable_external_ts_read` 设置为 `ON` 后,再次查询表中的数据:

```sql
SET tidb_enable_external_ts_read = ON;
SELECT * FROM t;
```

```
+------+
| c |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
```

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