psql_lockmon. Расширение для мониторинга блокировки
Версия: 1.0.
В исходном дистрибутиве установлено по умолчанию: да.
Связанные компоненты: отсутствуют.
Схема размещения:
ext
.
Расширение реализовано в виде двух дополнительных представлений, основанных на pg_locks
и pg_stat_activity
, которые вносят минимальный вклад в блокировки объектов. Информация, выводимая представлениями, исключает собственные зависимости и блокировки.
Назначение модуля:
- оперативный анализ блокировок сессий;
- выявление слабых мест производительности.
Расширение psql_lockmon
используется как инструмент для оперативного мониторинга заблокированных объектов. Подробнее с этой функциональностью можно ознакомиться в документе «Руководство администратора», раздел «Сценарии администрирования», подраздел «Мониторинг блокировок».
Объекты
Решение предоставляет следующие объекты:
locks_plain
locks_plain
Поле | Тип | Описание |
|
| Тип блокируемого объекта:
|
|
| Отношение, являющееся целью блокировки.
|
|
| Номер страницы в отношении, являющейся целью блокировки, либо |
|
| Номер кортежа на странице, являющегося целью блокировки, либо |
|
| Виртуальный идентификатор транзакции, являющийся целью блокировки, либо |
|
| Идентификатор транзакции, являющийся целью блокировки, либо |
|
|
|
|
|
|
|
| Номер столбца, являющегося целью блокировки (на саму таблицу указывают
|
|
| Виртуальный идентификатор транзакции, удерживающей или ожидающей блокировку |
|
| Идентификатор серверного процесса (PID, Process ID), удерживающего или ожидающего эту блокировку, либо |
|
| Список идентификаторов серверных процессов, удерживающих блокировки, необходимые процессу (через точку с запятой) |
|
| Список идентификаторов серверных процессов, удерживающих блокировки, необходимые процессу, с установленным уровнем изоляции транзакции |
|
| Название режима блокировки, которая удерживается или запрашивается процессом |
|
|
|
|
|
|
|
| База данных, к которой относится цель блокировки;
|
|
| Имя пользователя, создавшего подключение. |
|
| Название приложения, подключенного к этому серверному процессу |
|
| IP-адрес клиента, подключенного к этому серверному процессу.
|
|
|
|
|
| Версия TLS, при наличии |
|
| Используемый алгоритм шифрования, при наличии |
|
| Длина ключа SSL, при наличии |
|
| Признак использования сжатия SSL соединения, при наличии |
|
| Значение поля CN сертификата клиента, при наличии |
|
| Идентификатор верхнего уровня транзакции этого серверного процесса или любой другой |
|
| Текущая граница |
|
| Тип текущего серверного процесса.
|
|
| Время, прошедшее с момента запуска процесса. Для процессов, обслуживающих клиентов, это время подключения клиента к серверу |
|
| Время, прошедшее с начала текущей транзакции в этом процессе или |
|
| Время, прошедшее с начала выполнения активного в данный момент запроса, или, если |
|
| Время, прошедшее с последнего изменения состояния (поле |
|
| Время, прошедшее с фиксации последней транзакции (при включенном параметре |
|
| Тип события, которого ждет обслуживающий процесс, если это имеет место; в противном случае — |
|
| Имя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, а в противном случае — |
|
| Общее текущее состояние этого серверного процесса:
|
|
| Текст последнего запроса этого серверного процесса |
Представление locks_tree
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)