From 00fb603c1158f485737182051e2aee158e240c08 Mon Sep 17 00:00:00 2001 From: yisaer Date: Wed, 26 May 2021 18:20:09 +0800 Subject: [PATCH 01/57] add doc Signed-off-by: yisaer --- TOC.md | 4 +- read-historical-data.md | 2 +- read-stale-data.md | 265 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 269 insertions(+), 2 deletions(-) create mode 100644 read-stale-data.md diff --git a/TOC.md b/TOC.md index 95637c8f278e..18acafe241e0 100644 --- a/TOC.md +++ b/TOC.md @@ -60,7 +60,9 @@ + [BR 工具简介](/br/backup-and-restore-tool.md) + [使用 BR 命令行备份恢复](/br/use-br-command-line-tool.md) + [BR 备份恢复场景示例](/br/backup-and-restore-use-cases.md) - + [读取历史数据](/read-historical-data.md) + + [读取历史数据] + + [通过 tidb_snapshot 读取历史数据](/read-historical-data.md) + + [通过 as of timestamp 读取历史数据](/read-stale-data.md) + [修改时区](/configure-time-zone.md) + [日常巡检](/daily-check.md) + [TiFlash 常用运维操作](/tiflash/maintain-tiflash.md) diff --git a/read-historical-data.md b/read-historical-data.md index 3aa8479685e7..dfec0c1eff81 100644 --- a/read-historical-data.md +++ b/read-historical-data.md @@ -1,5 +1,5 @@ --- -title: 读取历史数据 +title: 通过 tidb_snapshot 读取历史数据 aliases: ['/docs-cn/dev/read-historical-data/','/docs-cn/dev/how-to/get-started/read-historical-data/'] --- diff --git a/read-stale-data.md b/read-stale-data.md new file mode 100644 index 000000000000..6c50463b3918 --- /dev/null +++ b/read-stale-data.md @@ -0,0 +1,265 @@ +--- +title: 通过 as of timestamp 读取历史数据 +aliases: ['/docs-cn/dev/read-stale-data/'] +--- + +# 读取历史数据 + +本文档介绍 TiDB 如何读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 + +## 功能说明 + +TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 client 或者 driver。当数据被更新、删除后,依然可以通过 SQL 接口将更新/删除前的数据读取出来。 + +另外即使在更新数据之后,表结构发生了变化,TiDB 依旧能用旧的表结构将数据读取出来。 + +## 操作流程 + +为支持读取历史版本数据,TiDB 扩展了新的语法 AS OF TIMESTAMP。目前支持以下三种方式使用该语法。 + +- 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP +- 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP +- 通过 SELECT 子句中使用 AS OF TIMESTAMP + +AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式为:“2016-10-08 16:45:26.999”,一般来说可以只写到秒,比如”2016-10-08 16:45:26”。 + +## 历史数据保留策略 + +参考[历史数据保留策略](/read-historical-data.md#历史数据保留策略) + +## 示例 + +### 准备阶段 + +1. 初始化阶段,创建一个表,并插入几行数据: + + {{< copyable "sql" >}} + + ```sql + create table t (c int); + ``` + + ``` + Query OK, 0 rows affected (0.01 sec) + ``` + + {{< copyable "sql" >}} + + ```sql + insert into t values (1), (2), (3); + ``` + + ``` + Query OK, 3 rows affected (0.00 sec) + ``` + +2. 查看表中的数据: + + {{< copyable "sql" >}} + + ```sql + select * from t; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 2 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + +3. 查看当前时间: + + {{< copyable "sql" >}} + + ```sql + select now(); + ``` + + ``` + +---------------------+ + | now() | + +---------------------+ + | 2021-05-26 16:45:26 | + +---------------------+ + 1 row in set (0.00 sec) + ``` + +4. 更新某一行数据: + + {{< copyable "sql" >}} + + ```sql + update t set c=22 where c=2; + ``` + + ``` + Query OK, 1 row affected (0.00 sec) + ``` + +5. 确认数据已经被更新: + + {{< copyable "sql" >}} + + ```sql + select * from t; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 22 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + +### 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 + +通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启一个基于历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 + + + ```sql + start transaction read only as of timestamp '2021-05-26 16:45:26'; + ``` + + ``` + Query OK, 0 rows affected (0.00 sec) + ``` + + ```sql + select * from t; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 2 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + + ```sql + commit; + ``` + + ``` + Query OK, 0 rows affected (0.00 sec) + ``` + +当事务结束后,即可读取最新数据。 + + ```sql + select * from t; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 22 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + +> **注意:** +> +> 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启的事务将会是一个只读事务。假如在该事务中执行写入操作,将会被该事务拒绝。 + +### 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 + +通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 表示下一个事务为基于该历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 + + ```sql + set transaction read only as of timestamp '2021-05-26 16:45:26'; + ``` + + ``` + Query OK, 0 rows affected (0.00 sec) + ``` + + ```sql + begin; + ``` + + ``` + Query OK, 0 rows affected (0.00 sec) + ``` + + ```sql + select * from t; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 2 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + + ```sql + commit; + ``` + + ``` + Query OK, 0 rows affected (0.00 sec) + ``` + +当事务结束后,即可读取最新数据。 + + ```sql + select * from t; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 22 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + +> **注意:** +> +> 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 开启的事务将会是一个只读事务。假如在该事务中执行写入操作,将会被该事务拒绝。 + +### 通过 SELECT 子句中使用 AS OF TIMESTAMP 读取历史数据 + +通过 SELECT 子句中使用 AS OF TIMESTAMP 对当前的查询语句基于历史时间进行查询数据。 + + ```sql + select * from t as of timestamp '2021-05-26 16:45:26'; + ``` + + ``` + +------+ + | c | + +------+ + | 1 | + | 2 | + | 3 | + +------+ + 3 rows in set (0.00 sec) + ``` + +## 历史数据恢复策略 + +参考[历史数据恢复策略](/read-historical-data.md#历史数据恢复策略) From 1b6e53fa6311a689bba3b2382fddd2e35518363e Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:17:09 +0800 Subject: [PATCH 02/57] add sql view Signed-off-by: yisaer --- read-stale-data.md | 4 ++-- .../sql-statement-set-transaction.md | 20 ++++++++++++------- .../sql-statement-start-transaction.md | 5 ++++- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/read-stale-data.md b/read-stale-data.md index 6c50463b3918..6853d6e7c33e 100644 --- a/read-stale-data.md +++ b/read-stale-data.md @@ -17,8 +17,8 @@ TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 为支持读取历史版本数据,TiDB 扩展了新的语法 AS OF TIMESTAMP。目前支持以下三种方式使用该语法。 -- 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP -- 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP +- 通过 [START TRANSACTION READ ONLY AS OF TIMESTAMP](/sql-statements/sql-statement-start-transaction.md) +- 通过 [SET TRANSACTION READ ONLY AS OF TIMESTAMP](/sql-statements/sql-statement-set-transaction.md) - 通过 SELECT 子句中使用 AS OF TIMESTAMP AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式为:“2016-10-08 16:45:26.999”,一般来说可以只写到秒,比如”2016-10-08 16:45:26”。 diff --git a/sql-statements/sql-statement-set-transaction.md b/sql-statements/sql-statement-set-transaction.md index 66973013fdc9..1f84502aaebc 100644 --- a/sql-statements/sql-statement-set-transaction.md +++ b/sql-statements/sql-statement-set-transaction.md @@ -10,17 +10,23 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-set-transaction/','/docs-cn ## 语法图 -**SetStmt:** +```ebnf+diagram -![SetStmt](/media/sqlgram/SetStmt.png) +SetStmt ::= + 'SET' ( VariableAssignmentList | + 'PASSWORD' ('FOR' Username)? '=' PasswordOpt | + ( 'GLOBAL'| 'SESSION' )? 'TRANSACTION' TransactionChars | + 'CONFIG' ( Identifier | stringLit) ConfigItemName EqOrAssignmentEq SetExpr ) -**TransactionChar:** +TransactionChars ::= + ( 'ISOLATION' 'LEVEL' IsolationLevel | 'READ' 'WRITE' | 'READ' 'ONLY' AsOfClause? ) -![TransactionChar](/media/sqlgram/TransactionChar.png) +IsolationLevel ::= + ( 'REPEATABLE' 'READ' | 'READ' ( 'COMMITTED' | 'UNCOMMITTED' ) | 'SERIALIZABLE' ) -**IsolationLevel:** - -![IsolationLevel](/media/sqlgram/IsolationLevel.png) +AsOfClause ::= + ( 'AS' 'OF' 'TIMESTAMP' Expression) +``` ## 示例 diff --git a/sql-statements/sql-statement-start-transaction.md b/sql-statements/sql-statement-start-transaction.md index c316b62bf92f..7e47005278fa 100644 --- a/sql-statements/sql-statement-start-transaction.md +++ b/sql-statements/sql-statement-start-transaction.md @@ -17,7 +17,10 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-start-transaction/','/docs- ```ebnf+diagram BeginTransactionStmt ::= 'BEGIN' ( 'PESSIMISTIC' | 'OPTIMISTIC' )? -| 'START' 'TRANSACTION' ( 'READ' ( 'WRITE' | 'ONLY' ( 'WITH' 'TIMESTAMP' 'BOUND' TimestampBound )? ) | 'WITH' 'CONSISTENT' 'SNAPSHOT' | 'WITH' 'CAUSAL' 'CONSISTENCY' 'ONLY' )? +| 'START' 'TRANSACTION' ( 'READ' ( 'WRITE' | 'ONLY' ( ( 'WITH' 'TIMESTAMP' 'BOUND' TimestampBound )? | AsOfClause ) ) | 'WITH' 'CONSISTENT' 'SNAPSHOT' | 'WITH' 'CAUSAL' 'CONSISTENCY' 'ONLY' )? + +AsOfClause ::= + ( 'AS' 'OF' 'TIMESTAMP' Expression) ``` ## 示例 From dc841572114588a178454339dd4aed840b82b86b Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:22:39 +0800 Subject: [PATCH 03/57] add sql view Signed-off-by: yisaer --- TOC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TOC.md b/TOC.md index 18acafe241e0..8a9af95a7092 100644 --- a/TOC.md +++ b/TOC.md @@ -60,7 +60,7 @@ + [BR 工具简介](/br/backup-and-restore-tool.md) + [使用 BR 命令行备份恢复](/br/use-br-command-line-tool.md) + [BR 备份恢复场景示例](/br/backup-and-restore-use-cases.md) - + [读取历史数据] + + 读取历史数据 + [通过 tidb_snapshot 读取历史数据](/read-historical-data.md) + [通过 as of timestamp 读取历史数据](/read-stale-data.md) + [修改时区](/configure-time-zone.md) From cc0e35c3268a022ecd351c8d18c818ce209a5c37 Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:28:45 +0800 Subject: [PATCH 04/57] fix lint Signed-off-by: yisaer --- read-stale-data.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/read-stale-data.md b/read-stale-data.md index 6853d6e7c33e..83d87af6911a 100644 --- a/read-stale-data.md +++ b/read-stale-data.md @@ -124,6 +124,7 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启一个基于历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 + {{< copyable "sql" >}} ```sql start transaction read only as of timestamp '2021-05-26 16:45:26'; @@ -133,6 +134,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 Query OK, 0 rows affected (0.00 sec) ``` + {{< copyable "sql" >}} + ```sql select * from t; ``` @@ -148,6 +151,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 3 rows in set (0.00 sec) ``` + {{< copyable "sql" >}} + ```sql commit; ``` @@ -158,6 +163,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 当事务结束后,即可读取最新数据。 + {{< copyable "sql" >}} + ```sql select * from t; ``` @@ -181,6 +188,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 表示下一个事务为基于该历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 + {{< copyable "sql" >}} + ```sql set transaction read only as of timestamp '2021-05-26 16:45:26'; ``` @@ -189,6 +198,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 Query OK, 0 rows affected (0.00 sec) ``` + {{< copyable "sql" >}} + ```sql begin; ``` @@ -197,6 +208,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 Query OK, 0 rows affected (0.00 sec) ``` + {{< copyable "sql" >}} + ```sql select * from t; ``` @@ -212,6 +225,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 3 rows in set (0.00 sec) ``` + {{< copyable "sql" >}} + ```sql commit; ``` @@ -222,6 +237,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 当事务结束后,即可读取最新数据。 + {{< copyable "sql" >}} + ```sql select * from t; ``` @@ -245,6 +262,8 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 通过 SELECT 子句中使用 AS OF TIMESTAMP 对当前的查询语句基于历史时间进行查询数据。 + {{< copyable "sql" >}} + ```sql select * from t as of timestamp '2021-05-26 16:45:26'; ``` From 14e2cf3f8fdd419a3442a3e9c52b437211fae5de Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:30:59 +0800 Subject: [PATCH 05/57] fix lint Signed-off-by: yisaer --- read-stale-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/read-stale-data.md b/read-stale-data.md index 83d87af6911a..b8c83be04a7f 100644 --- a/read-stale-data.md +++ b/read-stale-data.md @@ -263,7 +263,7 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 通过 SELECT 子句中使用 AS OF TIMESTAMP 对当前的查询语句基于历史时间进行查询数据。 {{< copyable "sql" >}} - + ```sql select * from t as of timestamp '2021-05-26 16:45:26'; ``` From 014573293f58f6b194ea7a1ebbe259aa551357f4 Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:35:09 +0800 Subject: [PATCH 06/57] fix lint Signed-off-by: yisaer --- read-stale-data.md | 222 +++++++++++++++++++++------------------------ 1 file changed, 102 insertions(+), 120 deletions(-) diff --git a/read-stale-data.md b/read-stale-data.md index b8c83be04a7f..2b413a57126b 100644 --- a/read-stale-data.md +++ b/read-stale-data.md @@ -33,152 +33,134 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 1. 初始化阶段,创建一个表,并插入几行数据: - {{< copyable "sql" >}} +```sql +create table t (c int); +``` - ```sql - create table t (c int); - ``` +``` +Query OK, 0 rows affected (0.01 sec) +``` - ``` - Query OK, 0 rows affected (0.01 sec) - ``` - - {{< copyable "sql" >}} +{{< copyable "sql" >}} - ```sql - insert into t values (1), (2), (3); - ``` +```sql +insert into t values (1), (2), (3); +``` - ``` - Query OK, 3 rows affected (0.00 sec) - ``` +``` +Query OK, 3 rows affected (0.00 sec) +``` 2. 查看表中的数据: - {{< copyable "sql" >}} - - ```sql - select * from t; - ``` - - ``` - +------+ - | c | - +------+ - | 1 | - | 2 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` +```sql +select * from t; +``` + +``` ++------+ +| c | ++------+ +| 1 | +| 2 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` 3. 查看当前时间: - {{< copyable "sql" >}} +```sql +select now(); +``` - ```sql - select now(); - ``` - - ``` - +---------------------+ - | now() | - +---------------------+ - | 2021-05-26 16:45:26 | - +---------------------+ - 1 row in set (0.00 sec) - ``` +``` ++---------------------+ +| now() | ++---------------------+ +| 2021-05-26 16:45:26 | ++---------------------+ +1 row in set (0.00 sec) +``` 4. 更新某一行数据: - {{< copyable "sql" >}} +```sql +update t set c=22 where c=2; +``` - ```sql - update t set c=22 where c=2; - ``` - - ``` - Query OK, 1 row affected (0.00 sec) - ``` +``` +Query OK, 1 row affected (0.00 sec) +``` 5. 确认数据已经被更新: - {{< copyable "sql" >}} - - ```sql - select * from t; - ``` - - ``` - +------+ - | c | - +------+ - | 1 | - | 22 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` +```sql +select * from t; +``` + +``` ++------+ +| c | ++------+ +| 1 | +| 22 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` ### 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启一个基于历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 - {{< copyable "sql" >}} - - ```sql - start transaction read only as of timestamp '2021-05-26 16:45:26'; - ``` - - ``` - Query OK, 0 rows affected (0.00 sec) - ``` - - {{< copyable "sql" >}} - - ```sql - select * from t; - ``` - - ``` - +------+ - | c | - +------+ - | 1 | - | 2 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` - - {{< copyable "sql" >}} - - ```sql - commit; - ``` - - ``` - Query OK, 0 rows affected (0.00 sec) - ``` +```sql +start transaction read only as of timestamp '2021-05-26 16:45:26'; +``` + +``` +Query OK, 0 rows affected (0.00 sec) +``` + +```sql +select * from t; +``` + +``` ++------+ +| c | ++------+ +| 1 | +| 2 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` + +```sql +commit; +``` + +``` +Query OK, 0 rows affected (0.00 sec) +``` 当事务结束后,即可读取最新数据。 - {{< copyable "sql" >}} - - ```sql - select * from t; - ``` - - ``` - +------+ - | c | - +------+ - | 1 | - | 22 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` +```sql +select * from t; +``` + +``` ++------+ +| c | ++------+ +| 1 | +| 22 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` > **注意:** > From 808a8891a74f08f0ddab580157e75e7f569c36e5 Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:49:31 +0800 Subject: [PATCH 07/57] fix lint Signed-off-by: yisaer --- read-stale-data.md | 130 ++++++++++++++++++++------------------------- 1 file changed, 58 insertions(+), 72 deletions(-) diff --git a/read-stale-data.md b/read-stale-data.md index 2b413a57126b..0c4b1deb8ab8 100644 --- a/read-stale-data.md +++ b/read-stale-data.md @@ -41,8 +41,6 @@ create table t (c int); Query OK, 0 rows affected (0.01 sec) ``` -{{< copyable "sql" >}} - ```sql insert into t values (1), (2), (3); ``` @@ -170,71 +168,61 @@ select * from t; 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 表示下一个事务为基于该历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 - {{< copyable "sql" >}} - - ```sql - set transaction read only as of timestamp '2021-05-26 16:45:26'; - ``` - - ``` - Query OK, 0 rows affected (0.00 sec) - ``` - - {{< copyable "sql" >}} - - ```sql - begin; - ``` +```sql +set transaction read only as of timestamp '2021-05-26 16:45:26'; +``` - ``` - Query OK, 0 rows affected (0.00 sec) - ``` +``` +Query OK, 0 rows affected (0.00 sec) +``` - {{< copyable "sql" >}} +```sql +begin; +``` - ```sql - select * from t; - ``` +``` +Query OK, 0 rows affected (0.00 sec) +``` - ``` - +------+ - | c | - +------+ - | 1 | - | 2 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` +```sql +select * from t; +``` - {{< copyable "sql" >}} +``` ++------+ +| c | ++------+ +| 1 | +| 2 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` - ```sql - commit; - ``` +```sql +commit; +``` - ``` - Query OK, 0 rows affected (0.00 sec) - ``` +``` +Query OK, 0 rows affected (0.00 sec) +``` 当事务结束后,即可读取最新数据。 - {{< copyable "sql" >}} - - ```sql - select * from t; - ``` +```sql +select * from t; +``` - ``` - +------+ - | c | - +------+ - | 1 | - | 22 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` +``` ++------+ +| c | ++------+ +| 1 | +| 22 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` > **注意:** > @@ -244,22 +232,20 @@ select * from t; 通过 SELECT 子句中使用 AS OF TIMESTAMP 对当前的查询语句基于历史时间进行查询数据。 - {{< copyable "sql" >}} - - ```sql - select * from t as of timestamp '2021-05-26 16:45:26'; - ``` - - ``` - +------+ - | c | - +------+ - | 1 | - | 2 | - | 3 | - +------+ - 3 rows in set (0.00 sec) - ``` +```sql +select * from t as of timestamp '2021-05-26 16:45:26'; +``` + +``` ++------+ +| c | ++------+ +| 1 | +| 2 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` ## 历史数据恢复策略 From c8f276d11ad530db397195d48158d16728b3d888 Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 27 May 2021 14:57:06 +0800 Subject: [PATCH 08/57] fix lint Signed-off-by: yisaer --- read-stale-data.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/read-stale-data.md b/read-stale-data.md index 0c4b1deb8ab8..c344d2d87500 100644 --- a/read-stale-data.md +++ b/read-stale-data.md @@ -31,7 +31,7 @@ AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式 ### 准备阶段 -1. 初始化阶段,创建一个表,并插入几行数据: +初始化阶段,创建一个表,并插入几行数据: ```sql create table t (c int); @@ -49,7 +49,7 @@ insert into t values (1), (2), (3); Query OK, 3 rows affected (0.00 sec) ``` -2. 查看表中的数据: +查看表中的数据: ```sql select * from t; @@ -66,7 +66,7 @@ select * from t; 3 rows in set (0.00 sec) ``` -3. 查看当前时间: +查看当前时间: ```sql select now(); @@ -81,7 +81,7 @@ select now(); 1 row in set (0.00 sec) ``` -4. 更新某一行数据: +更新某一行数据: ```sql update t set c=22 where c=2; @@ -91,7 +91,7 @@ update t set c=22 where c=2; Query OK, 1 row affected (0.00 sec) ``` -5. 确认数据已经被更新: +确认数据已经被更新: ```sql select * from t; From d84d1a3f9367b75bdee6b53b8d81fb91f0157907 Mon Sep 17 00:00:00 2001 From: JmPotato Date: Tue, 1 Jun 2021 18:32:32 +0800 Subject: [PATCH 09/57] Add Stale Read introduction Signed-off-by: JmPotato --- TOC.md | 6 ++++-- read-stale-data.md => as-of-timestamp.md | 15 ++++++++++----- stale-read.md | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) rename read-stale-data.md => as-of-timestamp.md (76%) create mode 100644 stale-read.md diff --git a/TOC.md b/TOC.md index 8a9af95a7092..3d165ea8b8a9 100644 --- a/TOC.md +++ b/TOC.md @@ -61,8 +61,10 @@ + [使用 BR 命令行备份恢复](/br/use-br-command-line-tool.md) + [BR 备份恢复场景示例](/br/backup-and-restore-use-cases.md) + 读取历史数据 - + [通过 tidb_snapshot 读取历史数据](/read-historical-data.md) - + [通过 as of timestamp 读取历史数据](/read-stale-data.md) + + 通过 Stale Read 功能读取历史数据 + + [Stale Read 功能使用场景介绍](/stale-read.md) + + [使用 AS OF TIMESTAMP 语法读取历史数据](/as-of-timestamp.md) + + [通过系统变量 tidb_snapshot 读取历史数据](/read-historical-data.md) + [修改时区](/configure-time-zone.md) + [日常巡检](/daily-check.md) + [TiFlash 常用运维操作](/tiflash/maintain-tiflash.md) diff --git a/read-stale-data.md b/as-of-timestamp.md similarity index 76% rename from read-stale-data.md rename to as-of-timestamp.md index c344d2d87500..71422338cb7f 100644 --- a/read-stale-data.md +++ b/as-of-timestamp.md @@ -1,11 +1,11 @@ --- -title: 通过 as of timestamp 读取历史数据 +title: 使用 AS OF TIMESTAMP 语法读取历史数据 aliases: ['/docs-cn/dev/read-stale-data/'] --- -# 读取历史数据 +# 使用 AS OF TIMESTAMP 语法读取历史数据 -本文档介绍 TiDB 如何读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 +本文档介绍如何使用 Stale Read 功能中的 AS OF TIMESTAMP 语句来读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 ## 功能说明 @@ -13,7 +13,7 @@ TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 另外即使在更新数据之后,表结构发生了变化,TiDB 依旧能用旧的表结构将数据读取出来。 -## 操作流程 +## 语法方式 为支持读取历史版本数据,TiDB 扩展了新的语法 AS OF TIMESTAMP。目前支持以下三种方式使用该语法。 @@ -21,7 +21,12 @@ TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 - 通过 [SET TRANSACTION READ ONLY AS OF TIMESTAMP](/sql-statements/sql-statement-set-transaction.md) - 通过 SELECT 子句中使用 AS OF TIMESTAMP -AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式为:“2016-10-08 16:45:26.999”,一般来说可以只写到秒,比如”2016-10-08 16:45:26”。 +AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式为:“2016-10-08 16:45:26.999”,最小时间精度范围为毫秒,但一般来说可以只写到秒,比如”2016-10-08 16:45:26”,也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。当需要指定时间范围时,需要使用 `TIDB_BOUNDED_STALENESS()` 函数,具体用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 t1 和 t2 为时间范围的两端,支持接受日期时间和时间函数,例如: + +- `AS OF TIMESTAMP '2016-10-08 16:45:26'` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒时最新的数据。 +- `AS OF TIMESTAMP NOW() - INTERVAL 10 SECOND` 表示读取 10 秒前最新的数据。 +- `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS('2016-10-08 16:45:26', '2016-10-08 16:45:29')` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒到 29 秒的时间范围内尽可能新的数据。 +- `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS(NOW() - INTERVAL 20 SECOND, NOW())` 表示读取 20 秒前到现在的时间范围内尽可能新的数据。 ## 历史数据保留策略 diff --git a/stale-read.md b/stale-read.md new file mode 100644 index 000000000000..e85280da602a --- /dev/null +++ b/stale-read.md @@ -0,0 +1,21 @@ +--- +title: Stale Read 功能使用场景介绍 +aliases: ['/docs-cn/dev/stale-read/'] +--- + +# Stale Read 功能介绍 + +Stale Read 是 TiDB 提供快速读取数据的一种机制。Stale Read 功能允许用户通过指定时间点或时间范围的方式读取一定程度上的历史数据(使用 [AS OF TIMESTAMP 语法](/as-of-timestamp.md))。通过 Stale Read,TiDB 可以从任意一个副本上读取到所给定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 + +# 使用场景 + +在一些跨数据中心部署的场景中,上层应用或业务所请求的大部分事务类型都是只读事务,只存在部分只写事务或读写事务。对于读写事务或者只写事务,业务应用可以容忍一定程度的延迟代价,但是对只读事务来说,其对延迟和 QPS 都有较高的要求。在达到延迟与 QPS 要求的基础上,此类只读事务往往也能够容忍读到一定程度的旧数据,即偏斜的数据(Stale Data)。在 Stale Read 功能中,TiDB 通过牺牲*只读事务*所能读到数据的实效性,并允许从更近距离的副本中读取数据,来在数据跨中心的部署场景中提供更好的读性能。由于 TiDB 使用了 Raft 来作为集群内的副本一致性共识算法,传统的读请求需要由多个副本中的 Leader 角色提供,即便引入了 [Follower Read](/follower-read.md) 功能来减少 Leader 对读请求的处理压力,但为了保证一致性读(Consistent Read)————即在 Follower 上读到的数据在 Leader 上也一定能读到,反之亦然————副本中的 Follower 角色需要在处理读请求之前与 Leader 进行通信,确保自身的数据同步进度至少与 Leader 一样才可以对外提供读请求的处理服务。在跨中心部署的场景下,延迟对上述过程所带来的影响会变得显著,从而降低集群对读请求的处理能力。Stale Read 通过引入类似安全时间节点的机制,达成一致性读的同时减少副本间的进度同步开销,并结合从地理位置更近的副本中读取,在多区域部署中带来更好的延迟表现。 + +# 使用方式 + +如前所述,TiDB 提供两种 Stale Read 的方式,分别是指定一个精确的时间点和一个时间范围,两者的区别如下: + +- 精确时间点:通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式)提供。 +- 时间范围:通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式) 和 [TIDB_BOUNDED_STALENESS 函数](/as-of-timestamp.md#语法方式)实现。 + +除了语法的使用,Stale Read 通常需要配合 TiDB 的 Geo-Partition 部署来进一步在跨中心部署场景中获得更好的性能表现,具体可见[Geo-Partition 使用文档](/configure-geo-partition.md)。 \ No newline at end of file From 03f3ccdff0897b26a800d8b270e0b21043509549 Mon Sep 17 00:00:00 2001 From: JmPotato Date: Tue, 1 Jun 2021 18:53:02 +0800 Subject: [PATCH 10/57] Fix the link Signed-off-by: JmPotato --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index e85280da602a..aca0bae85e69 100644 --- a/stale-read.md +++ b/stale-read.md @@ -18,4 +18,4 @@ Stale Read 是 TiDB 提供快速读取数据的一种机制。Stale Read 功能 - 精确时间点:通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式)提供。 - 时间范围:通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式) 和 [TIDB_BOUNDED_STALENESS 函数](/as-of-timestamp.md#语法方式)实现。 -除了语法的使用,Stale Read 通常需要配合 TiDB 的 Geo-Partition 部署来进一步在跨中心部署场景中获得更好的性能表现,具体可见[Geo-Partition 使用文档](/configure-geo-partition.md)。 \ No newline at end of file +除了语法的使用,Stale Read 通常需要配合 TiDB 的 Geo-Partition 部署来进一步在跨中心部署场景中获得更好的性能表现,具体可见 Geo-Partition 使用文档。 \ No newline at end of file From 72ec40a4c3421b00e71e1f2a4762f258471aef2a Mon Sep 17 00:00:00 2001 From: JmPotato Date: Tue, 1 Jun 2021 18:59:34 +0800 Subject: [PATCH 11/57] Fix a typo Signed-off-by: JmPotato --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 71422338cb7f..26bf1a354f76 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -171,7 +171,7 @@ select * from t; ### 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 -通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 表示下一个事务为基于该历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 +通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 表示下一个事务为基于该历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 ```sql set transaction read only as of timestamp '2021-05-26 16:45:26'; From bdb6ca9f1a05eac84ace9e91013747c03d2f3314 Mon Sep 17 00:00:00 2001 From: JmPotato Date: Tue, 8 Jun 2021 11:16:12 +0800 Subject: [PATCH 12/57] Refine the introduction of usage scenario Signed-off-by: JmPotato --- stale-read.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/stale-read.md b/stale-read.md index aca0bae85e69..73c9f64eeca9 100644 --- a/stale-read.md +++ b/stale-read.md @@ -9,7 +9,9 @@ Stale Read 是 TiDB 提供快速读取数据的一种机制。Stale Read 功能 # 使用场景 -在一些跨数据中心部署的场景中,上层应用或业务所请求的大部分事务类型都是只读事务,只存在部分只写事务或读写事务。对于读写事务或者只写事务,业务应用可以容忍一定程度的延迟代价,但是对只读事务来说,其对延迟和 QPS 都有较高的要求。在达到延迟与 QPS 要求的基础上,此类只读事务往往也能够容忍读到一定程度的旧数据,即偏斜的数据(Stale Data)。在 Stale Read 功能中,TiDB 通过牺牲*只读事务*所能读到数据的实效性,并允许从更近距离的副本中读取数据,来在数据跨中心的部署场景中提供更好的读性能。由于 TiDB 使用了 Raft 来作为集群内的副本一致性共识算法,传统的读请求需要由多个副本中的 Leader 角色提供,即便引入了 [Follower Read](/follower-read.md) 功能来减少 Leader 对读请求的处理压力,但为了保证一致性读(Consistent Read)————即在 Follower 上读到的数据在 Leader 上也一定能读到,反之亦然————副本中的 Follower 角色需要在处理读请求之前与 Leader 进行通信,确保自身的数据同步进度至少与 Leader 一样才可以对外提供读请求的处理服务。在跨中心部署的场景下,延迟对上述过程所带来的影响会变得显著,从而降低集群对读请求的处理能力。Stale Read 通过引入类似安全时间节点的机制,达成一致性读的同时减少副本间的进度同步开销,并结合从地理位置更近的副本中读取,在多区域部署中带来更好的延迟表现。 +在一些跨数据中心部署的场景中,上层应用或业务所请求的大部分事务类型都是只读事务,只存在部分只写事务或读写事务。对于读写事务或者只写事务,业务应用可以容忍一定程度的延迟代价,但是对只读事务来说,其对延迟和 QPS 都有较高的要求。在达到延迟与 QPS 要求的基础上,此类只读事务往往也能够容忍读到一定程度的旧数据,即偏斜的数据(Stale Data)。在 Stale Read 功能中,TiDB 通过牺牲*只读事务*所能读到数据的实效性,并允许从更近距离的副本中读取数据,来在数据跨中心的部署场景中提供更好的读性能。由于 TiDB 使用了 Raft 来作为集群内的副本一致性共识算法,传统的读请求需要由多个副本中的 Leader 角色提供,即便引入了 [Follower Read](/follower-read.md) 功能来减少 Leader 对读请求的处理压力,但为了保证一致性读(Consistent Read)————即在 Follower 上读到的数据在 Leader 上也一定能读到,反之亦然————副本中的 Follower 角色需要在处理读请求之前与 Leader 进行通信,确保自身的数据同步进度至少与 Leader 一样才可以对外提供读请求的处理服务。在跨中心部署的场景下,延迟对上述过程所带来的影响会变得显著,从而降低集群对读请求的处理能力。 + +而 Stale Read 通过引入类似安全时间节点的机制,达成一致性读的同时减少副本间的进度同步开销,并且可以从地理位置更近的副本中进行读操作,在多区域部署中带来更好的延迟表现。同时,由于 Stale Read 读取的可以是有一定时间偏斜的历史数据,读写冲突可以被极大地避免,性能表现从而得以提升。 # 使用方式 @@ -17,5 +19,3 @@ Stale Read 是 TiDB 提供快速读取数据的一种机制。Stale Read 功能 - 精确时间点:通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式)提供。 - 时间范围:通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式) 和 [TIDB_BOUNDED_STALENESS 函数](/as-of-timestamp.md#语法方式)实现。 - -除了语法的使用,Stale Read 通常需要配合 TiDB 的 Geo-Partition 部署来进一步在跨中心部署场景中获得更好的性能表现,具体可见 Geo-Partition 使用文档。 \ No newline at end of file From b53e3ad38e883d9687ffbbcd8b3d34b87af78d41 Mon Sep 17 00:00:00 2001 From: JmPotato Date: Thu, 10 Jun 2021 10:49:52 +0800 Subject: [PATCH 13/57] Update TOC.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- TOC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TOC.md b/TOC.md index 94c0be6376c6..b44d4ccc67a8 100644 --- a/TOC.md +++ b/TOC.md @@ -65,7 +65,7 @@ + 读取历史数据 + 通过 Stale Read 功能读取历史数据 + [Stale Read 功能使用场景介绍](/stale-read.md) - + [使用 AS OF TIMESTAMP 语法读取历史数据](/as-of-timestamp.md) + + [使用 `AS OF TIMESTAMP` 语法读取历史数据](/as-of-timestamp.md) + [通过系统变量 tidb_snapshot 读取历史数据](/read-historical-data.md) + [修改时区](/configure-time-zone.md) + [日常巡检](/daily-check.md) From 790d75aca25722e60c6861e6ef361864c21f70a2 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Thu, 10 Jun 2021 12:50:17 +0800 Subject: [PATCH 14/57] Apply suggestions from code review Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- TOC.md | 2 +- as-of-timestamp.md | 16 +++++++++------- read-historical-data.md | 2 +- stale-read.md | 18 ++++++++++-------- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/TOC.md b/TOC.md index b44d4ccc67a8..0fcbb534a49f 100644 --- a/TOC.md +++ b/TOC.md @@ -66,7 +66,7 @@ + 通过 Stale Read 功能读取历史数据 + [Stale Read 功能使用场景介绍](/stale-read.md) + [使用 `AS OF TIMESTAMP` 语法读取历史数据](/as-of-timestamp.md) - + [通过系统变量 tidb_snapshot 读取历史数据](/read-historical-data.md) + + [通过系统变量 `tidb_snapshot` 读取历史数据](/read-historical-data.md) + [修改时区](/configure-time-zone.md) + [日常巡检](/daily-check.md) + [TiFlash 常用运维操作](/tiflash/maintain-tiflash.md) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 26bf1a354f76..73d732f30417 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -1,11 +1,11 @@ --- title: 使用 AS OF TIMESTAMP 语法读取历史数据 -aliases: ['/docs-cn/dev/read-stale-data/'] +summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 --- # 使用 AS OF TIMESTAMP 语法读取历史数据 -本文档介绍如何使用 Stale Read 功能中的 AS OF TIMESTAMP 语句来读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 +本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 ## 功能说明 @@ -15,13 +15,15 @@ TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 ## 语法方式 -为支持读取历史版本数据,TiDB 扩展了新的语法 AS OF TIMESTAMP。目前支持以下三种方式使用该语法。 +你可以通过以下三种方式使用 `AS OF TIMESTAMP` 语法: -- 通过 [START TRANSACTION READ ONLY AS OF TIMESTAMP](/sql-statements/sql-statement-start-transaction.md) -- 通过 [SET TRANSACTION READ ONLY AS OF TIMESTAMP](/sql-statements/sql-statement-set-transaction.md) -- 通过 SELECT 子句中使用 AS OF TIMESTAMP +- [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) +- [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) +- 在 `SELECT` 的子句中使用 `AS OF TIMESTAMP` -AS OF TIMESTAMP 支持接收日期时间和时间函数,日期时间的格式为:“2016-10-08 16:45:26.999”,最小时间精度范围为毫秒,但一般来说可以只写到秒,比如”2016-10-08 16:45:26”,也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。当需要指定时间范围时,需要使用 `TIDB_BOUNDED_STALENESS()` 函数,具体用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 t1 和 t2 为时间范围的两端,支持接受日期时间和时间函数,例如: +如果你指定的是精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 + +如果你指定的是时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: - `AS OF TIMESTAMP '2016-10-08 16:45:26'` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒时最新的数据。 - `AS OF TIMESTAMP NOW() - INTERVAL 10 SECOND` 表示读取 10 秒前最新的数据。 diff --git a/read-historical-data.md b/read-historical-data.md index dfec0c1eff81..4e1728eb3476 100644 --- a/read-historical-data.md +++ b/read-historical-data.md @@ -1,5 +1,5 @@ --- -title: 通过 tidb_snapshot 读取历史数据 +title: 通过系统变量 tidb_snapshot 读取历史数据 aliases: ['/docs-cn/dev/read-historical-data/','/docs-cn/dev/how-to/get-started/read-historical-data/'] --- diff --git a/stale-read.md b/stale-read.md index 73c9f64eeca9..1f88c9ab708a 100644 --- a/stale-read.md +++ b/stale-read.md @@ -1,11 +1,13 @@ --- -title: Stale Read 功能使用场景介绍 -aliases: ['/docs-cn/dev/stale-read/'] +title: Stale Read 功能的使用场景 +summary: 介绍 Stale Read 功能和使用场景。 --- -# Stale Read 功能介绍 +# Stale Read 功能的使用场景 -Stale Read 是 TiDB 提供快速读取数据的一种机制。Stale Read 功能允许用户通过指定时间点或时间范围的方式读取一定程度上的历史数据(使用 [AS OF TIMESTAMP 语法](/as-of-timestamp.md))。通过 Stale Read,TiDB 可以从任意一个副本上读取到所给定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 +本文档介绍 Stale Read 的使用场景。Stale Read 是 TiDB 用户快速读取数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取一定程度上的历史数据。 + +在内部实现上,TiDB 通过 Stale Read 可以从任意一个副本上读取到该指定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 # 使用场景 @@ -13,9 +15,9 @@ Stale Read 是 TiDB 提供快速读取数据的一种机制。Stale Read 功能 而 Stale Read 通过引入类似安全时间节点的机制,达成一致性读的同时减少副本间的进度同步开销,并且可以从地理位置更近的副本中进行读操作,在多区域部署中带来更好的延迟表现。同时,由于 Stale Read 读取的可以是有一定时间偏斜的历史数据,读写冲突可以被极大地避免,性能表现从而得以提升。 -# 使用方式 +## 使用方法 -如前所述,TiDB 提供两种 Stale Read 的方式,分别是指定一个精确的时间点和一个时间范围,两者的区别如下: +TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: -- 精确时间点:通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式)提供。 -- 时间范围:通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。该功能通过 [AS OF TIMESTAMP 语法](/as-of-timestamp.md#语法方式) 和 [TIDB_BOUNDED_STALENESS 函数](/as-of-timestamp.md#语法方式)实现。 +- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 +- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式) 文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 From e897d1900a53462d76d5c50dbf953335cc9de057 Mon Sep 17 00:00:00 2001 From: yisaer Date: Thu, 10 Jun 2021 13:53:03 +0800 Subject: [PATCH 15/57] address the comment Signed-off-by: yisaer --- as-of-timestamp.md | 12 +++++++----- read-historical-data.md | 4 +++- stale-read.md | 6 ++++-- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 73d732f30417..4a221b99fc4d 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -11,7 +11,9 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 client 或者 driver。当数据被更新、删除后,依然可以通过 SQL 接口将更新/删除前的数据读取出来。 -另外即使在更新数据之后,表结构发生了变化,TiDB 依旧能用旧的表结构将数据读取出来。 +> **注意:** +> +> 读取历史数据时,即使当前数据的表结构相较于历史数据的表结构已经发生改变,历史数据也会使用当时的表结构来返回数据。 ## 语法方式 @@ -34,6 +36,10 @@ TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 参考[历史数据保留策略](/read-historical-data.md#历史数据保留策略) +## 历史数据恢复策略 + +参考[历史数据恢复策略](/read-historical-data.md#历史数据恢复策略) + ## 示例 ### 准备阶段 @@ -253,7 +259,3 @@ select * from t as of timestamp '2021-05-26 16:45:26'; +------+ 3 rows in set (0.00 sec) ``` - -## 历史数据恢复策略 - -参考[历史数据恢复策略](/read-historical-data.md#历史数据恢复策略) diff --git a/read-historical-data.md b/read-historical-data.md index 4e1728eb3476..eadc4e00a137 100644 --- a/read-historical-data.md +++ b/read-historical-data.md @@ -11,7 +11,9 @@ aliases: ['/docs-cn/dev/read-historical-data/','/docs-cn/dev/how-to/get-started/ TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 client 或者 driver。当数据被更新、删除后,依然可以通过 SQL 接口将更新/删除前的数据读取出来。 -另外即使在更新数据之后,表结构发生了变化,TiDB 依旧能用旧的表结构将数据读取出来。 +> **注意:** +> +> 读取历史数据时,即使当前数据的表结构相较于历史数据的表结构已经发生改变,历史数据也会使用当时的表结构来返回数据。 ## 操作流程 diff --git a/stale-read.md b/stale-read.md index 1f88c9ab708a..797a3790b67c 100644 --- a/stale-read.md +++ b/stale-read.md @@ -11,9 +11,11 @@ summary: 介绍 Stale Read 功能和使用场景。 # 使用场景 -在一些跨数据中心部署的场景中,上层应用或业务所请求的大部分事务类型都是只读事务,只存在部分只写事务或读写事务。对于读写事务或者只写事务,业务应用可以容忍一定程度的延迟代价,但是对只读事务来说,其对延迟和 QPS 都有较高的要求。在达到延迟与 QPS 要求的基础上,此类只读事务往往也能够容忍读到一定程度的旧数据,即偏斜的数据(Stale Data)。在 Stale Read 功能中,TiDB 通过牺牲*只读事务*所能读到数据的实效性,并允许从更近距离的副本中读取数据,来在数据跨中心的部署场景中提供更好的读性能。由于 TiDB 使用了 Raft 来作为集群内的副本一致性共识算法,传统的读请求需要由多个副本中的 Leader 角色提供,即便引入了 [Follower Read](/follower-read.md) 功能来减少 Leader 对读请求的处理压力,但为了保证一致性读(Consistent Read)————即在 Follower 上读到的数据在 Leader 上也一定能读到,反之亦然————副本中的 Follower 角色需要在处理读请求之前与 Leader 进行通信,确保自身的数据同步进度至少与 Leader 一样才可以对外提供读请求的处理服务。在跨中心部署的场景下,延迟对上述过程所带来的影响会变得显著,从而降低集群对读请求的处理能力。 +当一个事务只涉及到只读并且可以容忍牺牲一定程度的实时性时,我们可以通过 Stale Read 功能。由于牺牲了一定的实时性,使用 Stale Read 允许将请求发送到对应数据的任意一个副本,使得查询能够得到更强的吞吐能力。 -而 Stale Read 通过引入类似安全时间节点的机制,达成一致性读的同时减少副本间的进度同步开销,并且可以从地理位置更近的副本中进行读操作,在多区域部署中带来更好的延迟表现。同时,由于 Stale Read 读取的可以是有一定时间偏斜的历史数据,读写冲突可以被极大地避免,性能表现从而得以提升。 +在一些小表查询的场景中,在使用强一致性读的情况下,由于数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。而通过 Stale Read 功能,可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,会有显著的增强。 + +在一些跨数据中心部署的场景中,在使用强一致性读的情况下,可能存在数据请求的源头,与数据实际所在中心不同,从而产生跨数据中心读的情形,导致整体查询的访问延迟上升。通过使用 Stale Read 功能,可以让每个数据请求就近访问对应数据所在当前中心的副本,从而避免跨数据中心读的情形,降低整体查询的访问延迟。 ## 使用方法 From 911de890542ea45468186d26304bf735d9c04b0c Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:15:07 +0800 Subject: [PATCH 16/57] Update TOC.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- TOC.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TOC.md b/TOC.md index 0fcbb534a49f..6a27cb896658 100644 --- a/TOC.md +++ b/TOC.md @@ -64,7 +64,7 @@ + [BR 常见问题](/br/backup-and-restore-faq.md) + 读取历史数据 + 通过 Stale Read 功能读取历史数据 - + [Stale Read 功能使用场景介绍](/stale-read.md) + + [Stale Read 使用场景介绍](/stale-read.md) + [使用 `AS OF TIMESTAMP` 语法读取历史数据](/as-of-timestamp.md) + [通过系统变量 `tidb_snapshot` 读取历史数据](/read-historical-data.md) + [修改时区](/configure-time-zone.md) From 85bc899352a31e3244a77b7e61dd0ab798d57c95 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:15:30 +0800 Subject: [PATCH 17/57] Update stale-read.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index 797a3790b67c..0038ea8329c7 100644 --- a/stale-read.md +++ b/stale-read.md @@ -22,4 +22,4 @@ summary: 介绍 Stale Read 功能和使用场景。 TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: - 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 -- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式) 文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 +- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 From d6c070c7fb4e0f550b86cb77925264f9da6dd08c Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:15:57 +0800 Subject: [PATCH 18/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 4a221b99fc4d..153bfc63a3be 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -243,7 +243,7 @@ select * from t; ### 通过 SELECT 子句中使用 AS OF TIMESTAMP 读取历史数据 -通过 SELECT 子句中使用 AS OF TIMESTAMP 对当前的查询语句基于历史时间进行查询数据。 +若查询语句需要基于历史时间进行数据查询,你可以在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`: ```sql select * from t as of timestamp '2021-05-26 16:45:26'; From 293c4f45ad427df1f697d604c7e1e0194a318288 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:16:11 +0800 Subject: [PATCH 19/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 153bfc63a3be..75faf9192e44 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -241,7 +241,7 @@ select * from t; > > 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 开启的事务将会是一个只读事务。假如在该事务中执行写入操作,将会被该事务拒绝。 -### 通过 SELECT 子句中使用 AS OF TIMESTAMP 读取历史数据 +### 通过 `SELECT` 子句中使用 `AS OF TIMESTAMP` 读取历史数据 若查询语句需要基于历史时间进行数据查询,你可以在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`: From 27f0caf754b4e41a9d958a4f509d6a971864b8ea Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:16:23 +0800 Subject: [PATCH 20/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 75faf9192e44..2bafa694f470 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -239,7 +239,7 @@ select * from t; > **注意:** > -> 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 开启的事务将会是一个只读事务。假如在该事务中执行写入操作,将会被该事务拒绝。 +> 通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 开启的事务为只读事务。假如在该事务中执行写入操作,操作将会被该事务拒绝。 ### 通过 `SELECT` 子句中使用 `AS OF TIMESTAMP` 读取历史数据 From 0a79a097550a386f31196b1137c94f1ceb917030 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:16:32 +0800 Subject: [PATCH 21/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 2bafa694f470..21a47595593c 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -179,7 +179,7 @@ select * from t; ### 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 -通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 表示下一个事务为基于该历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 +通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 表示下一个事务是基于指定历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 ```sql set transaction read only as of timestamp '2021-05-26 16:45:26'; From 6cee97bd5df2dbf315ebeae7bed2cfb2f3c89592 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:16:43 +0800 Subject: [PATCH 22/57] Update stale-read.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index 0038ea8329c7..193073299d6c 100644 --- a/stale-read.md +++ b/stale-read.md @@ -13,7 +13,7 @@ summary: 介绍 Stale Read 功能和使用场景。 当一个事务只涉及到只读并且可以容忍牺牲一定程度的实时性时,我们可以通过 Stale Read 功能。由于牺牲了一定的实时性,使用 Stale Read 允许将请求发送到对应数据的任意一个副本,使得查询能够得到更强的吞吐能力。 -在一些小表查询的场景中,在使用强一致性读的情况下,由于数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。而通过 Stale Read 功能,可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,会有显著的增强。 ++ 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 在一些跨数据中心部署的场景中,在使用强一致性读的情况下,可能存在数据请求的源头,与数据实际所在中心不同,从而产生跨数据中心读的情形,导致整体查询的访问延迟上升。通过使用 Stale Read 功能,可以让每个数据请求就近访问对应数据所在当前中心的副本,从而避免跨数据中心读的情形,降低整体查询的访问延迟。 From 19c44aa6e2d70d7a8d038090fc91ed2838258a75 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:16:56 +0800 Subject: [PATCH 23/57] Update stale-read.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index 193073299d6c..f154032fa11b 100644 --- a/stale-read.md +++ b/stale-read.md @@ -15,7 +15,7 @@ summary: 介绍 Stale Read 功能和使用场景。 + 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 -在一些跨数据中心部署的场景中,在使用强一致性读的情况下,可能存在数据请求的源头,与数据实际所在中心不同,从而产生跨数据中心读的情形,导致整体查询的访问延迟上升。通过使用 Stale Read 功能,可以让每个数据请求就近访问对应数据所在当前中心的副本,从而避免跨数据中心读的情形,降低整体查询的访问延迟。 ++ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性读,数据请求的源头可能与数据实际所在中心不一致,从而产生跨数据中心读取数据的情况,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,每个数据请求可就近访问对应数据所在当前中心的副本,从而避免跨数据中心读,降低整体查询的访问延迟。 ## 使用方法 From 36a7487c82dbb26ff8479de85949013bc5e023e8 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:17:11 +0800 Subject: [PATCH 24/57] Update stale-read.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index f154032fa11b..26e099065283 100644 --- a/stale-read.md +++ b/stale-read.md @@ -9,7 +9,7 @@ summary: 介绍 Stale Read 功能和使用场景。 在内部实现上,TiDB 通过 Stale Read 可以从任意一个副本上读取到该指定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 -# 使用场景 +## 场景描述 当一个事务只涉及到只读并且可以容忍牺牲一定程度的实时性时,我们可以通过 Stale Read 功能。由于牺牲了一定的实时性,使用 Stale Read 允许将请求发送到对应数据的任意一个副本,使得查询能够得到更强的吞吐能力。 From 83a74549f88c11a53e2c37cdfa3d321e185b288f Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:17:17 +0800 Subject: [PATCH 25/57] Update stale-read.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index 26e099065283..4a6601ec10da 100644 --- a/stale-read.md +++ b/stale-read.md @@ -11,7 +11,7 @@ summary: 介绍 Stale Read 功能和使用场景。 ## 场景描述 -当一个事务只涉及到只读并且可以容忍牺牲一定程度的实时性时,我们可以通过 Stale Read 功能。由于牺牲了一定的实时性,使用 Stale Read 允许将请求发送到对应数据的任意一个副本,使得查询能够得到更强的吞吐能力。 ++ 场景一:如果一个事务仅涉及只读操作,并且一定程度上可容忍牺牲实时性,你可以使用 Stale Read 功能来读取历史数据。由于牺牲了一定的实时性,使用 Stale Read 后,TiDB 可将请求发送到对应数据的任意一个副本,使得查询的执行获得更大的吞吐量。 + 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 From 218a107f0fa25c52545029066012bd1047adbb42 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:17:38 +0800 Subject: [PATCH 26/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 1 - 1 file changed, 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 21a47595593c..8979f2e53965 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -7,7 +7,6 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 -## 功能说明 TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 client 或者 driver。当数据被更新、删除后,依然可以通过 SQL 接口将更新/删除前的数据读取出来。 From 23584df272300b46076e5b5e644e2afc0f0d3a6b Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:17:51 +0800 Subject: [PATCH 27/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 8979f2e53965..e1f92a6c7de9 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -8,7 +8,7 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 -TiDB 实现了通过标准 SQL 接口读取历史数据功能,无需特殊的 client 或者 driver。当数据被更新、删除后,依然可以通过 SQL 接口将更新/删除前的数据读取出来。 +TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的形式读取历史数据,无需特殊的服务器或者驱动器。当数据被更新、删除后,你可以通过 SQL 接口将更新或删除前的数据读取出来。 > **注意:** > From ebc77c1ee5e679abc71cae59d29018e39ee5dfe2 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:18:00 +0800 Subject: [PATCH 28/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index e1f92a6c7de9..478dbf5402a5 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -12,7 +12,7 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 > **注意:** > -> 读取历史数据时,即使当前数据的表结构相较于历史数据的表结构已经发生改变,历史数据也会使用当时的表结构来返回数据。 +> 读取历史数据时,即使当前数据的表结构相较于历史数据的表结构已经发生改变,历史数据也会以当时的历史表结构来返回。 ## 语法方式 From 18cb71589c93b8d708a70573336becfe914224d8 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:18:19 +0800 Subject: [PATCH 29/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 478dbf5402a5..5559c059793c 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -41,6 +41,8 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 ## 示例 +本节通过多个示例介绍 `AS OF TIMESTAMP` 语法的不同使用方法。在本节中,先准备用于恢复的数据,再分别展示如何通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP`、`SET TRANSACTION READ ONLY AS OF TIMESTAMP` 以及在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`。 + ### 准备阶段 初始化阶段,创建一个表,并插入几行数据: From c260ad82477fce34ab4359b97cc456e843dcfe56 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:19:02 +0800 Subject: [PATCH 30/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 5559c059793c..467a7694a25f 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -31,13 +31,9 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS('2016-10-08 16:45:26', '2016-10-08 16:45:29')` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒到 29 秒的时间范围内尽可能新的数据。 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS(NOW() - INTERVAL 20 SECOND, NOW())` 表示读取 20 秒前到现在的时间范围内尽可能新的数据。 -## 历史数据保留策略 +## 历史数据的保留和恢复策略 -参考[历史数据保留策略](/read-historical-data.md#历史数据保留策略) - -## 历史数据恢复策略 - -参考[历史数据恢复策略](/read-historical-data.md#历史数据恢复策略) +通过 Stale Read 方法读取的历史数据所采用的保留和恢复策略同使用 `tidb_snapshot` 系统变量读取的历史数据,详见[通过系统变量 `tidb_snapshot` 读取历史数据 - 历史数据保留策略](/read-historical-data.md#历史数据保留策略)和[通过系统变量 `tidb_snapshot` 读取历史数据 - 历史数据恢复策略](/read-historical-data.md#历史数据恢复策略)。 ## 示例 From 7f0b30219b2abc18670bb2dfdc066c702b87e135 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:19:20 +0800 Subject: [PATCH 31/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 467a7694a25f..fb8f9c04ce33 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -41,7 +41,7 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 ### 准备阶段 -初始化阶段,创建一个表,并插入几行数据: +在准备数据阶段,创建一张表,并插入若干行数据: ```sql create table t (c int); From 1f5b6ac2ea8c4ec10a4081ebda60a4d0b8a7c115 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:19:40 +0800 Subject: [PATCH 32/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index fb8f9c04ce33..8bb3df8013c0 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -39,7 +39,7 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 本节通过多个示例介绍 `AS OF TIMESTAMP` 语法的不同使用方法。在本节中,先准备用于恢复的数据,再分别展示如何通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP`、`SET TRANSACTION READ ONLY AS OF TIMESTAMP` 以及在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`。 -### 准备阶段 +### 准备数据 在准备数据阶段,创建一张表,并插入若干行数据: From bf2d73033fdcbd3bac5095ba674b967d41b65708 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:19:57 +0800 Subject: [PATCH 33/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 8bb3df8013c0..328ac7bf531d 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -172,7 +172,7 @@ select * from t; > **注意:** > -> 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启的事务将会是一个只读事务。假如在该事务中执行写入操作,将会被该事务拒绝。 +> 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 开启的事务为只读事务。假如在该事务中执行写入操作,操作将会被该事务拒绝。 ### 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 From baddd7cda87cf0f8fda67b9461cc5108508fe5d3 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:20:23 +0800 Subject: [PATCH 34/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 328ac7bf531d..f9d95c2fde5d 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -118,7 +118,7 @@ select * from t; 3 rows in set (0.00 sec) ``` -### 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 +### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启一个基于历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 From efc245a0d49899f405e233c6938c24ae3d7a2ca6 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:20:34 +0800 Subject: [PATCH 35/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index f9d95c2fde5d..c7acde662501 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -120,7 +120,7 @@ select * from t; ### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 -通过 START TRANSACTION READ ONLY AS OF TIMESTAMP 开启一个基于历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 +通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 语句开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 ```sql start transaction read only as of timestamp '2021-05-26 16:45:26'; From f352558e6af09ce763809681dd3c463c095c223d Mon Sep 17 00:00:00 2001 From: ShuNing Date: Fri, 11 Jun 2021 18:20:45 +0800 Subject: [PATCH 36/57] Update as-of-timestamp.md Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index c7acde662501..cb262001c3ec 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -174,7 +174,7 @@ select * from t; > > 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 开启的事务为只读事务。假如在该事务中执行写入操作,操作将会被该事务拒绝。 -### 通过 SET TRANSACTION READ ONLY AS OF TIMESTAMP 读取历史数据 +### 通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 表示下一个事务是基于指定历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 From 9158919f251bed1482a801e8d72c38eed92e57a6 Mon Sep 17 00:00:00 2001 From: TomShawn <41534398+TomShawn@users.noreply.github.com> Date: Fri, 11 Jun 2021 19:11:22 +0800 Subject: [PATCH 37/57] Update read-historical-data.md --- read-historical-data.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/read-historical-data.md b/read-historical-data.md index eadc4e00a137..9bb244de5bef 100644 --- a/read-historical-data.md +++ b/read-historical-data.md @@ -3,7 +3,7 @@ title: 通过系统变量 tidb_snapshot 读取历史数据 aliases: ['/docs-cn/dev/read-historical-data/','/docs-cn/dev/how-to/get-started/read-historical-data/'] --- -# 读取历史数据 +# 通过系统变量 tidb_snapshot 读取历史数据 本文档介绍 TiDB 如何读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 From 21c7f851be1a2c7d243fe1837b6b907cebf042ad Mon Sep 17 00:00:00 2001 From: TomShawn <41534398+TomShawn@users.noreply.github.com> Date: Fri, 11 Jun 2021 19:26:00 +0800 Subject: [PATCH 38/57] Apply suggestions from code review --- as-of-timestamp.md | 1 - stale-read.md | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index cb262001c3ec..ea2d00adaca2 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -7,7 +7,6 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 - TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的形式读取历史数据,无需特殊的服务器或者驱动器。当数据被更新、删除后,你可以通过 SQL 接口将更新或删除前的数据读取出来。 > **注意:** diff --git a/stale-read.md b/stale-read.md index 4a6601ec10da..32225450a0fb 100644 --- a/stale-read.md +++ b/stale-read.md @@ -13,13 +13,13 @@ summary: 介绍 Stale Read 功能和使用场景。 + 场景一:如果一个事务仅涉及只读操作,并且一定程度上可容忍牺牲实时性,你可以使用 Stale Read 功能来读取历史数据。由于牺牲了一定的实时性,使用 Stale Read 后,TiDB 可将请求发送到对应数据的任意一个副本,使得查询的执行获得更大的吞吐量。 -+ 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 ++ 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升查询整体的吞吐能力,从而显著提升查询性能。 -+ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性读,数据请求的源头可能与数据实际所在中心不一致,从而产生跨数据中心读取数据的情况,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,每个数据请求可就近访问对应数据所在当前中心的副本,从而避免跨数据中心读,降低整体查询的访问延迟。 ++ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性读,数据请求的源头可能与实际的数据中心不一致,从而产生跨数据中心读取数据的情况,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,每个数据请求可就近访问对应数据所在当前中心的副本,从而避免跨数据中心读,降低整体查询的访问延迟。 ## 使用方法 TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: -- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 -- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 +- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 文档的“语法方式”部分](/as-of-timestamp.md#语法方式)。 +- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 文档的“语法方式”部分](/as-of-timestamp.md#语法方式)有关 `TIDB_BOUNDED_STALENESS` 函数的介绍。 From 559162ed2fff3986326d98c4a4dd42827b1f6f61 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 11 Jun 2021 19:45:33 +0800 Subject: [PATCH 39/57] address Signed-off-by: nolouch --- as-of-timestamp.md | 5 ++--- stale-read.md | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index ea2d00adaca2..d84e98740050 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -7,6 +7,7 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 + TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的形式读取历史数据,无需特殊的服务器或者驱动器。当数据被更新、删除后,你可以通过 SQL 接口将更新或删除前的数据读取出来。 > **注意:** @@ -30,9 +31,7 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS('2016-10-08 16:45:26', '2016-10-08 16:45:29')` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒到 29 秒的时间范围内尽可能新的数据。 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS(NOW() - INTERVAL 20 SECOND, NOW())` 表示读取 20 秒前到现在的时间范围内尽可能新的数据。 -## 历史数据的保留和恢复策略 - -通过 Stale Read 方法读取的历史数据所采用的保留和恢复策略同使用 `tidb_snapshot` 系统变量读取的历史数据,详见[通过系统变量 `tidb_snapshot` 读取历史数据 - 历史数据保留策略](/read-historical-data.md#历史数据保留策略)和[通过系统变量 `tidb_snapshot` 读取历史数据 - 历史数据恢复策略](/read-historical-data.md#历史数据恢复策略)。 +注意: 除了指定时间戳,最常用使用的方式是读几秒前的数据,采用这种方式取值推荐读 5 秒以上的历史数据。 ## 示例 diff --git a/stale-read.md b/stale-read.md index 32225450a0fb..60f300a4ed01 100644 --- a/stale-read.md +++ b/stale-read.md @@ -5,7 +5,7 @@ summary: 介绍 Stale Read 功能和使用场景。 # Stale Read 功能的使用场景 -本文档介绍 Stale Read 的使用场景。Stale Read 是 TiDB 用户快速读取数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取一定程度上的历史数据。 +本文档介绍 Stale Read 的使用场景。由于 TiDB 数据是多版本存储的, Stale Read 能为用户提供了一种读取历史数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取对应的历史数据,从而避免数据同步带来延迟。 在内部实现上,TiDB 通过 Stale Read 可以从任意一个副本上读取到该指定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 @@ -13,13 +13,13 @@ summary: 介绍 Stale Read 功能和使用场景。 + 场景一:如果一个事务仅涉及只读操作,并且一定程度上可容忍牺牲实时性,你可以使用 Stale Read 功能来读取历史数据。由于牺牲了一定的实时性,使用 Stale Read 后,TiDB 可将请求发送到对应数据的任意一个副本,使得查询的执行获得更大的吞吐量。 -+ 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升查询整体的吞吐能力,从而显著提升查询性能。 ++ 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 -+ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性读,数据请求的源头可能与实际的数据中心不一致,从而产生跨数据中心读取数据的情况,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,每个数据请求可就近访问对应数据所在当前中心的副本,从而避免跨数据中心读,降低整体查询的访问延迟。 ++ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性读,数据请求的源头可能与数据实际所在中心不一致,从而产生跨数据中心读取数据的情况,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,每个数据请求可就近访问对应数据所在当前中心的副本,从而避免跨数据中心读,降低整体查询的访问延迟。 ## 使用方法 TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: -- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 文档的“语法方式”部分](/as-of-timestamp.md#语法方式)。 -- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 文档的“语法方式”部分](/as-of-timestamp.md#语法方式)有关 `TIDB_BOUNDED_STALENESS` 函数的介绍。 +- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 +- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 From 4fd6e558155d9d7f048d9c3734f0ba7775ff6849 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 11 Jun 2021 19:48:00 +0800 Subject: [PATCH 40/57] remove line Signed-off-by: nolouch --- as-of-timestamp.md | 1 - 1 file changed, 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index d84e98740050..ff00df2bd4c8 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -7,7 +7,6 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 - TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的形式读取历史数据,无需特殊的服务器或者驱动器。当数据被更新、删除后,你可以通过 SQL 接口将更新或删除前的数据读取出来。 > **注意:** From b842a92344e5700c8758f27ecf9c78f02b4d5f12 Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 11 Jun 2021 19:56:50 +0800 Subject: [PATCH 41/57] refine Signed-off-by: nolouch --- stale-read.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/stale-read.md b/stale-read.md index 60f300a4ed01..263795cb04a4 100644 --- a/stale-read.md +++ b/stale-read.md @@ -15,11 +15,12 @@ summary: 介绍 Stale Read 功能和使用场景。 + 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 -+ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性读,数据请求的源头可能与数据实际所在中心不一致,从而产生跨数据中心读取数据的情况,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,每个数据请求可就近访问对应数据所在当前中心的副本,从而避免跨数据中心读,降低整体查询的访问延迟。 ++ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性的 Follower 读,为了读到的数据与 Leader 上的数据一致,会产生跨数据中心获取 Readindex 来校验的请求,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,可以牺牲一定的实时性,可就近访问对应数据所在当前中心的副本,避免跨数据中心的网络延迟,降低整体查询的访问延迟。 ## 使用方法 TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: -- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别,但可能读到旧数据。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 -- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别,但可能读到旧数据。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 +- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 +- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别。在指定时间范围内,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间错之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。 +。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 From c504dd98b3c2ed9e4f80fc56ebf3042a2125751e Mon Sep 17 00:00:00 2001 From: nolouch Date: Fri, 11 Jun 2021 20:30:14 +0800 Subject: [PATCH 42/57] update select Signed-off-by: nolouch --- as-of-timestamp.md | 26 ++++++++++++++++++++++++-- sql-statements/sql-statement-select.md | 8 +++++++- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index ff00df2bd4c8..11d15bddb93d 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -17,9 +17,10 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 你可以通过以下三种方式使用 `AS OF TIMESTAMP` 语法: +- [在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`](/sql-statements/Sql-statement-select.md) - [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) - [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) -- 在 `SELECT` 的子句中使用 `AS OF TIMESTAMP` + 如果你指定的是精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 @@ -34,7 +35,7 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 ## 示例 -本节通过多个示例介绍 `AS OF TIMESTAMP` 语法的不同使用方法。在本节中,先准备用于恢复的数据,再分别展示如何通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP`、`SET TRANSACTION READ ONLY AS OF TIMESTAMP` 以及在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`。 +本节通过多个示例介绍 `AS OF TIMESTAMP` 语法的不同使用方法。在本节中,先准备用于恢复的数据,再分别展示如何通过 `SELECT` `START TRANSACTION READ ONLY AS OF TIMESTAMP`、`SET TRANSACTION READ ONLY AS OF TIMESTAMP` 以及在的子句中使用 `AS OF TIMESTAMP`。 ### 准备数据 @@ -115,6 +116,27 @@ select * from t; 3 rows in set (0.00 sec) ``` +## 通过 `SELECT` 读取历史数据 + +通过 `SELECT ... FROM ... AS OF TIMESTAMP EXPRESSION` 语句读取一个基于历史时间的数据。 + +```sql +select * from t as of timestamp '2021-05-26 16:45:26'; +``` + +``` ++------+ +| c | ++------+ +| 1 | +| 2 | +| 3 | ++------+ +3 rows in set (0.00 sec) +``` +> **注意:** +> +> 通过 `SELECT` 读取多个表时要保证 TIMESTAMP EXPRESSION 是一致的。 比如: `select * from t as of timestamp NOW() - INTERVAL 2 SECOND, c as of timestamp NOW() - INTERVAL 2 SECOND;`. 相关 table 的 as of 必须要指定,不指定会视为读最新的数据。 ### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 语句开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 diff --git a/sql-statements/sql-statement-select.md b/sql-statements/sql-statement-select.md index 69934393659a..47f14785e506 100644 --- a/sql-statements/sql-statement-select.md +++ b/sql-statements/sql-statement-select.md @@ -32,7 +32,13 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-select/','/docs-cn/dev/refe **TableRefsClause:** -![TableRefsClause](/media/sqlgram/TableRefsClause.png) +```ebnf+diagram +TableRefsClause ::= + (TableRef (AsOfClause)? ) ( ',' TableRef (AsOfClause)? ))* + +AsOfClause ::= + ( 'AS' 'OF' 'TIMESTAMP' Expression) +``` **WhereClauseOptional:** From 75605f79971fbabb6d40341fd31bf8c8cbba4b51 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 14 Jun 2021 23:30:18 +0800 Subject: [PATCH 43/57] address Signed-off-by: nolouch --- as-of-timestamp.md | 4 ++-- sql-statements/sql-statement-select.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 11d15bddb93d..9152be3ff69a 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -17,7 +17,7 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 你可以通过以下三种方式使用 `AS OF TIMESTAMP` 语法: -- [在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`](/sql-statements/Sql-statement-select.md) +- [在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`](/sql-statements/sql-statement-select.md) - [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) - [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) @@ -118,7 +118,7 @@ select * from t; ## 通过 `SELECT` 读取历史数据 -通过 `SELECT ... FROM ... AS OF TIMESTAMP EXPRESSION` 语句读取一个基于历史时间的数据。 +通过 `SELECT ... FROM ... AS OF TIMESTAMP` 语句读取一个基于历史时间的数据。 ```sql select * from t as of timestamp '2021-05-26 16:45:26'; diff --git a/sql-statements/sql-statement-select.md b/sql-statements/sql-statement-select.md index 47f14785e506..260aa4557d20 100644 --- a/sql-statements/sql-statement-select.md +++ b/sql-statements/sql-statement-select.md @@ -34,7 +34,7 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-select/','/docs-cn/dev/refe ```ebnf+diagram TableRefsClause ::= - (TableRef (AsOfClause)? ) ( ',' TableRef (AsOfClause)? ))* + ((TableRef (AsOfClause)? ) ( ',' TableRef (AsOfClause)? ))* AsOfClause ::= ( 'AS' 'OF' 'TIMESTAMP' Expression) From e769ecaebecd8d6ea0272f5f5e29bb7badccb12f Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 14 Jun 2021 23:37:05 +0800 Subject: [PATCH 44/57] fix the tableRefsClause Signed-off-by: nolouch --- sql-statements/sql-statement-select.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql-statements/sql-statement-select.md b/sql-statements/sql-statement-select.md index 260aa4557d20..1fca3c57587c 100644 --- a/sql-statements/sql-statement-select.md +++ b/sql-statements/sql-statement-select.md @@ -34,7 +34,7 @@ aliases: ['/docs-cn/dev/sql-statements/sql-statement-select/','/docs-cn/dev/refe ```ebnf+diagram TableRefsClause ::= - ((TableRef (AsOfClause)? ) ( ',' TableRef (AsOfClause)? ))* + (TableRef (AsOfClause)? ) (( ',' TableRef (AsOfClause)? ))* AsOfClause ::= ( 'AS' 'OF' 'TIMESTAMP' Expression) From de996cba4e082cda0e8780f105ca971923b659bf Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 14 Jun 2021 23:42:56 +0800 Subject: [PATCH 45/57] address linter Signed-off-by: nolouch --- as-of-timestamp.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 9152be3ff69a..3b58c91e61a0 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -21,7 +21,6 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 - [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) - [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) - 如果你指定的是精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 如果你指定的是时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: @@ -134,13 +133,16 @@ select * from t as of timestamp '2021-05-26 16:45:26'; +------+ 3 rows in set (0.00 sec) ``` + > **注意:** > > 通过 `SELECT` 读取多个表时要保证 TIMESTAMP EXPRESSION 是一致的。 比如: `select * from t as of timestamp NOW() - INTERVAL 2 SECOND, c as of timestamp NOW() - INTERVAL 2 SECOND;`. 相关 table 的 as of 必须要指定,不指定会视为读最新的数据。 + ### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 语句开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 + ```sql start transaction read only as of timestamp '2021-05-26 16:45:26'; ``` From d76fc54b5bbfd510c6e6be63e388053e89c8e3d0 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:44:32 +0800 Subject: [PATCH 46/57] Update as-of-timestamp.md Co-authored-by: Grace Cai --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 3b58c91e61a0..7a734fe1b9f6 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -7,7 +7,7 @@ summary: 了解如何使用 AS OF TIMESTAMP 语法读取历史数据。 本文档介绍如何通过 `AS OF TIMESTAMP` 语句使用 [Stale Read](/stale-read.md) 功能来读取 TiDB 历史版本数据,包括具体的操作示例以及历史数据的保存策略。 -TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的形式读取历史数据,无需特殊的服务器或者驱动器。当数据被更新、删除后,你可以通过 SQL 接口将更新或删除前的数据读取出来。 +TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的形式读取历史数据,无需特殊的服务器或者驱动器。当数据被更新或删除后,你可以通过 SQL 接口将更新或删除前的数据读取出来。 > **注意:** > From b6f57fbe4c8a048167fbd13cd124e231a4c17411 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:45:17 +0800 Subject: [PATCH 47/57] Update as-of-timestamp.md Co-authored-by: Grace Cai --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 7a734fe1b9f6..9af41ce25740 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -21,7 +21,7 @@ TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的 - [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) - [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) -如果你指定的是精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 +如果你想要指定一个精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 如果你指定的是时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: From 8e3f8ef32629ca614c5569c983070f300fe52cf7 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:50:16 +0800 Subject: [PATCH 48/57] Update as-of-timestamp.md Co-authored-by: Grace Cai --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 9af41ce25740..cec460f8dca5 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -34,7 +34,7 @@ TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的 ## 示例 -本节通过多个示例介绍 `AS OF TIMESTAMP` 语法的不同使用方法。在本节中,先准备用于恢复的数据,再分别展示如何通过 `SELECT` `START TRANSACTION READ ONLY AS OF TIMESTAMP`、`SET TRANSACTION READ ONLY AS OF TIMESTAMP` 以及在的子句中使用 `AS OF TIMESTAMP`。 +本节通过多个示例介绍 `AS OF TIMESTAMP` 语法的不同使用方法。在本节中,先介绍如何准备用于恢复的数据,再分别展示如何通过 `SELECT`、`START TRANSACTION READ ONLY AS OF TIMESTAMP`、`SET TRANSACTION READ ONLY AS OF TIMESTAMP` 以及 `SELECT` 子句使用 `AS OF TIMESTAMP`。 ### 准备数据 From 8bfcc032bc9f9dd5def74ef6eabd9e35eb0ea034 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:51:00 +0800 Subject: [PATCH 49/57] Update as-of-timestamp.md Co-authored-by: Grace Cai --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index cec460f8dca5..56d20cc491b2 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -136,7 +136,7 @@ select * from t as of timestamp '2021-05-26 16:45:26'; > **注意:** > -> 通过 `SELECT` 读取多个表时要保证 TIMESTAMP EXPRESSION 是一致的。 比如: `select * from t as of timestamp NOW() - INTERVAL 2 SECOND, c as of timestamp NOW() - INTERVAL 2 SECOND;`. 相关 table 的 as of 必须要指定,不指定会视为读最新的数据。 +> 通过 `SELECT` 语句读取多个表时要保证 TIMESTAMP EXPRESSION 是一致的。 比如: `select * from t as of timestamp NOW() - INTERVAL 2 SECOND, c as of timestamp NOW() - INTERVAL 2 SECOND;`。此外,在 `SELECT` 语句中,你必须要指定相关数据表的 as of 信息,若不指定,`SELECT` 语句会默认读最新的数据。 ### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 From 7655d8ef06f265aabbee7d9b86a8d979ff7ff3e6 Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:52:39 +0800 Subject: [PATCH 50/57] Update stale-read.md Co-authored-by: Grace Cai --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index 263795cb04a4..18b12c5da05e 100644 --- a/stale-read.md +++ b/stale-read.md @@ -5,7 +5,7 @@ summary: 介绍 Stale Read 功能和使用场景。 # Stale Read 功能的使用场景 -本文档介绍 Stale Read 的使用场景。由于 TiDB 数据是多版本存储的, Stale Read 能为用户提供了一种读取历史数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取对应的历史数据,从而避免数据同步带来延迟。 +本文档介绍 Stale Read 的使用场景。由于 TiDB 数据是多版本存储的,Stale Read 能为用户提供了一种读取历史数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取对应的历史数据,从而避免数据同步带来延迟。 在内部实现上,TiDB 通过 Stale Read 可以从任意一个副本上读取到该指定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 From 7d57426a7ff16f3860122afa78c6dec49a200b01 Mon Sep 17 00:00:00 2001 From: nolouch Date: Mon, 14 Jun 2021 23:53:10 +0800 Subject: [PATCH 51/57] address Signed-off-by: nolouch --- TOC.md | 4 ++-- as-of-timestamp.md | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/TOC.md b/TOC.md index 6a27cb896658..f5573f0ca8c8 100644 --- a/TOC.md +++ b/TOC.md @@ -63,10 +63,10 @@ + [外部存储](/br/backup-and-restore-storages.md) + [BR 常见问题](/br/backup-and-restore-faq.md) + 读取历史数据 - + 通过 Stale Read 功能读取历史数据 + + 使用 Stale Read 功能读取历史数据(推荐) + [Stale Read 使用场景介绍](/stale-read.md) + [使用 `AS OF TIMESTAMP` 语法读取历史数据](/as-of-timestamp.md) - + [通过系统变量 `tidb_snapshot` 读取历史数据](/read-historical-data.md) + + [使用系统变量 `tidb_snapshot` 读取历史数据](/read-historical-data.md) + [修改时区](/configure-time-zone.md) + [日常巡检](/daily-check.md) + [TiFlash 常用运维操作](/tiflash/maintain-tiflash.md) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 3b58c91e61a0..2a6cb2a518f0 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -23,14 +23,14 @@ TiDB 实现了通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法 如果你指定的是精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 -如果你指定的是时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: +如果你想要在一个时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。使用该函数,,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: - `AS OF TIMESTAMP '2016-10-08 16:45:26'` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒时最新的数据。 - `AS OF TIMESTAMP NOW() - INTERVAL 10 SECOND` 表示读取 10 秒前最新的数据。 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS('2016-10-08 16:45:26', '2016-10-08 16:45:29')` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒到 29 秒的时间范围内尽可能新的数据。 - `AS OF TIMESTAMP TIDB_BOUNDED_STALENESS(NOW() - INTERVAL 20 SECOND, NOW())` 表示读取 20 秒前到现在的时间范围内尽可能新的数据。 -注意: 除了指定时间戳,最常用使用的方式是读几秒前的数据,采用这种方式取值推荐读 5 秒以上的历史数据。 +注意: 除了指定时间戳,`AS OF TIMESTAMP` 语法最常用使用的方式是读几秒前的数据。如果采用这种方式,取值范围推荐为读 5 秒以上的历史数据。 ## 示例 @@ -115,7 +115,7 @@ select * from t; 3 rows in set (0.00 sec) ``` -## 通过 `SELECT` 读取历史数据 +### 通过 `SELECT` 读取历史数据 通过 `SELECT ... FROM ... AS OF TIMESTAMP` 语句读取一个基于历史时间的数据。 @@ -140,7 +140,7 @@ select * from t as of timestamp '2021-05-26 16:45:26'; ### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 -通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 语句开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 +通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 语句,你可以开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 ```sql @@ -197,7 +197,7 @@ select * from t; ### 通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 -通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 表示下一个事务是基于指定历史时间的只读事务,该事务将会基于所提供的历史时间来读取历史数据。 +通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 语句,你可以将下一个事务设置为基于指定历史时间的只读事务。该事务将会基于所提供的历史时间来读取历史数据。 ```sql set transaction read only as of timestamp '2021-05-26 16:45:26'; From b7e6c94054fd6bde3c8b0a10ba047c704459659b Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:53:28 +0800 Subject: [PATCH 52/57] Update stale-read.md Co-authored-by: Grace Cai --- stale-read.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stale-read.md b/stale-read.md index 18b12c5da05e..47ab31b302e7 100644 --- a/stale-read.md +++ b/stale-read.md @@ -21,6 +21,6 @@ summary: 介绍 Stale Read 功能和使用场景。 TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: -- 指定精确时间点:你可以通过指定一个时间戳,确保读到该指定时间点下保证全局事务记录一致性的数据,不破坏隔离级别。要使用该方法,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 +- 指定精确时间点:如需 TiDB 读取一个时间点上保证全局事务记录一致性的数据并且不破坏隔离级别,你可以指定这个时间点对应的时间戳。要使用该方式,请参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 - 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别。在指定时间范围内,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间错之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。 。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 From 2d9a83092af5450fc65c160c5ce5a0496ad08d2b Mon Sep 17 00:00:00 2001 From: ShuNing Date: Mon, 14 Jun 2021 23:54:32 +0800 Subject: [PATCH 53/57] Update stale-read.md Co-authored-by: Grace Cai --- stale-read.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stale-read.md b/stale-read.md index 47ab31b302e7..7815219c9a20 100644 --- a/stale-read.md +++ b/stale-read.md @@ -22,5 +22,4 @@ summary: 介绍 Stale Read 功能和使用场景。 TiDB 提供两种 Stale Read 使用方式,分别是指定一个精确的时间点和一个时间范围: - 指定精确时间点:如需 TiDB 读取一个时间点上保证全局事务记录一致性的数据并且不破坏隔离级别,你可以指定这个时间点对应的时间戳。要使用该方式,请参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档。 -- 指定时间范围:你可以通过指定一个时间范围,确保读到在该时间范围内尽可能新的数据,不破坏隔离级别。在指定时间范围内,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间错之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。 -。要使用该功能,参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 +- 指定时间范围:如需 TiDB 读取在一个时间范围内尽可能新的数据并不破坏隔离级别,你可以指定一个时间范围。在指定时间范围内,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证在所访问的可用副本上可执行读取操作而且不会被阻塞。 要使用该方式,请参阅 [`AS OF TIMESTAMP` 语法](/as-of-timestamp.md#语法方式)文档和该文档中 [`TIDB_BOUNDED_STALENESS` 函数](/as-of-timestamp.md#语法方式)部分的介绍。 From 757242bd99e0605c271a4d14c2216e1536fe8f7f Mon Sep 17 00:00:00 2001 From: nolouch Date: Tue, 15 Jun 2021 00:38:24 +0800 Subject: [PATCH 54/57] address Signed-off-by: nolouch --- as-of-timestamp.md | 30 +++++------------------------- 1 file changed, 5 insertions(+), 25 deletions(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 1f9cee42b48c..5c0d90af2fb2 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -17,13 +17,13 @@ TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的 你可以通过以下三种方式使用 `AS OF TIMESTAMP` 语法: -- [在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`](/sql-statements/sql-statement-select.md) +- [ `SELECT ... FROM ... AS OF TIMESTAMP`](/sql-statements/sql-statement-select.md) - [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) - [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) 如果你想要指定一个精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。 -如果你想要在一个时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。使用该函数,,TiDB 会选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: +如果你想要指定一个时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。使用该函数,TiDB 会在指定的时间范围内选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数,示例如下: - `AS OF TIMESTAMP '2016-10-08 16:45:26'` 表示读取在 2016 年 10 月 8 日 16 点 45 分 26 秒时最新的数据。 - `AS OF TIMESTAMP NOW() - INTERVAL 10 SECOND` 表示读取 10 秒前最新的数据。 @@ -117,7 +117,7 @@ select * from t; ### 通过 `SELECT` 读取历史数据 -通过 `SELECT ... FROM ... AS OF TIMESTAMP` 语句读取一个基于历史时间的数据。 +通过 [`SELECT ... FROM ... AS OF TIMESTAMP`](/sql-statements/sql-statement-select.md) 语句读取一个基于历史时间的数据。 ```sql select * from t as of timestamp '2021-05-26 16:45:26'; @@ -140,8 +140,7 @@ select * from t as of timestamp '2021-05-26 16:45:26'; ### 通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 -通过 `START TRANSACTION READ ONLY AS OF TIMESTAMP` 语句,你可以开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 - +通过 [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) 语句,你可以开启一个基于历史时间的只读事务,该事务基于所提供的历史时间来读取历史数据。 ```sql start transaction read only as of timestamp '2021-05-26 16:45:26'; @@ -197,7 +196,7 @@ select * from t; ### 通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 读取历史数据 -通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 语句,你可以将下一个事务设置为基于指定历史时间的只读事务。该事务将会基于所提供的历史时间来读取历史数据。 +通过 [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) 语句,你可以将下一个事务设置为基于指定历史时间的只读事务。该事务将会基于所提供的历史时间来读取历史数据。 ```sql set transaction read only as of timestamp '2021-05-26 16:45:26'; @@ -258,22 +257,3 @@ select * from t; > **注意:** > > 通过 `SET TRANSACTION READ ONLY AS OF TIMESTAMP` 开启的事务为只读事务。假如在该事务中执行写入操作,操作将会被该事务拒绝。 - -### 通过 `SELECT` 子句中使用 `AS OF TIMESTAMP` 读取历史数据 - -若查询语句需要基于历史时间进行数据查询,你可以在 `SELECT` 的子句中使用 `AS OF TIMESTAMP`: - -```sql -select * from t as of timestamp '2021-05-26 16:45:26'; -``` - -``` -+------+ -| c | -+------+ -| 1 | -| 2 | -| 3 | -+------+ -3 rows in set (0.00 sec) -``` From e8405e766a674f81cf5f1600b28e4006d8d511df Mon Sep 17 00:00:00 2001 From: nolouch Date: Tue, 15 Jun 2021 00:39:58 +0800 Subject: [PATCH 55/57] fix Signed-off-by: nolouch --- as-of-timestamp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 5c0d90af2fb2..6644979bc509 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -17,7 +17,7 @@ TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的 你可以通过以下三种方式使用 `AS OF TIMESTAMP` 语法: -- [ `SELECT ... FROM ... AS OF TIMESTAMP`](/sql-statements/sql-statement-select.md) +- [`SELECT ... FROM ... AS OF TIMESTAMP`](/sql-statements/sql-statement-select.md) - [`START TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-start-transaction.md) - [`SET TRANSACTION READ ONLY AS OF TIMESTAMP`](/sql-statements/sql-statement-set-transaction.md) From 8a103c0419cb373868e8869e09ec66d742111bf7 Mon Sep 17 00:00:00 2001 From: yisaer Date: Tue, 15 Jun 2021 14:58:08 +0800 Subject: [PATCH 56/57] add local read Signed-off-by: yisaer add local read Signed-off-by: yisaer --- TOC.md | 1 + best-practices/three-dc-local-read.md | 25 +++++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 best-practices/three-dc-local-read.md diff --git a/TOC.md b/TOC.md index f5573f0ca8c8..15d4180b46e1 100644 --- a/TOC.md +++ b/TOC.md @@ -145,6 +145,7 @@ + [PD 调度策略最佳实践](/best-practices/pd-scheduling-best-practices.md) + [海量 Region 集群调优](/best-practices/massive-regions-best-practices.md) + [三节点混合部署最佳实践](/best-practices/three-nodes-hybrid-deployment.md) + + [在三数据中心下就近读取数据](/best-practices/three-dc-local-read.md) + [Placement Rules 使用文档](/configure-placement-rules.md) + [Load Base Split 使用文档](/configure-load-base-split.md) + [Store Limit 使用文档](/configure-store-limit.md) diff --git a/best-practices/three-dc-local-read.md b/best-practices/three-dc-local-read.md new file mode 100644 index 000000000000..261592a836f9 --- /dev/null +++ b/best-practices/three-dc-local-read.md @@ -0,0 +1,25 @@ +--- +title: 在三数据中心下就近读取数据 +summary: 了解通过 Stale Read 功能在三数据中心下减少跨数据中心请求 +--- + +# 在三数据中心下就近读取数据 + +在三数据中心模式下,Region 的三个副本都会隔离在各个数据中心里。然而在强一致读的要求下,tidb 的每一个查询都需要访问对应数据的 Leader 副本,而查询的来源可能和 Leader 所在的数据中心不一致,这就会引起跨数据中心的数据访问,从而造成访问的延迟上升。本文主要介绍使用 [Stale Read](/stale-read.md) 功能,以牺牲数据实时性的方式,避免跨数据中心的访问,从而降低访问的延迟。 + +## 部署三数据中心的 TiDB 集群 + +如何部署三数据中心,参考[同城多数据中心部署 TiDB](/multi-data-centers-in-one-city-deployment.md) + +TiKV 和 TiDB 都有 `labels` 配置项,在给 TiKV 和 TiDB 配置标签时,对同一个数据中心下的 TiKV 和 TiDB 需要配置相同的 `zone` 标签。假如 TiKV 和 TiDB 都在对应 `dc-1` 数据中心下,那么两者都需要配置如下标签: + +``` +[labels] +zone=dc-1 +``` + +## 使用 Stale Read 就近读取数据 + +当 TiDB 收到 Stale Read 查询时,假如对应的 TiDB 配置了 `zone` 标签,就会将请求发送到对应数据副本所在 TiKV 拥有相同的 `zone` 标签的节点上。 + +如何使用 Stale Read 查询,参考[使用 AS OF TIMESTAMP 语法读取历史数据](/as-of-timestamp.md) From 84ddbea54b5f6b6f0174ec908467109069070446 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Tue, 15 Jun 2021 15:55:20 +0800 Subject: [PATCH 57/57] Apply suggestions from code review Co-authored-by: TomShawn <41534398+TomShawn@users.noreply.github.com> --- best-practices/three-dc-local-read.md | 10 ++++++---- read-historical-data.md | 6 +++++- stale-read.md | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/best-practices/three-dc-local-read.md b/best-practices/three-dc-local-read.md index 261592a836f9..39866965dbbd 100644 --- a/best-practices/three-dc-local-read.md +++ b/best-practices/three-dc-local-read.md @@ -1,6 +1,6 @@ --- title: 在三数据中心下就近读取数据 -summary: 了解通过 Stale Read 功能在三数据中心下减少跨数据中心请求 +summary: 了解通过 Stale Read 功能在三数据中心下就近读取数据,减少跨数据中心请求。 --- # 在三数据中心下就近读取数据 @@ -9,9 +9,9 @@ summary: 了解通过 Stale Read 功能在三数据中心下减少跨数据中 ## 部署三数据中心的 TiDB 集群 -如何部署三数据中心,参考[同城多数据中心部署 TiDB](/multi-data-centers-in-one-city-deployment.md) +部署三数据中心的方法,参考[同城多数据中心部署 TiDB](/multi-data-centers-in-one-city-deployment.md)。 -TiKV 和 TiDB 都有 `labels` 配置项,在给 TiKV 和 TiDB 配置标签时,对同一个数据中心下的 TiKV 和 TiDB 需要配置相同的 `zone` 标签。假如 TiKV 和 TiDB 都在对应 `dc-1` 数据中心下,那么两者都需要配置如下标签: +请注意,如果 TiKV 和 TiDB 都有 `labels` 配置项,在给 TiKV 和 TiDB 配置标签时,同一个数据中心下的 TiKV 和 TiDB 应该配置相同的 `zone` 标签。假设 TiKV 和 TiDB 都在 `dc-1` 数据中心下,那么两者都需要配置如下标签: ``` [labels] @@ -20,6 +20,8 @@ zone=dc-1 ## 使用 Stale Read 就近读取数据 +[Stale Read](/stale-read.md) 为用户提供了一种读取历史数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取对应的历史数据,从而避免数据同步带来延迟。在部分跨数据中心部署的场景中使用 Stale Read 功能,通过牺牲一定的实时性,TiDB 可就近访问对应数据所在当前中心的副本,避免跨数据中心的网络延迟,降低整体查询的访问延迟。 + 当 TiDB 收到 Stale Read 查询时,假如对应的 TiDB 配置了 `zone` 标签,就会将请求发送到对应数据副本所在 TiKV 拥有相同的 `zone` 标签的节点上。 -如何使用 Stale Read 查询,参考[使用 AS OF TIMESTAMP 语法读取历史数据](/as-of-timestamp.md) +如何使用 Stale Read 查询,参考[使用 AS OF TIMESTAMP 语法读取历史数据](/as-of-timestamp.md)。 diff --git a/read-historical-data.md b/read-historical-data.md index 9bb244de5bef..031aff360ab6 100644 --- a/read-historical-data.md +++ b/read-historical-data.md @@ -5,7 +5,11 @@ aliases: ['/docs-cn/dev/read-historical-data/','/docs-cn/dev/how-to/get-started/ # 通过系统变量 tidb_snapshot 读取历史数据 -本文档介绍 TiDB 如何读取历史版本数据,包括具体的操作流程以及历史数据的保存策略。 +本文档介绍如何通过系统变量 `tidb_snapshot` 读取历史数据,包括具体的操作流程以及历史数据的保存策略。 + +> **注意:** +> +> 你还可以使用 [Stale Read](/stale-read.md) 功能读取历史数据。更推荐使用 Stale Read 读取历史数据。 ## 功能说明 diff --git a/stale-read.md b/stale-read.md index 7815219c9a20..0888a0a29ac3 100644 --- a/stale-read.md +++ b/stale-read.md @@ -5,7 +5,7 @@ summary: 介绍 Stale Read 功能和使用场景。 # Stale Read 功能的使用场景 -本文档介绍 Stale Read 的使用场景。由于 TiDB 数据是多版本存储的,Stale Read 能为用户提供了一种读取历史数据的一种机制。使用 Stale Read 功能,你能从指定时间点或时间范围内读取对应的历史数据,从而避免数据同步带来延迟。 +本文档介绍 Stale Read 的使用场景。Stale Read 是一种读取历史数据版本的机制,读取 TiDB 中存储的历史数据版本。使用 Stale Read 功能,你能从指定时间点或时间范围内读取对应的历史数据,从而避免数据同步带来延迟。 在内部实现上,TiDB 通过 Stale Read 可以从任意一个副本上读取到该指定时间点或时间范围内尽可能新的数据,并在这个过程中始终保证数据的一致性约束。 @@ -15,7 +15,7 @@ summary: 介绍 Stale Read 功能和使用场景。 + 场景二:在一些小表的查询场景中,如果使用了强一致性读,数据可能集中在某一个存储节点上,导致查询压力集中在该节点,成为整个查询的瓶颈。使用 Stale Read 功能后,TiDB 可以将请求分发到对应数据的每一个副本上,提升了查询整体的吞吐能力,从而显著提升查询性能。 -+ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性的 Follower 读,为了读到的数据与 Leader 上的数据一致,会产生跨数据中心获取 Readindex 来校验的请求,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,可以牺牲一定的实时性,可就近访问对应数据所在当前中心的副本,避免跨数据中心的网络延迟,降低整体查询的访问延迟。 ++ 场景三:在部分跨数据中心部署的场景中,如果使用了强一致性的 Follower 读,为了读到的数据与 Leader 上的数据一致,会产生跨数据中心获取 `Readindex` 来校验的请求,导致整体查询的访问延迟增加。通过使用 Stale Read 功能,可以牺牲一定的实时性,可就近访问对应数据所在当前中心的副本,避免跨数据中心的网络延迟,降低整体查询的访问延迟。详情参考[在三数据中心下就近读取数据](/best-practices/three-dc-local-read.md)。 ## 使用方法