Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


29.19.2 获取父事件信息

表格data_locks显示了数据锁定的持有和请求。该表的行具有一个THREAD_ID列,表示会话ID,该会话拥有锁,并且有一个EVENT_ID列,表示性能_schema事件导致锁定。(THREAD_ID, EVENT_ID)值的组合隐式标识在其他性能_schema表中的父事件:

要获取父事件的详细信息,请将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 表格,除了事务表,假设服务器上没有其他查询正在运行(以便保留历史记录)。