文档首页
MySQL 8.4 参考手册
8.4 中文镜像

MySQL 8.4 参考手册 · 中文镜像

正文为中文,英文原文默认隐藏。点击任意中文段落即可展开 / 收起对应英文原文。

打开官方英文原文 ↗

译文由机器翻译生成,仅供理解参考;有疑问请以官方英文原文为准。

中文点击中文段落可显示 / 隐藏英文原文本页译文覆盖 100%

29.19.2 获取父事件信息29.19.2 Obtaining Parent Event Information

data_locks 表显示了持有和请求的数据锁。该表的行有一个 THREAD_ID 列,表示拥有锁的会话的线程 ID,还有一个 EVENT_ID 列,表示导致该锁的 Performance Schema 事件。(THREAD_ID, EVENT_ID) 值的元组在其他 Performance Schema 表中隐式标识一个父事件:The data_locks table shows data locks held and requested. Rows of this table have a THREAD_ID column indicating the thread ID of the session that owns the lock, and an EVENT_ID column indicating the Performance Schema event that caused the lock. Tuples of (THREAD_ID, EVENT_ID) values implicitly identify a parent event in other Performance Schema tables:

  • events_waits_xxx 表中的父等待事件The parent wait event in the events_waits_xxx tables

  • events_stages_xxx 表中的父阶段事件The parent stage event in the events_stages_xxx tables

  • 在 events_statements_xxx 表中的父语句事件The parent statement event in the events_statements_xxx tables

  • 在 events_transactions_current 表中的父事务事件The parent transaction event in the events_transactions_current table

要获取有关父事件的详细信息,将 THREAD_ID 和 EVENT_ID 列与相应父事件表中同名列进行连接。该关系基于嵌套集数据模型,因此连接包含多个条件。给定由 parent 和 child 表示的父表和子表,连接如下所示:To obtain details about the parent event, join the THREAD_ID and EVENT_ID columns with the columns of like name in the appropriate parent event table. The relation is based on a nested set data model, so the join has several clauses. Given parent and child tables represented by parent and child, respectively, the join looks like this:

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 */
  )

连接条件为:The conditions for the join are:

  1. 父事件和子事件在同一线程中。The parent and child events are in the same thread.

  2. 子事件在父事件之后开始,因此其 EVENT_ID 值大于父事件的值。The child event begins after the parent event, so its EVENT_ID value is greater than that of the parent.

  3. 父事件要么已经完成,要么仍在运行中。The parent event has either completed or is still running.

要查找锁信息,data_locks 表包含子事件。To find lock information, data_locks is the table containing child events.

data_locks 表仅显示现有锁,因此关于哪个表包含父事件,应考虑以下内容:The data_locks table shows only existing locks, so these considerations apply regarding which table contains the parent event:

等待、阶段和语句事件会很快从历史中消失。如果一个很久之前执行的语句获取了锁但事务仍然未提交,可能无法找到该语句,但可以找到该事务。Wait, stage, and statement events disappear quickly from the history. If a statement that executed a long time ago took a lock but is in a still-open transaction, it might not be possible to find the statement, but it is possible to find the transaction.

这就是为什么嵌套集合数据模型在定位父事件时更有效。当中间节点已经从历史表中消失时,通过父/子关系(数据锁 -> 父等待 -> 父阶段 -> 父事务)进行链接通常行不通。This is why the nested set data model works better for locating parent events. Following links in a parent/child relationship (data lock -> parent wait -> parent stage -> parent transaction) does not work well when intermediate nodes are already gone from the history tables.

下面的场景说明了如何找到一个在其中获取了锁的语句的父事务:The following scenario illustrates how to find the parent transaction of a statement in which a lock was taken:

会话 A:Session A:

[1] START TRANSACTION;
[2] SELECT * FROM t1 WHERE pk = 1;
[3] SELECT 'Hello, world';

会话 B:Session 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 的记录上的数据锁。The query for session B should show statement [2] as owning a data lock on the record with pk=1.

如果会话 A 执行更多语句,[2] 会在历史表中消失。If session A executes more statements, [2] fades out of the history table.

查询应显示从 [1] 开始的事务,无论执行了多少语句、阶段或等待。The query should show the transaction that started in [1], regardless of how many statements, stages, or waits were executed.

要查看更多数据,你也可以使用 events_xxx_history_long 表,除了 transactions,前提是假设服务器上没有其他查询运行(以便历史数据得以保留)。To see more data, you can also use the events_xxx_history_long tables, except for transactions, assuming no other query runs in the server (so that history is preserved).