Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

29.19.2 获取父事件信息

The data_locks 表显示数据锁的持有和请求。该表的行具有 THREAD_ID 列,指示拥有锁的会话的线程 ID,以及 EVENT_ID 列,指示导致锁的性能模式事件。 tuples of (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 表,除非事务外,假设服务器上没有其他查询运行(以便保留历史记录)。