该data_locks
表显示持有和请求的数据锁。该表的行有一个
THREAD_ID
列指示拥有锁的会话的线程 ID,以及一个
EVENT_ID
指示导致锁的性能模式事件的列。( THREAD_ID
, EVENT_ID
) 值的元组隐式标识其他性能模式表中的父事件:
表 中的父等待事件
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
. 如果事务已完成,它可能在事务历史表中,但锁已经消失了。对于语句,这完全取决于获取锁的语句是已经完成(use
events_statements_history
)的事务中的语句还是仍在运行(useevents_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