文档首页
MySQL 8.4 参考手册
相关文档 下载本手册
PDF (US Ltr) - 39.9Mb
PDF (A4) - 40.0Mb
手册页 (TGZ) - 258.5Kb
手册页 (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 参考手册  /  ...  /  获取父事件信息

29.19.2 获取父事件信息

data_locks 表显示已持有的数据锁和请求的数据锁。此表的行有一个 THREAD_ID 列,指示拥有锁的会话的线程 ID,以及一个 EVENT_ID 列,指示导致锁定的性能模式事件。 (THREAD_ID, EVENT_ID) 值的元组隐式地标识了其他性能模式表中的父事件。

  • events_waits_xxx 表中的父等待事件

  • events_stages_xxx 表中的父阶段事件

  • events_statements_xxx 表中的父语句事件

  • events_transactions_current 表中的父事务事件

要获取有关父事件的详细信息,请将 THREAD_IDEVENT_ID 列与相应父事件表中同名的列联接。该关系基于嵌套集数据模型,因此联接包含多个子句。假设分别由 parentchild 表示的父表和子表,则联接如下所示

WHERE
  parent.THREAD_ID = child.THREAD_ID        /* 1 */
  AND parent.EVENT_ID < child.EVENT_ID      /* 2 */
  AND (
    child.EVENT_ID <= parent.END_EVENT_ID   /* 3a */
    OR parent.END_EVENT_ID IS NULL          /* 3b */
  )

联接的条件是

  1. 父事件和子事件位于同一线程中。

  2. 子事件在父事件之后开始,因此其 EVENT_ID 值大于父事件的值。

  3. 父事件已完成或仍在运行。

要查找锁定信息,data_locks 是包含子事件的表。

data_locks 表仅显示现有锁,因此关于哪个表包含父事件,以下注意事项适用

等待、阶段和语句事件会很快从历史记录中消失。如果很久以前执行的语句获取了锁,但仍处于打开的事务中,则可能无法找到该语句,但可以找到该事务。

这就是为什么嵌套集数据模型更适合定位父事件的原因。在父/子关系(数据锁 -> 父等待 -> 父阶段 -> 父事务)中遵循链接在中间节点已从历史表中消失时效果不佳。

以下场景说明了如何查找获取锁的语句的父事务

会话 A

[1] START TRANSACTION;
[2] SELECT * FROM t1 WHERE pk = 1;
[3] SELECT 'Hello, world';

会话 B

SELECT ...
FROM performance_schema.events_transactions_current AS parent
  INNER JOIN performance_schema.data_locks AS child
WHERE
  parent.THREAD_ID = child.THREAD_ID
  AND parent.EVENT_ID < child.EVENT_ID
  AND (
    child.EVENT_ID <= parent.END_EVENT_ID
    OR parent.END_EVENT_ID IS NULL
  );

对于会话 B 的查询应该显示语句 [2] 拥有对记录 pk=1 的数据锁。

如果会话 A 执行更多语句,[2] 将从历史表中消失。

无论执行了多少语句、阶段或等待,查询都应该显示在 [1] 中开始的事务。

要查看更多数据,还可以使用 events_xxx_history_long 表,除了事务,假设服务器中没有其他查询运行(这样可以保留历史记录)。