Spec-Zone.ru › MySQL 8.4

29.19.2 Получение информации о родительских событиях

Таблица data_locks отображает захваченные и запрошенные блокировки данных. Строки этой таблицы содержат столбец THREAD_ID, указывающий идентификатор потока сессии, которая владеет блокировкой, и столбец EVENT_ID, указывающий событие Performance Schema, вызвавшее блокировку. Кортежи значений (THREAD_ID, EVENT_ID) неявно идентифицируют родительское событие в других таблицах Performance 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 */
  )

Условия для соединения:

  1. Родительское и дочернее событие находятся в одном потоке.

  2. Дочернее событие начинается после родительского события, поэтому его значение EVENT_ID больше, чем у родительского.

  3. Родительское событие завершилось или всё ещё выполняется.

Для поиска информации о блокировках, таблица 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. Однако, из-за большого количества записей ожиданий, событие ожидания, вызвавшее блокировку, скорее всего, уже отсутствует в таблицах истории.

События ожидания, стадии и операторы быстро исчезают из истории. Если оператор, выполнивший длительную операцию и взявший блокировку, всё ещё находится в открытой транзакции, возможно, оператор не будет найден, но транзакция будет найдена.

Именно поэтому модель данных вложенных множеств лучше подходит для поиска родительских событий. Следование ссылкам в отношениях «родитель/ребёнок» (блокировка данных -> родительское ожидание -> родительская стадия -> родительская транзакция) неэффективно, когда промежуточные узлы уже удалены из таблиц истории.

Следующий сценарий иллюстрирует, как найти родительскую транзакцию оператора, в котором была захвачена блокировка:

Сессия А:

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

Сессия Б:

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
  );

Запрос для сессии Б должен отобразить оператор [2] как владельца блокировки данных для записи с pk=1.

Если сессия А выполняет больше операторов, [2] исчезнет из таблицы истории.

Запрос должен отобразить транзакцию, начатую в [1], независимо от того, сколько операторов, стадий или ожиданий было выполнено.

Для просмотра дополнительных данных, можно также использовать таблицы events_xxx_history_long, за исключением транзакций, предполагая, что в сервере не выполняется другой запрос (чтобы история сохранилась).

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-8.4-en/performance-schema-obtaining-parent-events.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API