文档首页
MySQL 9.0 参考手册
相关文档 下载此手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


17.15.2.1 使用 InnoDB 事务和锁定信息

本节介绍如何使用性能架构 data_locksdata_lock_waits 表公开的锁定信息。

识别阻塞事务

有时识别哪些事务阻塞了另一个事务很有帮助。包含有关 InnoDB 事务和数据锁的信息的表使您能够确定哪个事务正在等待另一个事务,以及正在请求哪个资源。(有关这些表的描述,请参阅 第 17.15.2 节,“InnoDB INFORMATION_SCHEMA 事务和锁定信息”。)

假设三个会话正在并发运行。每个会话对应一个 MySQL 线程,并在另一个线程之后执行一个事务。考虑当这些会话发出以下语句时系统的状态,但还没有任何一个提交其事务

  • 会话 A

    BEGIN;
    SELECT a FROM t FOR UPDATE;
    SELECT SLEEP(100);
  • 会话 B

    SELECT b FROM t FOR UPDATE;
  • 会话 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 值,请参阅 在发出会话变为空闲后识别阻塞查询

等待 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

在上面的表中,您可以通过 等待查询阻塞查询 列识别会话。正如您所看到的

  • 会话 B (trx id A4, 线程 6) 和会话 C (trx id A5, 线程 7) 都在等待会话 A (trx id A3, 线程 5)。

  • 会话 C 正在等待会话 B 和会话 A。

您可以在 INFORMATION_SCHEMA INNODB_TRX 表和性能架构 data_locksdata_lock_waits 表中看到底层数据。

下表显示了 INNODB_TRX 表的一些示例内容。

trx id trx 状态 trx 开始时间 trx 请求的锁 ID trx 等待开始时间 trx 权重 trx MySQL 线程 ID trx 查询
A3 RUN­NING 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
识别发出会话变为空闲后的阻塞查询

在识别阻塞事务时,如果发出查询的会话变为空闲,则会报告阻塞查询的 NULL 值。在这种情况下,请使用以下步骤来确定阻塞查询。

  1. 确定阻塞事务的 processlist ID。在 sys.innodb_lock_waits 表中,阻塞事务的 processlist ID 是 blocking_pid 值。

  2. 使用 blocking_pid,查询 MySQL Performance Schema threads 表以确定阻塞事务的 THREAD_ID。例如,如果 blocking_pid 为 6,则发出以下查询

    SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = 6;
  3. 使用 THREAD_ID,查询 Performance Schema events_statements_current 表以确定线程执行的最后一个查询。例如,如果 THREAD_ID 为 28,则发出以下查询

    SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current
    WHERE THREAD_ID = 28\G
  4. 如果线程执行的最后一个查询不足以确定锁定的原因,则可以查询 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 会话关联起来

有时,将内部 InnoDB 锁定信息与 MySQL 保持的会话级信息关联起来很有用。例如,您可能想知道,对于给定的 InnoDB 事务 ID,相应的 MySQL 会话 ID 和可能持有锁的会话名称,以及因此阻塞其他事务的会话名称。

以下来自 INFORMATION_SCHEMA INNODB_TRX 表和 Performance Schema data_locksdata_lock_waits 表的输出取自一个负载较重的系统。如您所见,有多个事务正在运行。

以下 data_locksdata_lock_waits 表显示

  • 事务 77F(正在执行 INSERT)正在等待事务 77E77D77B 提交。

  • 事务 77E(正在执行 INSERT)正在等待事务 77D77B 提交。

  • 事务 77D(正在执行 INSERT)正在等待事务 77B 提交。

  • 事务 77B(正在执行 INSERT)正在等待事务 77A 提交。

  • 事务 77A 正在运行,当前正在执行 SELECT.

  • 事务 E56(正在执行 INSERT)正在等待事务 E55 提交。

  • 事务 E55(正在执行 INSERT)正在等待事务 19C 提交。

  • 事务 19C 正在运行,当前正在执行 INSERT.

注意

INFORMATION_SCHEMA PROCESSLISTINNODB_TRX 表中显示的查询之间可能存在不一致。有关解释,请参见 第 17.15.2.3 节,“InnoDB 事务和锁定信息的持久性和一致性”.

下表显示了运行繁重 工作负载 的系统的 PROCESSLIST 表的内容。

ID USER HOST DB COMMAND TIME STATE INFO
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 id trx 状态 trx 开始时间 trx 请求的锁 ID trx 等待开始时间 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 RUN­NING 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 RUN­NING 2008-01-15 13:09:10 NULL NULL 2900 130 INSERT INTO t2 VALUES …
E15 RUN­NING 2008-01-15 13:08:59 NULL NULL 5395 61 INSERT INTO t2 VALUES …
51D RUN­NING 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