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 */
)
Условия для соединения:
Родительское и дочернее событие находятся в одном потоке.
Дочернее событие начинается после родительского события, поэтому его значение
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. Однако, из-за большого количества записей ожиданий, событие ожидания, вызвавшее блокировку, скорее всего, уже отсутствует в таблицах истории.
События ожидания, стадии и операторы быстро исчезают из истории. Если оператор, выполнивший длительную операцию и взявший блокировку, всё ещё находится в открытой транзакции, возможно, оператор не будет найден, но транзакция будет найдена.
Именно поэтому модель данных вложенных множеств лучше подходит для поиска родительских событий. Следование ссылкам в отношениях «родитель/ребёнок» (блокировка данных -> родительское ожидание -> родительская стадия -> родительская транзакция) неэффективно, когда промежуточные узлы уже удалены из таблиц истории.
Следующий сценарий иллюстрирует, как найти родительскую транзакцию оператора, в котором была захвачена блокировка:
Сессия А:
[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.