Skip to content

Update documents of lock view for sprint 4 #6824

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions functions-and-operators/tidb-functions.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,3 +259,73 @@ Check Table Before Drop: false
### MySQL 兼容性

`TIDB_VERSION` 是 TiDB 特有的函数,和 MySQL 不兼容。如果要求兼容 MySQL,可以使用 `VERSION` 获取版本信息,但结果不包含详细的构建信息。

## TIDB_DECODE_SQL_DIGESTS

`TIDB_DECODE_SQL_DIGESTS` 函数用于在集群中查询一组 SQL Digest 所对应的 SQL 语句的归一化形式(即去除格式和参数后的形式)。函数接受 1 个或 2 个参数:

* `digests`:字符串类型,该参数应符合 JSON 字符串数组的格式,数组中的每个字符串应为一个 SQL Digest。
* `stmtTruncateLength`:可选参数,整数类型,用来限制返回结果中每条 SQL 语句的长度,超过指定的长度会被截断。0 表示不限制长度。

返回一个字符串,符合 JSON 字符串数组的格式,数组中的第 *i* 项为参数 `digests` 中的第 *i* 个元素所对应的语句。如果参数 `digests` 中的某一项不是一个有效的 SQL Digest 或系统无法查询到其对应的 SQL 语句,则返回结果中对应项为 `null`。如果指定了截断长度(`stmtTruncateLength > 0`),则返回结果中每条超过该长度的语句,保留前 `stmtTruncateLength` 个字符,并在尾部增加 `"..."` 后缀表示发生了截断。如果参数 `digests` 为 `NULL`,则函数的返回值为 `NULL`。

> **注意:**
>
> * 仅持有 [PROCESS](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_process) 权限的用户可以使用该函数。
> * `TIDB_DECODE_SQL_DIGESTS` 执行时,TiDB 内部从 Statement Summary 一系列表中查询每个 SQL Digest 所对应的语句,因而并不能保证对任意 SQL Digest 都总是能查询到对应的语句,只有在集群中执行过的语句才有可能被查询到,且是否能查询到受 Statement Summary 表相关配置的影响。有关 Statement Summary 表的详细说明,参见 [Statement Summary Tables](/statement-summary-tables.md)。
> * 该函数开销较大,在行数很多的查询中(比如在规模较大、比较繁忙的集群上查询 `information_schema.cluster_tidb_trx` 全表时)直接使用该函数可能导致查询运行时间较长。请谨慎使用。
> * 该函数开销大的原因是,其每次被调用时,都会在内部发起对 `STATEMENTS_SUMMARY`、`STATEMENTS_SUMMARY_HISTORY`、`CLUSTER_STATEMENTS_SUMMARY` 和 `CLUSTER_STATEMENTS_SUMMARY_HISTORY` 这几张表的查询,且其中涉及 `UNION` 操作。且该函数目前不支持向量化,即对于多行数据调用该函数时,对每行都会独立进行一次上述的查询。

### 语法图

```ebnf+diagram
DecodeSQLDigestsExpr ::=
"TIDB_DECODE_SQL_DIGESTS" "(" digests ( "," stmtTruncateLength )? ")"
```

### 示例

{{< copyable "sql" >}}

```sql
set @digests = '["e6f07d43b5c21db0fbb9a31feac2dc599787763393dd5acbfad80e247eb02ad5","38b03afa5debbdf0326a014dbe5012a62c51957f1982b3093e748460f8b00821","e5796985ccafe2f71126ed6c0ac939ffa015a8c0744a24b7aee6d587103fd2f7"]';

select tidb_decode_sql_digests(@digests);
```

```sql
+------------------------------------+
| tidb_decode_sql_digests(@digests) |
+------------------------------------+
| ["begin",null,"select * from `t`"] |
+------------------------------------+
1 row in set (0.00 sec)
```

上面的例子中,参数是一个包含 3 个 SQL Digest 的 JSON 数组,其对应的 SQL 语句分别为查询结果中给出的三项。但是其中第二条 SQL Digest 所对应的 SQL 语句未能从集群中找到,因而结果中的第二项为 `null`。

{{< copyable "sql" >}}

```sql
select tidb_decode_sql_digests(@digests, 10);
```

```sql
+---------------------------------------+
| tidb_decode_sql_digests(@digests, 10) |
+---------------------------------------+
| ["begin",null,"select * f..."] |
+---------------------------------------+
1 row in set (0.01 sec)
```

上述调用指定了第二个参数(即截断长度)为 10,而查询结果中的第三条语句的长度大于 10,因而仅保留了前 10 个字符,并在尾部添加了 `"..."` 表示发生了截断。

### MySQL 兼容性

`TIDB_DECODE_SQL_DIGESTS` 是 TiDB 特有的函数,和 MySQL 不兼容。

### 另请参阅

- [`Statement Summary Tables`](/statement-summary-tables.md)
- [`INFORMATION_SCHEMA.TIDB_TRX`](/information-schema/information-schema-tidb-trx.md)
82 changes: 43 additions & 39 deletions information-schema/information-schema-data-lock-waits.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ summary: 了解 information_schema 表 `DATA_LOCK_WAITS`。

`DATA_LOCK_WAITS` 表展示了集群中所有 TiKV 节点上当前正在发生的悲观锁等锁的情况。

> **警告:**
>
> 该功能目前为实验性功能,表结构的定义和行为在未来版本中可能有较大改动。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这张系统表在 v5.1 中仍为实验功能吗?


{{< copyable "sql" >}}

```sql
Expand All @@ -22,24 +18,55 @@ DESC data_lock_waits;
+------------------------+---------------------+------+------+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+---------------------+------+------+---------+-------+
| KEY | varchar(64) | NO | | NULL | |
| KEY | text | NO | | NULL | |
| KEY_INFO | text | YES | | NULL | |
| TRX_ID | bigint(21) unsigned | NO | | NULL | |
| CURRENT_HOLDING_TRX_ID | bigint(21) unsigned | NO | | NULL | |
| SQL_DIGEST | varchar(64) | YES | | NULL | |
| SQL_DIGEST_TEXT | text | YES | | NULL | |
+------------------------+---------------------+------+------+---------+-------+
```

`DATA_LOCK_WAITS` 表中各列的字段含义如下:

* `KEY`:正在发生等锁的 KEY,以十六进制编码的形式显示。
* `KEY`:正在发生等锁的 key,以十六进制编码的形式显示。
* `KEY_INFO`:对 `KEY` 进行解读得出的一些详细信息,见 [KEY_INFO](#key_info)。
* `TRX_ID`:正在等锁的事务 ID,即 `start_ts`。
* `CURRENT_HOLDING_TRX_ID`:当前持有锁的事务 ID,即 `start_ts`。
* `SQL_DIGEST`:当前正在等锁的事务中被阻塞的 SQL 语句的 Digest。
* `SQL_DIGEST_TEXT`:当前正在等锁的事务中被阻塞的 SQL 语句的归一化形式,即去除了参数和格式的 SQL 语句。与 `SQL_DIGEST` 对应。

> **警告:**
>
> * 该表中的信息是在查询时,从所有 TiKV 节点实时获取的。目前,即使加上了 `WHERE` 查询条件,也无法避免对所有 TiKV 节点都进行信息收集。如果集群规模很大、负载很高,查询该表有造成性能抖动的潜在风险,因此请根据实际情况使用。
> * 来自不同 TiKV 节点的信息不一定是同一时间点的快照。
> * 仅拥有 [PROCESS](https://dev.mysql.com/doc/refman/8.0/en/privileges-provided.html#priv_process) 权限的用户可以查询该表。
> * `DATA_LOCK_WAITS` 表中的信息是在查询时,从所有 TiKV 节点实时获取的。目前,即使加上了 `WHERE` 查询条件,也无法避免对所有 TiKV 节点都进行信息收集。如果集群规模很大、负载很高,查询该表有造成性能抖动的潜在风险,因此请根据实际情况使用。
> * 来自不同 TiKV 节点的信息不能保证是同一时间点的快照。
> * `SQL_DIGEST` 列中的信息(SQL Digest)为 SQL 语句进行归一化后计算得到的哈希值。`SQL_DIGEST_TEXT` 列中的信息为内部从 Statements Summary 系列表中查询得到,因而存在内部查询不到对应语句的可能性。关于 SQL Digest 和 Statements Summary 相关表的详细说明,请参阅[Statement Summary Tables](/statement-summary-tables.md)。

## `KEY_INFO`

`KEY_INFO` 列中展示了对 `KEY` 列中所给出的 key 的详细信息,以 JSON 格式给出。其包含的信息如下:

* `"db_id"`:该 key 所属的数据库(schema)的 ID。
* `"db_name"`:该 key 所属的数据库(schema)的名称。
* `"table_id"`:该 key 所属的表的 ID。
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May need to explain if it's a partitioned table, if it's the partition table id or the real physical table id

* `"table_name"`:该 key 所属的表的名称。
* `"partition_id"`:该 key 所在的分区(partition)的 ID。
* `"partition_name"`:该 key 所在的分区(partition)的名称。
* `"handle_type"`:该 row key (即储存一行数据的 key)的 handle 类型,其可能的值有:
* `"int"`:handle 为 int 类型,即 handle 为 row ID
* `"common"`:非 int64 类型的 handle,在启用 clustered index 时非 int 类型的主键会显示为此类型
* `"unknown"`:当前暂不支持的 handle 类型
* `"handle_value"`:handle 的值。
* `"index_id"`:该 index key (即储存索引的 key)所属的 index ID。
* `"index_name"`:该 index key 所属的 index 名称。
* `"index_values"`:该 index key 中的 index value。

其中,不适用或当前无法查询到的信息会被省略。比如,row key 的信息中不会包含 `index_id`、`index_name` 和 `index_values`;index key 不会包含 `handle_type` 和 `handle_value`;非分区表不会显示 `partition_id` 和 `partition_name`;已经被删除掉的表中的 key 的信息无法获取 `table_name`、`db_id`、`db_name`、`index_name` 等 schema 信息,且无法区分是否为分区表。

> **注意:**
>
> 如果一个 key 来自一张启用了分区的表,而在查询时,由于某些原因(例如,其所属的表已经被删除)导致无法查询其所属的 schema 信息,则其所属的分区的 ID 可能会出现在 `table_id` 字段中。这是因为,TiDB 对不同分区的 key 的编码方式与对几张独立的表的 key 的编码方式一致,因而在缺失 schema 信息时无法确认该 key 属于一张未分区的表还是某张表的一个分区。

## 示例

Expand All @@ -51,36 +78,13 @@ select * from information_schema.data_lock_waits\G

```sql
*************************** 1. row ***************************
KEY: 7480000000000000355f728000000000000002
TRX_ID: 425405024158875649
CURRENT_HOLDING_TRX_ID: 425405016242126849
SQL_DIGEST: f7530877a35ae65300c42250abd8bc731bbaf0a7cabc05dab843565230611bb22
2 rows in set (0.01 sec)
```

以上查询结果显示,ID 为 `425405024158875649` 的事务在执行 Digest 为 `"f7530877a35ae65300c42250abd8bc731bbaf0a7cabc05dab843565230611bb22"` 的语句的过程中,试图在 `"7480000000000000355f728000000000000002"` 这个 key 上获取悲观锁,但是该 key 上的锁目前被 ID 为 `425405016242126849` 的事务持有。

## SQL Digest

`DATA_LOCK_WAITS` 表中会记录 SQL Digest,并不记录 SQL 原文。

SQL Digest 是 SQL 归一化之后的哈希值。如需查找 SQL Digest 对应的 SQL 原文,请进行以下操作之一:

- 对于当前 TiDB 节点在最近一段时间内执行过的语句,你可以从 `STATEMENTS_SUMMARY` 或 `STATEMENTS_SUMMARY_HISTORY` 中根据 SQL Digest 查找到对应的 SQL 原文。
- 对于整个集群所有 TiDB 节点在最近一段时间内执行过的语句,你可以从 `CLUSTER_STATEMENTS_SUMMARY` 或`CLUSTER_STATEMENTS_SUMMARY_HISTORY` 中根据 SQL Digest 查找到对应的 SQL 原文。

{{< copyable "sql" >}}

```sql
select digest, digest_text from information_schema.statements_summary where digest = "f7530877a35ae65300c42250abd8bc731bbaf0a7cabc05dab843565230611bb2";
```

```sql
+------------------------------------------------------------------+---------------------------------------+
| digest | digest_text |
+------------------------------------------------------------------+---------------------------------------+
| f7530877a35ae65300c42250abd8bc731bbaf0a7cabc05dab843565230611bb2 | update `t` set `v` = ? where `id` = ? |
+------------------------------------------------------------------+---------------------------------------+
KEY: 7480000000000000355F728000000000000001
KEY_INFO: {"db_id":1,"db_name":"test","table_id":53,"table_name":"t","handle_type":"int","handle_value":"1"}
TRX_ID: 426790594290122753
CURRENT_HOLDING_TRX_ID: 426790590082449409
SQL_DIGEST: 38b03afa5debbdf0326a014dbe5012a62c51957f1982b3093e748460f8b00821
SQL_DIGEST_TEXT: update `t` set `v` = `v` + ? where `id` = ?
1 row in set (0.01 sec)
```

关于 SQL Digest 和 `STATEMENTS_SUMMARY`、`STATEMENTS_SUMMARY_HISTORY` 、`CLUSTER_STATEMENTS_SUMMARY`、`CLUSTER_STATEMENTS_SUMMARY_HISTORY` 表的详细说明,请参阅 [Statement Summary Tables](/statement-summary-tables.md)
以上查询结果显示,ID 为 `425405024158875649` 的事务在执行 Digest 为 `"f7530877a35ae65300c42250abd8bc731bbaf0a7cabc05dab843565230611bb22"`、形如 ``update `t` set `v` = `v` + ? where `id` = ?`` 的语句的过程中,试图在 `"7480000000000000355f728000000000000002"` 这个 key 上获取悲观锁,但是该 key 上的锁目前被 ID 为 `425405016242126849` 的事务持有
Loading