笔记
本节描述了由性能模式data_locks
和 data_lock_waits
表公开的锁定信息,它们取代了MySQL 8.0 中的INFORMATION_SCHEMA
INNODB_LOCKS
和 INNODB_LOCK_WAITS
表。有关根据旧INFORMATION_SCHEMA
表编写的类似讨论,请参阅 MySQL 5.7 参考手册中的Using InnoDB Transaction and Locking Information。
识别阻塞事务
有时识别哪个事务阻塞了另一个事务是有帮助的。包含有关 InnoDB
事务和数据锁的信息的表使您能够确定哪个事务正在等待另一个事务,以及正在请求哪个资源。(有关这些表的描述,请参阅 第 15.15.2 节,“InnoDB INFORMATION_SCHEMA 事务和锁定信息”。)
假设三个session同时运行。每个session对应一个 MySQL 线程,一个接一个地执行事务。当这些session发出以下语句但还没有提交其事务时,请考虑系统的状态:
-
session A:
BEGIN; SELECT a FROM t FOR UPDATE; SELECT SLEEP(100);
复制 -
session B:
SELECT b FROM t FOR UPDATE;
复制 -
session C:
SELECT c FROM t FOR UPDATE;
复制
在这种情况下,使用以下查询来查看哪些事务正在等待以及哪些事务正在阻塞它们:
SELECT
r.trx_id waiting_trx_id,
r.trx_mysql_thread_id waiting_thread,
r.trx_query waiting_query,
b.trx_id blocking_trx_id,
b.trx_mysql_thread_id blocking_thread,
b.trx_query blocking_query
FROM performance_schema.data_lock_waits w
INNER JOIN information_schema.innodb_trx b
ON b.trx_id = w.blocking_engine_transaction_id
INNER JOIN information_schema.innodb_trx r
ON r.trx_id = w.requesting_engine_transaction_id;
复制
或者,更简单地说,使用sys
模式 innodb_lock_waits
视图:
SELECT
waiting_trx_id,
waiting_pid,
waiting_query,
blocking_trx_id,
blocking_pid,
blocking_query
FROM sys.innodb_lock_waits;
复制
如果为阻塞查询报告了 NULL 值,请参阅 在发出session变为空闲后识别阻塞查询。
等待 trx id | 等待线程 | 等待查询 | 阻止 trx id | 阻塞线程 | 阻塞查询 |
---|---|---|---|---|---|
A4 |
6 |
SELECT b FROM t FOR UPDATE |
A3 |
5 |
SELECT SLEEP(100) |
A5 |
7 |
SELECT c FROM t FOR UPDATE |
A3 |
5 |
SELECT SLEEP(100) |
A5 |
7 |
SELECT c FROM t FOR UPDATE |
A4 |
6 |
SELECT b FROM t FOR UPDATE |
在上表中,您可以通过 “等待查询”或“阻塞查询” 列来识别session。如你看到的:
- session B (trx id
A4
, thread6
) 和session C (trx idA5
, thread7
) 都在等待session A (trx idA3
, thread5
)。 - session C 正在等待session B 以及session A。
INFORMATION_SCHEMA
INNODB_TRX
您可以在表和 Performance Schemadata_locks
和 表 中看到基础数据 data_lock_waits
。
下表显示了该表的一些示例内容 INNODB_TRX
。
交易编号 | 状态 | trx 开始 | trx 请求的锁 id | trx 等待开始 | 重量 | trx mysql线程id | trx 查询 |
---|---|---|---|---|---|---|---|
A3 |
RUNNING |
2008-01-15 16:44:54 |
NULL |
NULL |
2 |
5 |
SELECT SLEEP(100) |
A4 |
LOCK WAIT |
2008-01-15 16:45:09 |
A4:1:3:2 |
2008-01-15 16:45:09 |
2 |
6 |
SELECT b FROM t FOR UPDATE |
A5 |
LOCK WAIT |
2008-01-15 16:45:14 |
A5:1:3:2 |
2008-01-15 16:45:14 |
2 |
7 |
SELECT c FROM t FOR UPDATE |
下表显示了该表的一些示例内容 data_locks
。
锁ID | 锁定 trx id | 锁定模式 | 锁型 | 锁模式 | 锁表 | 锁定索引 | 锁定数据 |
---|---|---|---|---|---|---|---|
A3:1:3:2 |
A3 |
X |
RECORD |
test |
t |
PRIMARY |
0x0200 |
A4:1:3:2 |
A4 |
X |
RECORD |
test |
t |
PRIMARY |
0x0200 |
A5:1:3:2 |
A5 |
X |
RECORD |
test |
t |
PRIMARY |
0x0200 |
下表显示了该表的一些示例内容 data_lock_waits
。
请求 trx id | 请求的锁 ID | 阻止 trx id | 阻塞锁ID |
---|---|---|---|
A4 |
A4:1:3:2 |
A3 |
A3:1:3:2 |
A5 |
A5:1:3:2 |
A3 |
A3:1:3:2 |
A5 |
A5:1:3:2 |
A4 |
A4:1:3:2 |
在发出session变为空闲后识别阻塞查询
识别阻塞事务时,如果发出查询的session已空闲,则为阻塞查询报告 NULL 值。在这种情况下,请使用以下步骤来确定阻塞查询:
-
识别阻塞事务的进程列表 ID。在
sys.innodb_lock_waits
表中,阻塞事务的进程列表 ID 是blocking_pid
值。 -
使用
blocking_pid
,查询 MySQL Performance Schemathreads
表以确定THREAD_ID
阻塞事务的。例如,如果blocking_pid
是 6,则发出以下查询:SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = 6;
复制 -
使用
THREAD_ID
,查询 Performance Schemaevents_statements_current
表以确定线程执行的最后一个查询。例如,如果THREAD_ID
是 28,请发出以下查询:SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current WHERE THREAD_ID = 28\G
复制 -
如果线程执行的最后一个查询没有足够的信息来确定持有锁的原因,您可以查询 Performance Schema
events_statements_history
表以查看线程执行的最后 10 条语句。SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_history WHERE THREAD_ID = 28 ORDER BY EVENT_ID;
复制
将 InnoDB 事务与 MySQL session相关联
InnoDB
有时将内部锁定信息与 MySQL 维护的session级信息 相关联很有用 。例如,对于给定的InnoDB
事务 ID,您可能想知道相应的 MySQL session ID 和可能持有锁并因此阻塞其他事务的session的名称。
INFORMATION_SCHEMA
INNODB_TRX
表和性能模式data_locks
和 表 的以下输出 data_lock_waits
取自一个有些负载的系统。可以看出,有几个事务正在运行。
以下data_locks
和 data_lock_waits
表格显示:
- 事务
77F
(执行INSERT
)正在等待事务77E
、77D
和77B
提交。 - 事务
77E
(执行一个INSERT
)正在等待事务77D
并77B
提交。 - 事务
77D
(执行一个INSERT
)正在等待事务77B
提交。 - 事务
77B
(执行一个INSERT
)正在等待事务77A
提交。 - 事务
77A
正在运行,当前正在执行SELECT
。 - 事务
E56
(执行一个INSERT
)正在等待事务E55
提交。 - 事务
E55
(执行一个INSERT
)正在等待事务19C
提交。 - 事务
19C
正在运行,当前正在执行一个INSERT
.
笔记
INFORMATION_SCHEMA
PROCESSLIST
和 INNODB_TRX
表 中显示的查询之间可能存在不一致 。有关解释,请参阅 第 15.15.2.3 节,“InnoDB 事务和锁定信息的持久性和一致性”。
下表显示了 PROCESSLIST
运行繁重工作负载的系统的表格内容。
ID | 用户 | 主持人 | D B | 命令 | 时间 | 状态 | 信息 |
---|---|---|---|---|---|---|---|
384 |
root |
localhost |
test |
Query |
10 |
update |
INSERT INTO t2 VALUES … |
257 |
root |
localhost |
test |
Query |
3 |
update |
INSERT INTO t2 VALUES … |
130 |
root |
localhost |
test |
Query |
0 |
update |
INSERT INTO t2 VALUES … |
61 |
root |
localhost |
test |
Query |
1 |
update |
INSERT INTO t2 VALUES … |
8 |
root |
localhost |
test |
Query |
1 |
update |
INSERT INTO t2 VALUES … |
4 |
root |
localhost |
test |
Query |
0 |
preparing |
SELECT * FROM PROCESSLIST |
2 |
root |
localhost |
test |
Sleep |
566 |
`` | NULL |
下表显示了 INNODB_TRX
运行繁重工作负载的系统的表格内容。
交易编号 | 状态 | trx 开始 | trx 请求的锁 id | trx 等待开始 | 重量 | trx mysql线程id | trx 查询 |
---|---|---|---|---|---|---|---|
77F |
LOCK WAIT |
2008-01-15 13:10:16 |
77F |
2008-01-15 13:10:16 |
1 |
876 |
INSERT INTO t09 (D, B, C) VALUES … |
77E |
LOCK WAIT |
2008-01-15 13:10:16 |
77E |
2008-01-15 13:10:16 |
1 |
875 |
INSERT INTO t09 (D, B, C) VALUES … |
77D |
LOCK WAIT |
2008-01-15 13:10:16 |
77D |
2008-01-15 13:10:16 |
1 |
874 |
INSERT INTO t09 (D, B, C) VALUES … |
77B |
LOCK WAIT |
2008-01-15 13:10:16 |
77B:733:12:1 |
2008-01-15 13:10:16 |
4 |
873 |
INSERT INTO t09 (D, B, C) VALUES … |
77A |
RUNNING |
2008-01-15 13:10:16 |
NULL |
NULL |
4 |
872 |
SELECT b, c FROM t09 WHERE … |
E56 |
LOCK WAIT |
2008-01-15 13:10:06 |
E56:743:6:2 |
2008-01-15 13:10:06 |
5 |
384 |
INSERT INTO t2 VALUES … |
E55 |
LOCK WAIT |
2008-01-15 13:10:06 |
E55:743:38:2 |
2008-01-15 13:10:13 |
965 |
257 |
INSERT INTO t2 VALUES … |
19C |
RUNNING |
2008-01-15 13:09:10 |
NULL |
NULL |
2900 |
130 |
INSERT INTO t2 VALUES … |
E15 |
RUNNING |
2008-01-15 13:08:59 |
NULL |
NULL |
5395 |
61 |
INSERT INTO t2 VALUES … |
51D |
RUNNING |
2008-01-15 13:08:47 |
NULL |
NULL |
9807 |
8 |
INSERT INTO t2 VALUES … |
下表显示了 data_lock_waits
运行繁重 工作负载的系统的表格内容。
请求 trx id | 请求的锁 ID | 阻止 trx id | 阻塞锁ID |
---|---|---|---|
77F |
77F:806 |
77E |
77E:806 |
77F |
77F:806 |
77D |
77D:806 |
77F |
77F:806 |
77B |
77B:806 |
77E |
77E:806 |
77D |
77D:806 |
77E |
77E:806 |
77B |
77B:806 |
77D |
77D:806 |
77B |
77B:806 |
77B |
77B:733:12:1 |
77A |
77A:733:12:1 |
E56 |
E56:743:6:2 |
E55 |
E55:743:6:2 |
E55 |
E55:743:38:2 |
19C |
19C:743:38:2 |
下表显示了 data_locks
运行繁重工作负载的系统的表格内容。
锁ID | 锁定 trx id | 锁定模式 | 锁型 | 锁模式 | 锁表 | 锁定索引 | 锁定数据 |
---|---|---|---|---|---|---|---|
77F:806 |
77F |
AUTO_INC |
TABLE |
test |
t09 |
NULL |
NULL |
77E:806 |
77E |
AUTO_INC |
TABLE |
test |
t09 |
NULL |
NULL |
77D:806 |
77D |
AUTO_INC |
TABLE |
test |
t09 |
NULL |
NULL |
77B:806 |
77B |
AUTO_INC |
TABLE |
test |
t09 |
NULL |
NULL |
77B:733:12:1 |
77B |
X |
RECORD |
test |
t09 |
PRIMARY |
supremum pseudo-record |
77A:733:12:1 |
77A |
X |
RECORD |
test |
t09 |
PRIMARY |
supremum pseudo-record |
E56:743:6:2 |
E56 |
S |
RECORD |
test |
t2 |
PRIMARY |
0, 0 |
E55:743:6:2 |
E55 |
X |
RECORD |
test |
t2 |
PRIMARY |
0, 0 |
E55:743:38:2 |
E55 |
S |
RECORD |
test |
t2 |
PRIMARY |
1922, 1922 |
19C:743:38:2 |
19C |
X |
RECORD |
test |
t2 |
PRIMARY |
1922, 1922 |