-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Lock View related documents (#6408)
- Loading branch information
1 parent
5f4b573
commit 56793a8
Showing
7 changed files
with
580 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
--- | ||
title: DATA_LOCK_WAITS | ||
summary: 了解 information_schema 表 `DATA_LOCK_WAITS`。 | ||
--- | ||
|
||
# DATA_LOCK_WAITS | ||
|
||
`DATA_LOCK_WAITS` 表展示了集群中所有 TiKV 节点上当前正在发生的悲观锁等锁的情况。 | ||
|
||
> **警告:** | ||
> | ||
> 该功能目前为实验性功能,表结构的定义和行为在未来版本中可能有较大改动。 | ||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
USE information_schema; | ||
DESC data_lock_waits; | ||
``` | ||
|
||
```sql | ||
+------------------------+---------------------+------+------+---------+-------+ | ||
| Field | Type | Null | Key | Default | Extra | | ||
+------------------------+---------------------+------+------+---------+-------+ | ||
| KEY | varchar(64) | NO | | NULL | | | ||
| TRX_ID | bigint(21) unsigned | NO | | NULL | | | ||
| CURRENT_HOLDING_TRX_ID | bigint(21) unsigned | NO | | NULL | | | ||
| SQL_DIGEST | varchar(64) | YES | | NULL | | | ||
+------------------------+---------------------+------+------+---------+-------+ | ||
``` | ||
|
||
`DATA_LOCK_WAITS` 表中各列的字段含义如下: | ||
|
||
* `KEY`:正在发生等锁的 KEY,以十六进制编码的形式显示。 | ||
* `TRX_ID`:正在等锁的事务 ID,即 `start_ts`。 | ||
* `CURRENT_HOLDING_TRX_ID`:当前持有锁的事务 ID,即 `start_ts`。 | ||
* `SQL_DIGEST`:当前正在等锁的事务中被阻塞的 SQL 语句的 Digest。 | ||
|
||
> **警告:** | ||
> | ||
> * 该表中的信息是在查询时,从所有 TiKV 节点实时获取的。目前,即使加上了 `WHERE` 查询条件,也无法避免对所有 TiKV 节点都进行信息收集。如果集群规模很大、负载很高,查询该表有造成性能抖动的潜在风险,因此请根据实际情况使用。 | ||
> * 来自不同 TiKV 节点的信息不一定是同一时间点的快照。 | ||
## 示例 | ||
|
||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
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` = ? | | ||
+------------------------------------------------------------------+---------------------------------------+ | ||
``` | ||
|
||
关于 SQL Digest 和 `STATEMENTS_SUMMARY`、`STATEMENTS_SUMMARY_HISTORY` 、`CLUSTER_STATEMENTS_SUMMARY`、`CLUSTER_STATEMENTS_SUMMARY_HISTORY` 表的详细说明,请参阅 [Statement Summary Tables](/statement-summary-tables.md)。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
--- | ||
title: DEADLOCKS | ||
summary: 了解 information_schema 表 `DEADLOCKS`。 | ||
--- | ||
|
||
# DEADLOCKS | ||
|
||
`DEADLOCKS` 表提供当前 TiDB 节点上最近发生的若干次死锁错误的信息。 | ||
|
||
> **警告:** | ||
> | ||
> 该功能目前为实验性功能,表结构的定义和行为在未来版本中可能有较大改动。 | ||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
USE information_schema; | ||
DESC deadlocks; | ||
``` | ||
|
||
```sql | ||
+--------------------+---------------------+------+------+---------+-------+ | ||
| Field | Type | Null | Key | Default | Extra | | ||
+--------------------+---------------------+------+------+---------+-------+ | ||
| DEADLOCK_ID | bigint(21) | NO | | NULL | | | ||
| OCCUR_TIME | timestamp(6) | YES | | NULL | | | ||
| RETRYABLE | tinyint(1) | NO | | NULL | | | ||
| TRY_LOCK_TRX_ID | bigint(21) unsigned | NO | | NULL | | | ||
| CURRENT_SQL_DIGEST | varchar(64) | YES | | NULL | | | ||
| KEY | text | YES | | NULL | | | ||
| TRX_HOLDING_LOCK | bigint(21) unsigned | NO | | NULL | | | ||
+--------------------+---------------------+------+------+---------+-------+ | ||
``` | ||
|
||
`DEADLOCKS` 表中需要用多行来表示同一个死锁事件,每行显示参与死锁的其中一个事务的信息。当该 TiDB 节点记录了多次死锁错误时,需要按照 `DEADLOCK_ID` 列来区分,相同的 `DEADLOCK_ID` 表示同一个死锁事件。需要注意,`DEADLOCK_ID` **并不保证全局唯一,也不会持久化**,因而其只能在同一个结果集里表示同一个死锁事件。 | ||
|
||
`DEADLOCKS` 表中各列的字段含义如下: | ||
|
||
* `DEADLOCK_ID`:死锁事件的 ID。当表内存在多次死锁错误的信息时,需要使用该列来区分属于不同死锁错误的行。 | ||
* `OCCUR_TIME`:发生该次死锁错误的时间。 | ||
* `RETRYABLE`:该次死锁错误是否可重试。目前暂不支持收集可重试的死锁错误的信息,因而该字段值恒为 0。关于可重试的死锁错误的说明,参见[可重试的死锁错误](#可重试的死锁错误)小节。 | ||
* `TRY_LOCK_TRX_ID`:试图上锁的事务 ID,即事务的 `start_ts`。 | ||
* `CURRENT_SQL_DIGEST`:试图上锁的事务中当前正在执行的 SQL 语句的 Digest。 | ||
* `KEY`:该事务试图上锁、但是被阻塞的 key,以十六进制编码的形式显示。 | ||
* `TRX_HOLDING_LOCK`:该 key 上当前持锁并导致阻塞的事务 ID,即事务的 `start_ts`。 | ||
|
||
要调整 `DEADLOCKS` 表中可以容纳的死锁事件数量,可通过 TiDB 配置文件中的 [`pessimistic-txn.deadlock-history-capacity`](/tidb-configuration-file.md#deadlock-history-capacity) 配置项进行调整,默认容纳最近 10 次死锁错误的信息。 | ||
|
||
## 示例 1 | ||
|
||
假设有如下表定义和初始数据: | ||
|
||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
create table t (id int primary key, v int); | ||
insert into t values (1, 10), (2, 20); | ||
``` | ||
|
||
使两个事务按如下顺序执行: | ||
|
||
| 事务 1 | 事务 2 | 说明 | | ||
|--------------------------------------|--------------------------------------|----------------------| | ||
| `update t set v = 11 where id = 1;` | | | | ||
| | `update t set v = 21 where id = 2;` | | | ||
| `update t set v = 12 where id = 2;` | | 事务 1 阻塞 | | ||
| | `update t set v = 22 where id = 1;` | 事务 2 报出死锁错误 | | ||
|
||
接下来,事务 2 将报出死锁错误。此时,查询 `DEADLOCKS` 表,将得到如下结果: | ||
|
||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
select * from information_schema.deadlocks; | ||
``` | ||
|
||
```sql | ||
+-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+----------------------------------------+--------------------+ | ||
| DEADLOCK_ID | OCCUR_TIME | RETRYABLE | TRY_LOCK_TRX_ID | CURRENT_SQL_DIGEST | KEY | TRX_HOLDING_LOCK | | ||
+-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+----------------------------------------+--------------------+ | ||
| 1 | 2021-06-04 08:22:38.765699 | 0 | 425405959304904707 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000002 | 425405959304904708 | | ||
| 1 | 2021-06-04 08:22:38.765699 | 0 | 425405959304904708 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000001 | 425405959304904707 | | ||
+-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+----------------------------------------+--------------------+ | ||
``` | ||
|
||
该表中产生了两行数据,两行的 `DEADLOCK_ID` 字段皆为 1,表示这两行数据包含同一次死锁错误的信息。第一行显示 ID 为 `425405959304904707` 的事务,在 `"7480000000000000385F728000000000000002"` 这个 key 上,被 ID 为 `"425405959304904708"` 的事务阻塞了;第二行则显示 ID 为 `"425405959304904708"` 的事务在 `"7480000000000000385F728000000000000001"` 这个 key 上被 ID 为 `425405959304904707` 的事务阻塞了,构成了相互阻塞的状态,形成了死锁。 | ||
|
||
## 示例 2 | ||
|
||
假设查询 `DEADLOCKS` 表得到了如下结果集: | ||
|
||
```sql | ||
+-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+----------------------------------------+--------------------+ | ||
| DEADLOCK_ID | OCCUR_TIME | RETRYABLE | TRY_LOCK_TRX_ID | CURRENT_SQL_DIGEST | KEY | TRX_HOLDING_LOCK | | ||
+-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+----------------------------------------+--------------------+ | ||
| 1 | 2021-06-04 08:22:38.765699 | 0 | 425405959304904707 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000002 | 425405959304904708 | | ||
| 1 | 2021-06-04 08:22:38.765699 | 0 | 425405959304904708 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000001 | 425405959304904707 | | ||
| 2 | 2021-06-04 08:22:56.795410 | 0 | 425405961664462853 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000002 | 425405961664462854 | | ||
| 2 | 2021-06-04 08:22:56.795410 | 0 | 425405961664462854 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000003 | 425405961664462855 | | ||
| 2 | 2021-06-04 08:22:56.795410 | 0 | 425405961664462855 | 22230766411edb40f27a68dadefc63c6c6970d5827f1e5e22fc97be2c4d8350d | 7480000000000000385F728000000000000001 | 425405961664462853 | | ||
+-------------+----------------------------+-----------+--------------------+------------------------------------------------------------------+----------------------------------------+--------------------+ | ||
``` | ||
|
||
以上查询结果中的 `DEADLOCK_ID` 列表明,前两行共同表示一次死锁错误的信息,两条事务相互等待构成了死锁;而后三行共同表示另一次死锁信息,三个事务循环等待构成了死锁。 | ||
|
||
## 可重试的死锁错误 | ||
|
||
> **注意:** | ||
> | ||
> 目前,`DEADLOCKS` 表暂不支持收集可重试的死锁错误相关的信息。 | ||
当事务 A 被另一个事务已经持有的锁阻塞,而事务 B 直接或间接地被当前事务持有的锁阻塞,将会引发一个死锁错误。这里: | ||
|
||
+ 情况一:事务 B 可能(直接或间接地)被事务 A 之前已经执行完的语句产生的锁阻塞 | ||
+ 情况二:事务 B 也可能被事务 A 目前正在执行的语句阻塞 | ||
|
||
对于情况一,TiDB 将会向事务 A 的客户端报告死锁错误,并终止该事务;而对于情况二,事务 A 当前正在执行的语句将在 TiDB 内部被自动重试。例如,假设事务 A 执行了如下语句: | ||
|
||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
update t set v = v + 1 where id = 1 or id = 2; | ||
``` | ||
|
||
事务 B 则先后执行如下两条语句: | ||
|
||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
update t set v = 4 where id = 2; | ||
update t set v = 2 where id = 1; | ||
``` | ||
|
||
那么如果事务 A 先后对 `id = 1` 和 `id = 2` 的两行分别上锁,且两个事务以如下时序运行: | ||
|
||
1. 事务 A 对 `id = 1` 的行上锁 | ||
2. 事务 B 执行第一条语句并对 `id = 2` 的行上锁 | ||
3. 事务 B 执行第二条语句试图对 `id = 1` 的行上锁,被事务 A 阻塞 | ||
4. 事务 A 试图对 `id = 2` 的行上锁,被 B 阻塞,形成死锁 | ||
|
||
对于情况二,由于事务 A 阻塞其它事务的语句也是当前正在执行的语句,因而可以解除当前语句所上的悲观锁(使得事务 B 可以继续运行),并重试当前语句。TiDB 内部使用 key 的 hash 来判断是否属于这种情况。 | ||
|
||
当可重试的死锁发生时,内部自动重试并不会引起事务报错,因而对客户端透明,但是这种情况的频繁发生可能影响性能。当这种情况发生时,在 TiDB 的日志中可以观察到 `single statement deadlock, retry statement` 字样的日志。 | ||
|
||
## CLUSTER_DEADLOCKS | ||
|
||
`CLUSTER_DEADLOCKS` 表返回整个集群上每个 TiDB 节点中最近发生的数次死锁错误的信息,即将每个节点上的 `DEADLOCKS` 表内的信息合并在一起。`CLUSTER_DEADLOCKS` 还包含额外的 `INSTANCE` 列展示所属节点的 IP 地址和端口,用以区分不同的 TiDB 节点。 | ||
|
||
需要注意的是,由于 `DEADLOCK_ID` 并不保证全局唯一,所以在 `CLUSTER_DEADLOCKS` 表的查询结果中,需要 `INSTANCE` 和 `DEADLOCK_ID` 两个字段共同区分结果集中的不同死锁错误的信息。 | ||
|
||
{{< copyable "sql" >}} | ||
|
||
```sql | ||
USE information_schema; | ||
DESC cluster_deadlocks; | ||
``` | ||
|
||
```sql | ||
+--------------------+---------------------+------+------+---------+-------+ | ||
| Field | Type | Null | Key | Default | Extra | | ||
+--------------------+---------------------+------+------+---------+-------+ | ||
| INSTANCE | varchar(64) | YES | | NULL | | | ||
| DEADLOCK_ID | bigint(21) | NO | | NULL | | | ||
| OCCUR_TIME | timestamp(6) | YES | | NULL | | | ||
| RETRYABLE | tinyint(1) | NO | | NULL | | | ||
| TRY_LOCK_TRX_ID | bigint(21) unsigned | NO | | NULL | | | ||
| CURRENT_SQL_DIGEST | varchar(64) | YES | | NULL | | | ||
| KEY | text | YES | | NULL | | | ||
| TRX_HOLDING_LOCK | bigint(21) unsigned | NO | | NULL | | | ||
+--------------------+---------------------+------+------+---------+-------+ | ||
``` | ||
|
||
## SQL Digest | ||
|
||
`DEADLOCKS` 表记录 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` = ? | | ||
+------------------------------------------------------------------+---------------------------------------+ | ||
``` | ||
|
||
关于 SQL Digest 和 `STATEMENTS_SUMMARY`、`STATEMENTS_SUMMARY_HISTORY`、`CLUSTER_STATEMENTS_SUMMARY`、`CLUSTER_STATEMENTS_SUMMARY_HISTORY` 表的详细说明,请参阅 [Statement Summary Tables](/statement-summary-tables.md)。 |
Oops, something went wrong.