psql_lockmon. Расширение для мониторинга блокировки#
Версия: 1.0.
В исходном дистрибутиве установлено по умолчанию: да.
Связанные компоненты: отсутствуют.
Схема размещения:
ext.
Расширение реализовано в виде двух дополнительных представлений, основанных на pg_locks и pg_stat_activity, которые вносят минимальный вклад в блокировки объектов. Информация, выводимая представлениями, исключает собственные зависимости и блокировки.
Назначение модуля:
оперативный анализ блокировок сессий;
выявление слабых мест производительности.
Расширение psql_lockmon используется как инструмент для оперативного мониторинга заблокированных объектов. Подробнее с этой функциональностью можно ознакомиться в документе «Руководство администратора», раздел «Сценарии администрирования», подраздел «Мониторинг блокировок».
Объекты#
Решение предоставляет следующие объекты:
locks_plain
Поле |
Тип |
Описание |
|---|---|---|
|
|
Тип блокируемого объекта:
|
|
|
Отношение, являющееся целью блокировки.
|
|
|
Номер страницы в отношении, являющейся целью блокировки, либо |
|
|
Номер кортежа на странице, являющегося целью блокировки, либо |
|
|
Виртуальный идентификатор транзакции, являющийся целью блокировки, либо |
|
|
Идентификатор транзакции, являющийся целью блокировки, либо |
|
|
|
|
|
|
|
|
Номер столбца, являющегося целью блокировки (на саму таблицу указывают
|
|
|
Виртуальный идентификатор транзакции, удерживающей или ожидающей блокировку |
|
|
Идентификатор серверного процесса (PID, Process ID), удерживающего или ожидающего эту блокировку, либо |
|
|
Список идентификаторов серверных процессов, удерживающих блокировки, необходимые процессу (через точку с запятой) |
|
|
Список идентификаторов серверных процессов, удерживающих блокировки, необходимые процессу, с установленным уровнем изоляции транзакции |
|
|
Название режима блокировки, которая удерживается или запрашивается процессом |
|
|
|
|
|
|
|
|
База данных, к которой относится цель блокировки;
|
|
|
Имя пользователя, создавшего подключение. |
|
|
Название приложения, подключенного к этому серверному процессу |
|
|
IP-адрес клиента, подключенного к этому серверному процессу.
|
|
|
|
|
|
Версия TLS, при наличии |
|
|
Используемый алгоритм шифрования, при наличии |
|
|
Длина ключа SSL, при наличии |
|
|
Признак использования сжатия SSL соединения, при наличии |
|
|
Значение поля CN сертификата клиента, при наличии |
|
|
Идентификатор верхнего уровня транзакции этого серверного процесса или любой другой |
|
|
Текущая граница |
|
|
Тип текущего серверного процесса.
|
|
|
Время, прошедшее с момента запуска процесса. Для процессов, обслуживающих клиентов, это время подключения клиента к серверу |
|
|
Время, прошедшее с начала текущей транзакции в этом процессе или |
|
|
Время, прошедшее с начала выполнения активного в данный момент запроса, или, если |
|
|
Время, прошедшее с последнего изменения состояния (поле |
|
|
Время, прошедшее с фиксации последней транзакции (при включенном параметре |
|
|
Тип события, которого ждет обслуживающий процесс, если это имеет место; в противном случае — |
|
|
Имя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, а в противном случае — |
|
|
Общее текущее состояние этого серверного процесса:
|
|
|
Текст последнего запроса этого серверного процесса |
Представление locks_tree
Поле |
Тип |
Описание |
|---|---|---|
|
|
Идентификатор серверного процесса (PID, Process ID), удерживающего блокировку |
|
|
Идентификатор серверного процесса (PID, Process ID), ожидающего эту блокировку |
|
|
Список идентификаторов процессов, ожидающих блокировку, созданную процессом |
|
|
Тип блокируемого объекта:
|
|
|
Отношение, являющееся целью блокировки;
|
|
|
Название режима блокировки, которая удерживается или запрашивается процессом |
|
|
Имя пользователя, создавшего подключение. |
|
|
База данных, к которой относится цель блокировки;
|
|
|
Название приложения, подключенного к этому серверному процессу |
|
|
IP-адрес клиента, подключенного к этому серверному процессу.
|
|
|
Время, прошедшее с начала текущей транзакции в этом процессе или |
|
|
Время, прошедшее с начала выполнения активного в данный момент запроса, или, если |
|
|
Время, прошедшее с последнего изменения состояния (поле |
|
|
Имя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, а в противном случае — |
|
|
Общее текущее состояние этого серверного процесса:
|
|
|
Текст последнего запроса этого серверного процесса |
Доработка#
Доработка: Набор представлений для работы с
pg_locks,pg_stat_activity.Версия: 5.2.0.
Решение реализовано в виде расширения psql_lockmon, состоящего из набора представлений для работы с pg_locks, pg_stat_activity.
По сравнению с процессом прямого опроса системных представлений в доработке реализована расшифровка:
OIDобъектов;типов
OIDобъектов;дерева взаимоблокировок при их наличии.
Решение позволяет снизить:
квалификационный порог для эксплуатации;
затраты на поддержку СУБД экспертами.
Решение не предназначено для автоматизированного частотного мониторинга (от сотен запросов в секунду).
Ограничения#
Область видимости ограничена полномочиями пользователя, который выполняет запрос к представлениям и базе данных.
В целях ограничения длительных запросов глубина очереди ограничена в 1000 pid (глубина вложенности pid).
Установка#
При наличии прав администратора СУБД включение модуля возможно выполнить вручную:
CREATE EXTENSION psql_lockmon SCHEMA ext;
Настройка#
Настройка не требуется.
Использование модуля#
Расширение, в первую очередь, предназначено для оперативного анализа блокировок сессий и выявления слабых мест производительности.
Построение дерева блокировок определенной сессии с целью определить блокирующую и устранить ее:
SELECT * FROM locks_tree WHERE blocked_pid=<pid>;Построение дерева блокировок для сессии с определенным
pid. Идентификатор блокирующей сессии будет определен в полеmain_pid, список заблокированных сессий - в полеlock_tree. Отсутствие записей означает, что сессия не заблокирована.Построение дерева блокировок всех сессий, используя существующие представления, с целью определить заблокированные сессии и устранить блокировки:
SELECT * FROM locks_tree;Идентификатор блокирующей сессии будет определен в поле
main_pid, список заблокированных сессий - в полеlock_tree.Список заблокированных процессов:
SELECT DISTINCT blocked_pid FROM locks_tree;Будет получен список
pidпроцессов, ожидающих блокировки. Если заблокированные процессы отсутствуют, будет получен пустой список.Пример вывода результата выполнения запроса:
blocked_pid ------------- 8053 (2 rows)Список блокирующих процессов:
SELECT DISTINCT main_pid FROM locks_tree;Будет получен список
pidпроцессов, блокирующих другие процессы. Будет получен пустой список, если блокирующие процессы отсутствуют.Пример вывода результата выполнения запроса:
main_pid ---------- 7576 (1 row)Максимальная длительность блокировки:
SELECT blocked_pid, max (state_change_age) FROM locks_tree WHERE blocked_pid NOTNULL GROUP BY 1 ORDER BY 2 DESC,1 LIMIT 1;Будут получены
pidзаблокированного процесса и длительность блокировки.Пример вывода результата выполнения запроса:
blocked_pid | max -------------+----------------- 8053 | 00:25:24.556964 (1 row)Поиск по логам текста запроса, приведшего к блокировке (требует прав
pg_read_all_stats):SELECT DISTINCT t1.main_pid, current_timestamp-t1.xact_age, current_timestamp-t2.state_change_age FROM locks_tree t1 JOIN locks_tree t2 USING(main_pid) WHERE t1.lock_depth=1 AND t2.lock_depth=2;Поскольку в полях
queryотображается последний выполненный запрос, то для выявления блокирующего запроса стоит восстановить ретроспективу по логам базы данных. Для этого необходимы:pidблокирующего процесса;время начала транзакции в процессе;
время начала ожидания блокировки.
Пример вывода результата выполнения запроса:
main_pid | ?column? | ?column? ----------+-------------------------------+------------------------------- 7576 | 2023-03-23 10:42:52.409485+03 | 2023-03-23 12:04:39.150078+03 (1 row)В результате запроса получены
pidблокирующего процесса и диапазоны времени для поиска по логам.Принудительное завершение серверных сессий, приводящих к длительным блокировкам (требует прав
pg_signal_backend).SELECT DISTINCT main_pid, pg_terminate_backend (main_pid) FROM locks_tree WHERE lock_depth=2 AND state_change_age > interval '30 minutes';В примере запрос принудительно завершает процессы, приводящие к блокировкам длительностью более 30 минут.
Пример вывода результата выполнения запроса:
main_pid | pg_terminate_backend ----------+---------------------- 7576 | t (1 row)