Documentation Home

27.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 列与相应父事件表中名称相似的列连接起来。该关系基于嵌套集数据模型,因此连接有多个子句。parent给定分别由和 表示的父表和子表child,连接如下所示:

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