diff --git a/as-of-timestamp.md b/as-of-timestamp.md index 33ba7d1a4611..e4c2a41e6787 100644 --- a/as-of-timestamp.md +++ b/as-of-timestamp.md @@ -23,7 +23,7 @@ TiDB 支持通过标准 SQL 接口,即通过 `AS OF TIMESTAMP` SQL 语法的 如果你想要指定一个精确的时间点,可在 `AS OF TIMESTAMP` 中使用日期时间和时间函数,日期时间的格式为:"2016-10-08 16:45:26.999",最小时间精度范围为毫秒,通常可只写到秒,例如 "2016-10-08 16:45:26"。你也可以通过 `NOW(3)` 函数获得精确到毫秒的当前时间。如果想读取几秒前的数据,推荐使用例如 `NOW() - INTERVAL 10 SECOND` 的表达式。(推荐) -如果你想要指定一个时间范围,需要使用 `TIDB_BOUNDED_STALENESS()` 函数。使用该函数,TiDB 会在指定的时间范围内选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数。 +如果你想要指定一个时间范围,需要使用 [`TIDB_BOUNDED_STALENESS()`](/functions-and-operators/tidb-functions.md#tidb_bounded_staleness) 函数。使用该函数,TiDB 会在指定的时间范围内选择一个合适的时间戳,该时间戳能保证所访问的副本上不存在开始于这个时间戳之前且还没有提交的相关事务,即能保证所访问的可用副本上执行读取操作而且不会被阻塞。用法为 `TIDB_BOUNDED_STALENESS(t1, t2)`,其中 `t1` 和 `t2` 为时间范围的两端,支持使用日期时间和时间函数。 示例如下: diff --git a/functions-and-operators/tidb-functions.md b/functions-and-operators/tidb-functions.md index 279e546f07d4..19cd4d4723a1 100644 --- a/functions-and-operators/tidb-functions.md +++ b/functions-and-operators/tidb-functions.md @@ -9,34 +9,146 @@ summary: 学习使用 TiDB 特有的函数。 | 函数名 | 函数说明 | | :-------------- | :------------------------------------- | -| `TIDB_BOUNDED_STALENESS()` | `TIDB_BOUNDED_STALENESS` 函数指示 TiDB 在指定时间范围内读取尽可能新的数据。参见[使用 AS OF TIMESTAMP 语法读取历史数据](/as-of-timestamp.md)。 | -| [`TIDB_DECODE_KEY(str)`](#tidb_decode_key) | `TIDB_DECODE_KEY` 函数用于将 TiDB 编码的键输入解码为包含 `_tidb_rowid` 和 `table_id` 的 JSON 结构。你可以在一些系统表和日志输出中找到 TiDB 的编码键。 | -| [`TIDB_DECODE_PLAN(str)`](#tidb_decode_plan) | `TIDB_DECODE_PLAN` 函数用于解码 TiDB 执行计划。 | -| `TIDB_IS_DDL_OWNER()` | `TIDB_IS_DDL_OWNER` 函数用于检查你连接的 TiDB 实例是否是 DDL Owner。DDL Owner 代表集群中所有其他节点执行 DDL 语句的 TiDB 实例。 | -| [`TIDB_PARSE_TSO(num)`](#tidb_parse_tso) | `TIDB_PARSE_TSO` 函数用于从 TiDB TSO 时间戳中提取物理时间戳。参见 [`tidb_current_ts`](/system-variables.md#tidb_current_ts)。 | -| `TIDB_PARSE_TSO_LOGICAL(num)` | `TIDB_PARSE_TSO_LOGICAL` 函数用于从 TiDB TSO 时间戳中提取逻辑时间戳。| -| [`TIDB_VERSION()`](#tidb_version) | `TIDB_VERSION` 函数用于获取当前连接的 TiDB 服务器版本和构建详细信息。 | -| [`TIDB_DECODE_SQL_DIGESTS(digests, stmtTruncateLength)`](#tidb_decode_sql_digests) | `TIDB_DECODE_SQL_DIGESTS` 函数用于在集群中查询一组 SQL Digest 所对应的 SQL 语句的归一化形式(即去除格式和参数后的形式)。 | -| `VITESS_HASH(str)` | `VITESS_HASH` 函数返回与 Vitess 的 `HASH` 函数兼容的字符串哈希值,有助于从 Vitess 迁移数据。 | -| `TIDB_SHARD()` | `TIDB_SHARD` 函数用于创建一个 SHARD INDEX 来打散热点索引。SHARD INDEX 是一种以 `TIDB_SHARD` 函数为前缀的表达式索引。 | -| `TIDB_ROW_CHECKSUM()` | `TIDB_ROW_CHECKSUM()` 函数用于查询行数据的 Checksum 值。该函数只能用于 FastPlan 流程的 `SELECT` 语句,即你可通过形如 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id = ?` 或 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id IN (?, ?, ...)` 的语句进行查询。参见[数据正确性校验](/ticdc/ticdc-integrity-check.md)。 | -| `CURRENT_RESOURCE_GROUP()` | `CURRENT_RESOURCE_GROUP()` 用于查询当前连接绑定的资源组名。参见[使用资源管控 (Resource Control) 实现资源隔离](/tidb-resource-control.md)。 | +| [`CURRENT_RESOURCE_GROUP()`](#current_resource_group) | 用于查询当前连接绑定的资源组名。参见[使用资源管控 (Resource Control) 实现资源隔离](/tidb-resource-control.md)。 | +| [`TIDB_BOUNDED_STALENESS()`](#tidb_bounded_staleness) | 指示 TiDB 在指定时间范围内读取尽可能新的数据。参见[使用 `AS OF TIMESTAMP` 语法读取历史数据](/as-of-timestamp.md)。 | +| [`TIDB_CURRENT_TSO()`](#tidb_current_tso) | 返回当前的 [TimeStamp Oracle (TSO)](/tso.md)。 | +| [`TIDB_DECODE_BINARY_PLAN()`](#tidb_decode_binary_plan) | 用于解码以二进制格式编码的执行计划。 | +| [`TIDB_DECODE_KEY()`](#tidb_decode_key) | 用于将 TiDB 编码的键输入解码为包含 `_tidb_rowid` 和 `table_id` 的 JSON 结构。一些系统表和日志输出中有 TiDB 编码的键。 | +| [`TIDB_DECODE_PLAN()`](#tidb_decode_plan) | 用于解码 TiDB 执行计划。 | +| [`TIDB_DECODE_SQL_DIGESTS()`](#tidb_decode_sql_digests) | 用于在集群中查询一组 SQL digest 所对应的 SQL 语句的归一化形式(即去除格式和参数后的形式)。 | +| [`TIDB_ENCODE_SQL_DIGEST()`](#tidb_encode_sql_digest) | 用于为查询字符串获取 digest。 | +| [`TIDB_IS_DDL_OWNER()`](#tidb_is_ddl_owner) | 用于检查你连接的 TiDB 实例是否是 DDL Owner。DDL Owner 是代表集群中所有其他节点执行 DDL 语句的 TiDB 实例。 | +| [`TIDB_PARSE_TSO()`](#tidb_parse_tso) | 用于从 TiDB TSO 时间戳中提取物理时间戳。参见 [`tidb_current_ts`](/system-variables.md#tidb_current_ts)。 | +| [`TIDB_PARSE_TSO_LOGICAL()`](#tidb_parse_tso_logical) | 用于从 TiDB TSO 时间戳中提取逻辑时间戳。| +| [`TIDB_ROW_CHECKSUM()`](#tidb_row_checksum) | 用于查询行数据的 Checksum 值。该函数只能用于 FastPlan 流程的 `SELECT` 语句,即你可通过类似 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id = ?` 或 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id IN (?, ?, ...)` 的语句进行查询。参见[数据正确性校验](/ticdc/ticdc-integrity-check.md)。 | +| [`TIDB_SHARD()`](#tidb_shard) | 用于创建一个 SHARD INDEX 来打散热点索引。SHARD INDEX 是一种以 `TIDB_SHARD` 函数为前缀的表达式索引。 | +| [`TIDB_VERSION()`](#tidb_version) | 用于获取当前连接的 TiDB 服务器的版本以及构建信息。 | +| [`VITESS_HASH()`](#vitess_hash) | 返回与 Vitess 的 `HASH` 函数兼容的数值的哈希值,有助于从 Vitess 迁移至 TiDB。 | + +## CURRENT_RESOURCE_GROUP + +`CURRENT_RESOURCE_GROUP()` 函数用于查询当前连接绑定的资源组名称。当开启[资源管控 (Resource Control)](/tidb-resource-control.md) 功能时,执行 SQL 语句对资源的占用会受到所绑定的资源组资源配置的限制。 -## 示例 +在会话建立时,TiDB 默认会将连接绑定至登录用户绑定的资源组,如果用户没有绑定任何资源组,则会将连接绑定至 `default` 资源组。在会话建立之后,绑定的资源组默认不会发生变化,即使执行了[修改用户绑定的资源组](/sql-statements/sql-statement-alter-user.md#修改用户绑定的资源组)。如需修改当前会话绑定的资源组,可以使用 [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) 语句。 -下面为部分以上函数的示例。 +示例: -### TIDB_DECODE_KEY +创建一个用户 `user1`,创建两个资源组 `rg1` 和 `rg2`,并将用户 `user1` 绑定资源组 `rg1`: -`TIDB_DECODE_KEY` 函数用于将 TiDB 编码的键输入解码为包含 `_tidb_rowid` 和 `table_id` 的 JSON 结构。你可以在一些系统表和日志输出中找到 TiDB 的编码键。 +```sql +CREATE USER 'user1'; +CREATE RESOURCE GROUP rg1 RU_PER_SEC = 1000; +CREATE RESOURCE GROUP rg2 RU_PER_SEC = 2000; +ALTER USER 'user1' RESOURCE GROUP `rg1`; +``` -以下示例中,表 `t1` 有一个隐藏的 `rowid`,该 `rowid` 由 TiDB 生成。语句中使用了 `TIDB_DECODE_KEY` 函数。结果显示,隐藏的 `rowid` 被解码后并输出,这是典型的非聚簇主键结果。 +使用 `user1` 登录,查看当前用户绑定的资源组: ```sql -SELECT START_KEY, TIDB_DECODE_KEY(START_KEY) FROM information_schema.tikv_region_status WHERE table_name='t1' AND REGION_ID=2\G +SELECT CURRENT_RESOURCE_GROUP(); +``` + +``` ++--------------------------+ +| CURRENT_RESOURCE_GROUP() | ++--------------------------+ +| rg1 | ++--------------------------+ +1 row in set (0.00 sec) +``` + +执行 `SET RESOURCE GROUP` 将当前会话的资源组设置为 `rg2`,然后查看当前用户绑定的资源组: + +```sql +SET RESOURCE GROUP `rg2`; +SELECT CURRENT_RESOURCE_GROUP(); +``` + +``` ++--------------------------+ +| CURRENT_RESOURCE_GROUP() | ++--------------------------+ +| rg2 | ++--------------------------+ +1 row in set (0.00 sec) +``` + +## TIDB_BOUNDED_STALENESS + +`TIDB_BOUNDED_STALENESS()` 函数用作 [`AS OF TIMESTAMP`](/as-of-timestamp.md) 语法的一部分。 + +## TIDB_CURRENT_TSO + +`TIDB_CURRENT_TSO()` 函数返回当前事务的 [TSO](/tso.md),类似于 [`tidb_current_ts`](/system-variables.md#tidb_current_ts) 变量。 + +```sql +BEGIN; +``` + +``` +Query OK, 0 rows affected (0.00 sec) +``` + +```sql +SELECT TIDB_CURRENT_TSO(); +``` + +``` ++--------------------+ +| TIDB_CURRENT_TSO() | ++--------------------+ +| 450456244814610433 | ++--------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT @@tidb_current_ts; +``` + +``` ++--------------------+ +| @@tidb_current_ts | ++--------------------+ +| 450456244814610433 | ++--------------------+ +1 row in set (0.00 sec) +``` + +## TIDB_DECODE_BINARY_PLAN + +`TIDB_DECODE_BINARY_PLAN(binary_plan)` 函数用于解码以二进制格式编码的执行计划,例如 [`STATEMENTS_SUMMARY`](/statement-summary-tables.md) 表中 `BINARY_PLAN` 列的计划。 + +必须将 [`tidb_generate_binary_plan`](/system-variables.md#tidb_generate_binary_plan-从-v620-版本开始引入) 变量设置为 `ON`,二进制计划才可用。 + +示例: + +```sql +SELECT BINARY_PLAN,TIDB_DECODE_BINARY_PLAN(BINARY_PLAN) FROM information_schema.STATEMENTS_SUMMARY LIMIT 1\G +``` + +``` +*************************** 1. row *************************** + BINARY_PLAN: lQLwPgqQAgoMUHJvamVjdGlvbl8zEngKDk1lbVRhYmxlU2Nhbl80KQAAAAAAiMNAMAM4AUABSioKKAoSaW5mb3JtYQU00HNjaGVtYRISU1RBVEVNRU5UU19TVU1NQVJZWhV0aW1lOjI5LjPCtXMsIGxvb3BzOjJw////CQIEAXgJCBD///8BIQFnDOCb+EA6cQCQUjlDb2x1bW4jOTIsIHRpZGJfZGVjb2RlX2JpbmFyeV9wbGFuKBUjCCktPg0MEDEwM1oWBYAIMTA4NoEAeGINQ29uY3VycmVuY3k6NXDIZXj///////////8BGAE= +TIDB_DECODE_BINARY_PLAN(BINARY_PLAN): +| id | estRows | estCost | actRows | task | access object | execution info | operator info | memory | disk | +| Projection_3 | 10000.00 | 100798.00 | 3 | root | | time:108.3µs, loops:2, Concurrency:5 | Column#92, tidb_decode_binary_plan(Column#92)->Column#103 | 12.7 KB | N/A | +| └─MemTableScan_4 | 10000.00 | 0.00 | 3 | root | table:STATEMENTS_SUMMARY | time:29.3µs, loops:2 | | N/A | N/A | + +1 row in set (0.00 sec) ``` +## TIDB_DECODE_KEY + +`TIDB_DECODE_KEY()` 函数用于将 TiDB 编码的键输入解码为包含 `_tidb_rowid` 和 `table_id` 的 JSON 结构。在一些系统表和日志输出中有 TiDB 编码的键。 + +以下示例中,表 `t1` 有一个隐藏的 `rowid`,该 `rowid` 由 TiDB 生成。语句中使用了 `TIDB_DECODE_KEY()` 函数。结果显示,隐藏的 `rowid` 被解码后并输出,这是典型的非聚簇主键结果。 + ```sql +SELECT START_KEY, TIDB_DECODE_KEY(START_KEY) FROM information_schema.tikv_region_status WHERE table_name='t1' AND REGION_ID=2\G +``` + +``` *************************** 1. row *************************** START_KEY: 7480000000000000FF3B5F728000000000FF1DE3F10000000000FA TIDB_DECODE_KEY(START_KEY): {"_tidb_rowid":1958897,"table_id":"59"} @@ -49,7 +161,7 @@ TIDB_DECODE_KEY(START_KEY): {"_tidb_rowid":1958897,"table_id":"59"} SHOW CREATE TABLE t2\G ``` -```sql +``` *************************** 1. row *************************** Table: t2 Create Table: CREATE TABLE `t2` ( @@ -65,7 +177,7 @@ Create Table: CREATE TABLE `t2` ( SELECT * FROM information_schema.tikv_region_status WHERE table_name='t2' LIMIT 1\G ``` -```sql +``` *************************** 1. row *************************** REGION_ID: 48 START_KEY: 7480000000000000FF3E5F720400000000FF0000000601633430FF3338646232FF2D64FF3531632D3131FF65FF622D386337352DFFFF3830653635303138FFFF61396265000000FF00FB000000000000F9 @@ -91,7 +203,7 @@ REPLICATIONSTATUS_STATEID: NULL SELECT tidb_decode_key('7480000000000000FF3E5F720400000000FF0000000601633430FF3338646232FF2D64FF3531632D3131FF65FF622D386337352DFFFF3830653635303138FFFF61396265000000FF00FB000000000000F9'); ``` -```sql +``` +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | tidb_decode_key('7480000000000000FF3E5F720400000000FF0000000601633430FF3338646232FF2D64FF3531632D3131FF65FF622D386337352DFFFF3830653635303138FFFF61396265000000FF00FB000000000000F9') | +---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -116,7 +228,7 @@ ORDER BY START_KEY; ``` -```sql +``` +------------+-----------------------------------------------------------+-----------------------------------------------------------+ | TABLE_NAME | TIDB_DECODE_KEY(START_KEY) | TIDB_DECODE_KEY(END_KEY) | +------------+-----------------------------------------------------------+-----------------------------------------------------------+ @@ -130,7 +242,7 @@ ORDER BY `TIDB_DECODE_KEY` 在解码成功时返回有效的 JSON,在解码失败时返回传入的参数值。 -### TIDB_DECODE_PLAN +## TIDB_DECODE_PLAN 你可以在慢查询日志中找到编码形式的 TiDB 执行计划,然后使用 `TIDB_DECODE_PLAN()` 函数将编码的执行计划解码为易读的形式。 @@ -140,7 +252,7 @@ ORDER BY SELECT tidb_decode_plan('8QIYMAkzMV83CQEH8E85LjA0CWRhdGE6U2VsZWN0aW9uXzYJOTYwCXRpbWU6NzEzLjHCtXMsIGxvb3BzOjIsIGNvcF90YXNrOiB7bnVtOiAxLCBtYXg6IDU2OC41wgErRHByb2Nfa2V5czogMCwgcnBjXxEpAQwFWBAgNTQ5LglZyGNvcHJfY2FjaGVfaGl0X3JhdGlvOiAwLjAwfQkzLjk5IEtCCU4vQQoxCTFfNgkxXzAJMwm2SGx0KHRlc3QudC5hLCAxMDAwMCkNuQRrdgmiAHsFbBQzMTMuOMIBmQnEDDk2MH0BUgEEGAoyCTQzXzUFVwX1oGFibGU6dCwga2VlcCBvcmRlcjpmYWxzZSwgc3RhdHM6cHNldWRvCTk2ISE2aAAIMTUzXmYA')\G ``` -```sql +``` *************************** 1. row *************************** tidb_decode_plan('8QIYMAkzMV83CQEH8E85LjA0CWRhdGE6U2VsZWN0aW9uXzYJOTYwCXRpbWU6NzEzLjHCtXMsIGxvb3BzOjIsIGNvcF90YXNrOiB7bnVtOiAxLCBtYXg6IDU2OC41wgErRHByb2Nfa2V5czogMCwgcnBjXxEpAQwFWBAgNTQ5LglZyGNvcHJfY2FjaGVfaGl0X3JhdGlvOiAwLjAwfQkzLjk5IEtCCU4vQQoxCTFfNgkxXz: id task estRows operator info actRows execution info memory disk TableReader_7 root 319.04 data:Selection_6 960 time:713.1µs, loops:2, cop_task: {num: 1, max: 568.5µs, proc_keys: 0, rpc_num: 1, rpc_time: 549.1µs, copr_cache_hit_ratio: 0.00} 3.99 KB N/A @@ -148,62 +260,14 @@ SELECT tidb_decode_plan('8QIYMAkzMV83CQEH8E85LjA0CWRhdGE6U2VsZWN0aW9uXzYJOTYwCXR └─TableFullScan_5 cop[tikv] 960 table:t, keep order:false, stats:pseudo 960 tikv_task:{time:153µs, loops:960} N/A N/A ``` -### TIDB_PARSE_TSO - -`TIDB_PARSE_TSO` 函数用于从 TiDB TSO 时间戳中提取物理时间戳。 - -TSO 指 Time Stamp Oracle,是 PD (Placement Driver) 为每个事务提供的单调递增的时间戳。TSO 是一串数字,包含以下两部分: - -- 一个物理时间戳 -- 一个逻辑计数器 - -```sql -BEGIN; -SELECT TIDB_PARSE_TSO(@@tidb_current_ts); -ROLLBACK; -``` - -```sql -+-----------------------------------+ -| TIDB_PARSE_TSO(@@tidb_current_ts) | -+-----------------------------------+ -| 2021-05-26 11:33:37.776000 | -+-----------------------------------+ -1 row in set (0.0012 sec) -``` - -以上示例使用 `TIDB_PARSE_TSO` 函数从 `tidb_current_ts` 会话变量提供的可用时间戳编号中提取物理时间戳。因为每个事务都会分配到时间戳,所以此函数在事务中运行。 - -### TIDB_VERSION - -`TIDB_VERSION` 函数用于获取当前连接的 TiDB 服务器版本和构建详细信息。向 GitHub 上提交 issue 时,你可使用此函数获取相关信息。 - -```sql -SELECT TIDB_VERSION()\G -``` - -```sql -*************************** 1. row *************************** -TIDB_VERSION(): Release Version: v5.1.0-alpha-13-gd5e0ed0aa-dirty -Edition: Community -Git Commit Hash: d5e0ed0aaed72d2f2dfe24e9deec31cb6cb5fdf0 -Git Branch: master -UTC Build Time: 2021-05-24 14:39:20 -GoVersion: go1.13 -Race Enabled: false -TiKV Min Version: v3.0.0-60965b006877ca7234adaced7890d7b029ed1306 -Check Table Before Drop: false -1 row in set (0.00 sec) -``` - -### TIDB_DECODE_SQL_DIGESTS +## TIDB_DECODE_SQL_DIGESTS `TIDB_DECODE_SQL_DIGESTS()` 函数用于在集群中查询一组 SQL Digest 所对应的 SQL 语句的归一化形式(即去除格式和参数后的形式)。函数接受 1 个或 2 个参数: * `digests`:字符串类型,该参数应符合 JSON 字符串数组的格式,数组中的每个字符串应为一个 SQL Digest。 -* `stmtTruncateLength`:可选参数,整数类型,用来限制返回结果中每条 SQL 语句的长度,超过指定的长度会被截断。0 表示不限制长度。 +* `stmtTruncateLength`:可选参数,整数类型,用来限制返回结果中每条 SQL 语句的长度,超过指定的长度会被截断。`0` 表示不限制长度。 -返回一个字符串,符合 JSON 字符串数组的格式,数组中的第 *i* 项为参数 `digests` 中的第 *i* 个元素所对应的语句。如果参数 `digests` 中的某一项不是一个有效的 SQL Digest 或系统无法查询到其对应的 SQL 语句,则返回结果中对应项为 `null`。如果指定了截断长度(`stmtTruncateLength > 0`),则返回结果中每条超过该长度的语句,保留前 `stmtTruncateLength` 个字符,并在尾部增加 `"..."` 后缀表示发生了截断。如果参数 `digests` 为 `NULL`,则函数的返回值为 `NULL`。 +该函数返回一个字符串,符合 JSON 字符串数组的格式,数组中的第 *i* 项为参数 `digests` 中的第 *i* 个元素所对应的语句。如果参数 `digests` 中的某一项不是一个有效的 SQL Digest 或系统无法查询到其对应的 SQL 语句,则返回结果中对应项为 `null`。如果指定了截断长度 (`stmtTruncateLength > 0`),则返回结果中每条超过该长度的语句,保留前 `stmtTruncateLength` 个字符,并在尾部增加 `"..."` 后缀表示发生了截断。如果参数 `digests` 为 `NULL`,则函数的返回值为 `NULL`。 > **注意:** > @@ -213,14 +277,14 @@ Check Table Before Drop: false > * 该函数开销大的原因是,其每次被调用时,都会在内部发起对 `STATEMENTS_SUMMARY`、`STATEMENTS_SUMMARY_HISTORY`、`CLUSTER_STATEMENTS_SUMMARY` 和 `CLUSTER_STATEMENTS_SUMMARY_HISTORY` 这几张表的查询,且其中涉及 `UNION` 操作。且该函数目前不支持向量化,即对于多行数据调用该函数时,对每行都会独立进行一次上述的查询。 ```sql -set @digests = '["e6f07d43b5c21db0fbb9a31feac2dc599787763393dd5acbfad80e247eb02ad5","38b03afa5debbdf0326a014dbe5012a62c51957f1982b3093e748460f8b00821","e5796985ccafe2f71126ed6c0ac939ffa015a8c0744a24b7aee6d587103fd2f7"]'; +SET @digests = '["e6f07d43b5c21db0fbb9a31feac2dc599787763393dd5acbfad80e247eb02ad5","38b03afa5debbdf0326a014dbe5012a62c51957f1982b3093e748460f8b00821","e5796985ccafe2f71126ed6c0ac939ffa015a8c0744a24b7aee6d587103fd2f7"]'; -select tidb_decode_sql_digests(@digests); +SELECT TIDB_DECODE_SQL_DIGESTS(@digests); ``` -```sql +``` +------------------------------------+ -| tidb_decode_sql_digests(@digests) | +| TIDB_DECODE_SQL_DIGESTS(@digests) | +------------------------------------+ | ["begin",null,"select * from `t`"] | +------------------------------------+ @@ -230,12 +294,12 @@ select tidb_decode_sql_digests(@digests); 上面的例子中,参数是一个包含 3 个 SQL Digest 的 JSON 数组,其对应的 SQL 语句分别为查询结果中给出的三项。但是其中第二条 SQL Digest 所对应的 SQL 语句未能从集群中找到,因而结果中的第二项为 `null`。 ```sql -select tidb_decode_sql_digests(@digests, 10); +SELECT TIDB_DECODE_SQL_DIGESTS(@digests, 10); ``` ```sql +---------------------------------------+ -| tidb_decode_sql_digests(@digests, 10) | +| TIDB_DECODE_SQL_DIGESTS(@digests, 10) | +---------------------------------------+ | ["begin",null,"select * f..."] | +---------------------------------------+ @@ -246,65 +310,117 @@ select tidb_decode_sql_digests(@digests, 10); 另请参阅: -- [`Statement Summary Tables`](/statement-summary-tables.md) +- [Statement Summary Tables](/statement-summary-tables.md) - [`INFORMATION_SCHEMA.TIDB_TRX`](/information-schema/information-schema-tidb-trx.md) -### TIDB_SHARD +## TIDB_ENCODE_SQL_DIGEST -`TIDB_SHARD` 函数用于创建一个 SHARD INDEX 来打散热点索引。SHARD INDEX 是一种以 `TIDB_SHARD` 函数为前缀的表达式索引。 +`TIDB_ENCODE_SQL_DIGEST(query_str)` 函数返回查询字符串的 SQL digest。 -- 创建方式: +在以下示例中,你可以看到两个查询都获得了相同的查询 digest,这是因为两个查询的 digest 都是 `select ?`。 - 使用 `uk((tidb_shard(a)), a))` 为字段 `a` 创建一个 SHARD INDEX。当二级唯一索引 `uk((tidb_shard(a)), a))` 的索引字段 `a` 上存在因单调递增或递减而产生的热点时,索引的前缀 `tidb_shard(a)` 会打散热点,从而提升集群可扩展性。 +```sql +SELECT TIDB_ENCODE_SQL_DIGEST('SELECT 1'); +``` -- 适用场景: +``` ++------------------------------------------------------------------+ +| TIDB_ENCODE_SQL_DIGEST('SELECT 1') | ++------------------------------------------------------------------+ +| e1c71d1661ae46e09b7aaec1c390957f0d6260410df4e4bc71b9c8d681021471 | ++------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` - - 二级唯一索引上 key 值存在单调递增或递减导致的写入热点,且该索引包含的列是整型。 - - 业务中 SQL 语句根据该二级索引的全部字段做等值查询,查询可以是单独的 `SELECT`,也可以是 `UPDATE`,`DELETE` 等产生的内部查询,等值查询包括 `a = 1` 或 `a IN (1, 2, ......)` 两种方式。 +```sql +SELECT TIDB_ENCODE_SQL_DIGEST('SELECT 2'); +``` -- 使用限制: +``` ++------------------------------------------------------------------+ +| TIDB_ENCODE_SQL_DIGEST('SELECT 2') | ++------------------------------------------------------------------+ +| e1c71d1661ae46e09b7aaec1c390957f0d6260410df4e4bc71b9c8d681021471 | ++------------------------------------------------------------------+ +1 row in set (0.00 sec) +``` - - 非等值查询无法使用索引。 - - 查询条件中 `AND` 和 `OR` 混合且最外层是 `AND` 算子时无法使用 SHARD INDEX。 - - `GROUP BY` 无法使用 SHARD INDEX。 - - `ORDER BY` 无法使用 SHARD INDEX。 - - `ON` 子句无法使用 SHARD INDEX。 - - `WHERE` 子查询无法使用 SHARD INDEX。 - - SHARD INDEX 只能打散整型字段的唯一索引。 - - SHARD INDEX 联合索引可能失效。 - - SHARD INDEX 无法走 FastPlan 流程,影响优化器性能。 - - SHARD INDEX 无法使用执行计划缓存。 +## TIDB_IS_DDL_OWNER -`TIDB_SHARD` 函数的使用示例如下: +如果你连接的 TiDB 实例是 DDL Owner,`TIDB_IS_DDL_OWNER()` 函数返回 `1`。 -- 使用 `TIDB_SHARD` 函数计算 SHARD 值 +```sql +SELECT TIDB_IS_DDL_OWNER(); +``` - 以下示例说明如何使用 `TIDB_SHARD` 函数计算 `12373743746` 的 SHARD 值。 +``` ++---------------------+ +| TIDB_IS_DDL_OWNER() | ++---------------------+ +| 1 | ++---------------------+ +1 row in set (0.00 sec) +``` - ```sql - SELECT TIDB_SHARD(12373743746); - ``` +## TIDB_PARSE_TSO -- 计算得出 SHARD 值为: +`TIDB_PARSE_TSO()` 函数用于从 TiDB TSO 时间戳中提取物理时间戳。 - ```sql - +-------------------------+ - | TIDB_SHARD(12373743746) | - +-------------------------+ - | 184 | - +-------------------------+ - 1 row in set (0.00 sec) - ``` +TSO 指 Time Stamp Oracle,是 PD (Placement Driver) 为每个事务提供的单调递增的时间戳。TSO 是一串数字,包含以下两部分: -- 使用 `TIDB_SHARD` 函数创建 SHARD INDEX +- 一个物理时间戳 +- 一个逻辑计数器 - ```sql - CREATE TABLE test(id INT PRIMARY KEY CLUSTERED, a INT, b INT, UNIQUE KEY uk((tidb_shard(a)), a)); - ``` +```sql +BEGIN; +SELECT TIDB_PARSE_TSO(@@tidb_current_ts); +ROLLBACK; +``` + +``` ++-----------------------------------+ +| TIDB_PARSE_TSO(@@tidb_current_ts) | ++-----------------------------------+ +| 2021-05-26 11:33:37.776000 | ++-----------------------------------+ +1 row in set (0.0012 sec) +``` + +以上示例使用 `TIDB_PARSE_TSO()` 函数从 `tidb_current_ts` 会话变量提供的可用时间戳编号中提取物理时间戳。因为每个事务都会分配到时间戳,所以此函数在事务中运行。 -### TIDB_ROW_CHECKSUM +## TIDB_PARSE_TSO_LOGICAL -`TIDB_ROW_CHECKSUM` 函数用于查询行数据的 Checksum 值。该函数只能用于 FastPlan 流程的 `SELECT` 语句,即你可通过形如 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id = ?` 或 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id IN (?, ?, ...)` 的语句进行查询。 +`TIDB_PARSE_TSO_LOGICAL(tso)` 函数返回从 TiDB [TSO](/tso.md) 时间戳中提取的逻辑时间戳。 + +```sql +SELECT TIDB_PARSE_TSO_LOGICAL(450456244814610433); +``` + +``` ++--------------------------------------------+ +| TIDB_PARSE_TSO_LOGICAL(450456244814610433) | ++--------------------------------------------+ +| 1 | ++--------------------------------------------+ +1 row in set (0.00 sec) +``` + +```sql +SELECT TIDB_PARSE_TSO_LOGICAL(450456244814610434); +``` + +``` ++--------------------------------------------+ +| TIDB_PARSE_TSO_LOGICAL(450456244814610434) | ++--------------------------------------------+ +| 2 | ++--------------------------------------------+ +1 row in set (0.00 sec) +``` + +## TIDB_ROW_CHECKSUM + +`TIDB_ROW_CHECKSUM()` 函数用于查询行数据的 Checksum 值。该函数只能用于 FastPlan 流程的 `SELECT` 语句,即你可通过形如 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id = ?` 或 `SELECT TIDB_ROW_CHECKSUM() FROM t WHERE id IN (?, ?, ...)` 的语句进行查询。 在 TiDB 中开启行数据 Checksum 功能 [`tidb_enable_row_level_checksum`](/system-variables.md#tidb_enable_row_level_checksum-从-v710-版本开始引入): @@ -319,7 +435,7 @@ SET GLOBAL tidb_enable_row_level_checksum = ON; ```sql USE test; CREATE TABLE t (id INT PRIMARY KEY, k INT, c CHAR(1)); -INSERT INTO t values (1, 10, 'a'); +INSERT INTO t VALUES (1, 10, 'a'); ``` 查询表 `t` 中 `id = 1` 的行数据的 Checksum 值: @@ -330,7 +446,7 @@ SELECT *, TIDB_ROW_CHECKSUM() FROM t WHERE id = 1; 输出结果如下: -```sql +``` +----+------+------+---------------------+ | id | k | c | TIDB_ROW_CHECKSUM() | +----+------+------+---------------------+ @@ -339,50 +455,96 @@ SELECT *, TIDB_ROW_CHECKSUM() FROM t WHERE id = 1; 1 row in set (0.000 sec) ``` -### CURRENT_RESOURCE_GROUP +## TIDB_SHARD -`CURRENT_RESOURCE_GROUP` 函数用于查询当前连接绑定的资源组名称。当开启[资源管控 (Resource Control)](/tidb-resource-control.md) 功能时,执行 SQL 语句对资源的占用会受到所绑定的资源组资源配置的限制。 +`TIDB_SHARD()` 函数用于创建一个 SHARD INDEX 来打散热点索引。SHARD INDEX 是一种以 `TIDB_SHARD()` 函数为前缀的表达式索引。 -在会话建立时,TiDB 默认会将连接绑定至登录用户绑定的资源组,如果用户没有绑定任何资源组,则会将连接绑定至 `default` 资源组。在会话建立之后,绑定的资源组默认不会发生变化,即使执行了[修改用户绑定的资源组](/sql-statements/sql-statement-alter-user.md#修改用户绑定的资源组)。如需修改当前会话绑定的资源组,可以使用 [`SET RESOURCE GROUP`](/sql-statements/sql-statement-set-resource-group.md) 语句。 +- 创建方式: -#### 示例 + 使用 `uk((tidb_shard(a)), a))` 为字段 `a` 创建一个 SHARD INDEX。当二级唯一索引 `uk((tidb_shard(a)), a))` 的索引字段 `a` 上存在因单调递增或递减而产生的热点时,索引的前缀 `tidb_shard(a)` 会打散热点,从而提升集群可扩展性。 -创建一个用户 `user1`,创建两个资源组 `rg1` 和 `rg2`,并将用户 `user1` 绑定资源组 `rg1`: +- 适用场景: -```sql -CREATE USER 'user1'; -CREATE RESOURCE GROUP 'rg1' RU_PER_SEC = 1000; -CREATE RESOURCE GROUP 'rg2' RU_PER_SEC = 2000; -ALTER USER 'user1' RESOURCE GROUP `rg1`; -``` + - 二级唯一索引上 key 值存在单调递增或递减导致的写入热点,且该索引包含的列是整型。 + - 业务中 SQL 语句根据该二级索引的全部字段做等值查询,查询可以是单独的 `SELECT`,也可以是 `UPDATE`,`DELETE` 等产生的内部查询,等值查询包括 `a = 1` 或 `a IN (1, 2, ......)` 两种方式。 -使用 `user1` 登录,查看当前用户绑定的资源组: +- 使用限制: + + - 非等值查询无法使用索引。 + - 查询条件中 `AND` 和 `OR` 混合且最外层是 `AND` 算子时无法使用 SHARD INDEX。 + - `GROUP BY` 无法使用 SHARD INDEX。 + - `ORDER BY` 无法使用 SHARD INDEX。 + - `ON` 子句无法使用 SHARD INDEX。 + - `WHERE` 子查询无法使用 SHARD INDEX。 + - SHARD INDEX 只能打散整型字段的唯一索引。 + - SHARD INDEX 联合索引可能失效。 + - SHARD INDEX 无法走 FastPlan 流程,影响优化器性能。 + - SHARD INDEX 无法使用执行计划缓存。 + +`TIDB_SHARD()` 函数的使用示例如下: + +- 使用 `TIDB_SHARD()` 函数计算 SHARD 值: + + 以下示例说明如何使用 `TIDB_SHARD()` 函数计算 `12373743746` 的 SHARD 值。 + + ```sql + SELECT TIDB_SHARD(12373743746); + ``` + +- 计算得出 SHARD 值为: + + ```sql + +-------------------------+ + | TIDB_SHARD(12373743746) | + +-------------------------+ + | 184 | + +-------------------------+ + 1 row in set (0.00 sec) + ``` + +- 使用 `TIDB_SHARD()` 函数创建 SHARD INDEX: + + ```sql + CREATE TABLE test(id INT PRIMARY KEY CLUSTERED, a INT, b INT, UNIQUE KEY uk((tidb_shard(a)), a)); + ``` + +## TIDB_VERSION + +`TIDB_VERSION()` 函数用于获取当前连接的 TiDB 服务器版本和构建详细信息。向 GitHub 上提交 issue 时,你可使用此函数获取相关信息。 ```sql -SELECT CURRENT_RESOURCE_GROUP(); +SELECT TIDB_VERSION()\G ``` ```sql -+--------------------------+ -| CURRENT_RESOURCE_GROUP() | -+--------------------------+ -| rg1 | -+--------------------------+ +*************************** 1. row *************************** +TIDB_VERSION(): Release Version: v8.2.0 +Edition: Community +Git Commit Hash: 821e491a20fbab36604b36b647b5bae26a2c1418 +Git Branch: HEAD +UTC Build Time: 2024-07-11 19:16:25 +GoVersion: go1.21.10 +Race Enabled: false +Check Table Before Drop: false +Store: tikv 1 row in set (0.00 sec) ``` -执行 `SET RESOURCE GROUP` 将当前会话的资源组设置为 `rg2`,然后查看当前用户绑定的资源组: +## VITESS_HASH + +`VITESS_HASH(num)` 函数以与 Vitess 相同的方式返回数值的哈希值。这有助于将数据从 Vitess 迁移到 TiDB。 + +示例: ```sql -SET RESOURCE GROUP `rg2`; -SELECT CURRENT_RESOURCE_GROUP(); +SELECT VITESS_HASH(123); ``` -```sql -+--------------------------+ -| CURRENT_RESOURCE_GROUP() | -+--------------------------+ -| rg2 | -+--------------------------+ -1 row in set (0.00 sec) ``` ++---------------------+ +| VITESS_HASH(123) | ++---------------------+ +| 1155070131015363447 | ++---------------------+ +1 row in set (0.00 sec) +``` \ No newline at end of file diff --git a/identify-slow-queries.md b/identify-slow-queries.md index 11f716ab37f8..76adc129c0ff 100644 --- a/identify-slow-queries.md +++ b/identify-slow-queries.md @@ -74,7 +74,7 @@ Slow Query 基础信息: * `Succ`:表示语句是否执行成功。 * `Backoff_time`:表示语句遇到需要重试的错误时在重试前等待的时间。常见的需要重试的错误有以下几种:遇到了 lock、Region 分裂、`tikv server is busy`。 * `Plan`:表示语句的执行计划,用 `select tidb_decode_plan('xxx...')` SQL 语句可以解析出具体的执行计划。 -* `Binary_plan`:表示以二进制格式编码后的语句的执行计划,用 `select tidb_decode_binary_plan('xxx...')` SQL 语句可以解析出具体的执行计划。传递的信息和 `Plan` 字段基本相同,但是解析出的执行计划的格式会和 `Plan` 字段不同。 +* `Binary_plan`:表示以二进制格式编码后的语句的执行计划,用 [`SELECT tidb_decode_binary_plan('xxx...')`](/functions-and-operators/tidb-functions.md#tidb_decode_binary_plan) SQL 语句可以解析出具体的执行计划。传递的信息和 `Plan` 字段基本相同,但是解析出的执行计划的格式会和 `Plan` 字段不同。 * `Prepared`:表示这个语句是否是 `Prepare` 或 `Execute` 的请求。 * `Plan_from_cache`:表示这个语句是否命中了执行计划缓存。 * `Plan_from_binding`:表示这个语句是否用的绑定的执行计划。 diff --git a/statement-summary-tables.md b/statement-summary-tables.md index c7c47d04fbd4..73e66137ffcf 100644 --- a/statement-summary-tables.md +++ b/statement-summary-tables.md @@ -276,7 +276,7 @@ SQL 的基础信息: - `SAMPLE_USER`:执行这类 SQL 的用户名,多个用户名只取其中一个 - `PLAN_DIGEST`:执行计划的 digest - `PLAN`:原执行计划,多条语句只取其中一条的执行计划 -- `BINARY_PLAN`:以二进制格式编码后的原执行计划,存在多条语句时,只取其中一条语句的执行计划。用 `select tidb_decode_binary_plan('xxx...')` SQL 语句可以解析出具体的执行计划。 +- `BINARY_PLAN`:以二进制格式编码后的原执行计划,存在多条语句时,只取其中一条语句的执行计划。用 [`SELECT tidb_decode_binary_plan('xxx...')`](/functions-and-operators/tidb-functions.md#tidb_decode_binary_plan) SQL 语句可以解析出具体的执行计划。 - `PLAN_CACHE_HITS`:这类 SQL 语句命中 plan cache 的总次数 - `PLAN_IN_CACHE`:这类 SQL 语句的上次执行是否命中了 plan cache - `PLAN_CACHE_UNQUALIFIED`:这类 SQL 语句没有命中 plan cache 的次数 diff --git a/system-variables.md b/system-variables.md index 50d19a6713dd..c726f3ea7dba 100644 --- a/system-variables.md +++ b/system-variables.md @@ -2683,7 +2683,7 @@ v5.0 后,用户仍可以单独修改以上系统变量(会有废弃警告) - 默认值:`ON` - 这个变量用于指定是否在 slow log 和 statement summary 里包含以二进制格式编码的执行计划。 - 开启该变量后,即可在 TiDB Dashboard 中查看查询的图形化执行计划。注意,TiDB Dashboard 只显示变量开启时产生的查询的执行计划。 -- 用 `select tidb_decode_binary_plan('xxx...')` SQL 语句可以从编码后的执行计划解析出具体的执行计划。 +- 用 [`SELECT tidb_decode_binary_plan('xxx...')`](/functions-and-operators/tidb-functions.md#tidb_decode_binary_plan) SQL 语句可以从编码后的执行计划解析出具体的执行计划。 ### `tidb_gogc_tuner_max_value` 从 v7.5.0 版本开始引入