29.19.2 获取父事件信息
表格data_locks
显示了数据锁定的持有和请求。该表的行具有一个THREAD_ID
列,表示会话ID,该会话拥有锁,并且有一个EVENT_ID
列,表示性能_schema事件导致锁定。(THREAD_ID, EVENT_ID)
值的组合隐式标识在其他性能_schema表中的父事件:
-
等待事件在
events_waits_
表中xxx
-
阶段事件在
events_stages_
表中xxx
-
语句事件在
events_statements_
表中xxx
-
事务事件在
events_transactions_current
表中
要获取父事件的详细信息,请将THREAD_ID
和EVENT_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 */
)
连接的条件是:
-
父事件与子事件在同一线程中。
-
子事件开始于父事件之后,因此其
EVENT_ID
值大于父事件的值。 -
父事件已完成或仍在运行。
要找到锁定信息,请使用data_locks
表,该表包含子事件。
由于data_locks
表只显示现有锁,因此关于哪个表包含父事件的考虑如下:
-
对于事务,只有一种选择,即
events_transactions_current
。如果事务已完成,它可能在事务历史表中,但锁定已经消失。 -
对于语句,情况取决于是否该语句持有锁是在一个已经完成的事务中执行的(使用
events_statements_history
)还是该语句仍在运行(使用events_statements_current
)。 -
对于阶段,逻辑与语句类似;使用
events_stages_history
或events_stages_current
。 -
对于等待,逻辑与语句类似;使用
events_waits_history
或events_waits_current
。然而,由于等待事件记录的数量很多,导致锁定的等待可能已经从历史表中消失。
等待、阶段和语句事件很快就会从历史表中消失。如果一个长时间之前执行的语句持有了锁但仍在打开的事务中,它可能无法找到该语句,但可以找到事务。
这就是嵌套集合数据模型如何更好地定位父事件。跟随父/子关系中的链接(数据锁定-> 父等待-> 父阶段-> 父事务)在历史表中已消失的节点上不太有效。
以下是一个场景,说明如何找到一个语句所持有的父事务的锁定:
会话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