psql_lockmon
Расширение для мониторинга блокировки.
Схема размещения:
ext
.Расширение реализовано в виде двух дополнительных представлений, основанных на
pg_locks
и pg_stat_activity
, которые вносят минимальный вклад в блокировки объектов. Информация, выводимая представлениями, исключает собственные зависимости и блокировки.Назначение модуля:
- оперативный анализ блокировок сессий;
- выявление слабых мест производительности.
Решение предоставляет следующие объекты:
-
locks_plain:
Поле Тип Описание locktype
text
Тип блокируемого объекта:
–relation
(отношение);
–extend
(расширение отношения);
–frozenid
(замороженный идентификатор);
–page
(страница);
–tuple
(кортеж);
–transactionid
(идентификатор транзакции);
–virtualxid
(виртуальный идентификатор);
–object
(объект);
–userlock
(пользовательская блокировка);
–advisory
(рекомендательная)relation
text
– Отношение, являющееся целью блокировки. NULL
, если целью блокировки не является отношение или его часть.
Перед именем отношения указывается признак репликации объекта и его тип.
Признаки репликации:
–Ordinary
: обычные объекты;
–Unlogged
: объекты, созданные с признакомUnlogged
, или их зависимости;
–Temporary
: объекты, созданные с признакомTemporary
, или их зависимости;
Типы объектов:
–Table
: таблицы;
–Index
: индексы, включаяprimary key
;
–Sequence
: последовательности;
–TOAST
:TOAST
таблицы;
–View
: представления;
–MatView
: материализованные представления;
–CompositeType
: составные типы;
–ForeignTable
: внешние таблицы;
–PartitionedTable
: партиции;
–PartitionedIndex
: индексы партицийpage
int4
Номер страницы в отношении, являющейся целью блокировки, либо NULL
, если цель блокировки не страница или кортеж отношенияtuple
int2
Номер кортежа на странице, являющегося целью блокировки, либо NULL
, если цель блокировки не кортежvirtualxid
text
Виртуальный идентификатор транзакции, являющийся целью блокировки, либо NULL
, если цель блокировки — другой объектtransactionid
xid
Идентификатор транзакции, являющийся целью блокировки, либо NULL
, если цель блокировки — другой объектclassid
oid
OID
системного каталогаpg_class
, содержащего цель блокировки, либоNULL
, если цель блокировки не обычный объект базы данныхobjid
oid
OID
цели блокировки в соответствующем системном каталоге, либоNULL
, если цель блокировки не обычный объект базы данныхobjsubid
int2
– Номер столбца, являющегося целью блокировки (на саму таблицу указывают classid
иobjid
);
–0
(ноль), если это некоторый другой обычный объект базы данных;
–NULL
, если целью не является обычный объектvirtualtransaction
text
Виртуальный идентификатор транзакции, удерживающей или ожидающей блокировку pid
int4
Идентификатор серверного процесса (PID, Process ID), удерживающего или ожидающего эту блокировку, либо NULL
, если блокировка удерживается подготовленной транзакциейblocking_pids
text
Список идентификаторов серверных процессов, удерживающих блокировки, необходимые процессу (через точку с запятой) safe_snapshot_blocking_pids
text
Список идентификаторов серверных процессов, удерживающих блокировки, необходимые процессу, с установленным уровнем изоляции транзакции SERIALIZABLE
илиREPEATABLE READ
(через точку запятой)mode
text
Название режима блокировки, которая удерживается или запрашивается процессом granted
bool
True
– блокировка получена;false
– блокировка ожидаетсяfastpath
bool
True
– блокировка получена по короткому пути;false
– блокировка получена через основную таблицу блокировокdatabase
name
– База данных, к которой относится цель блокировки;
–0
(ноль), если разделяемый объект;
–NULL
, если целью является идентификатор транзакцииusername
name
Имя пользователя, создавшего подключение.
ВНИМАНИЕ: переключение ролей черезSET ROLE
,SET SESSION AUTHORIZATION
не меняют отображаемого имени пользователяclient_app_name
text
Название приложения, подключенного к этому серверному процессу client_addr
text
IP-адрес клиента, подключенного к этому серверному процессу.
Значения:
–null
означает, что клиент подключен как внутренний процесс (автоочистка);
–-1
означает, что клиент подключен через сокет Unix на стороне сервераssl
bool
True
– подключение произведено с использованием SSL;False
– подключение произведено без SSLsslversion
text
Версия TLS, при наличии sslcipher
text
Используемый алгоритм шифрования, при наличии sslbits
int4
Длина ключа SSL, при наличии sslcompression
bool
Признак использования сжатия SSL соединения, при наличии sslclientdn
text
Значение поля CN сертификата клиента, при наличии backend_xid
xid
Идентификатор верхнего уровня транзакции этого серверного процесса или любой другой backend_xmin
xid
Текущая граница xmin
для серверного процессаbackend_type
text
Тип текущего серверного процесса.
Возможные варианты:
–autovacuum launcher
;
–autovacuum worker
;
–logical replication launcher
;
–logical replication worker
;
–parallel worker
;
–background writer
;
–client backend
;
–checkpointer
;
–startup
;
–walreceiver
;
–walsender
;
–walwriter
Фоновые рабочие процессы, регистрируемые расширениями, могут иметь дополнительные типыbackend_age
interval
Время, прошедшее с момента запуска процесса. Для процессов, обслуживающих клиентов, это время подключения клиента к серверу xact_age
interval
Время, прошедшее с начала текущей транзакции в этом процессе или null
при отсутствии активной транзакции. Если текущий запрос был первым в своей транзакции, то значение в этом столбце совпадает со значением столбцаquery_age
query_age
interval
Время, прошедшее с начала выполнения активного в данный момент запроса, или, если state
неactive
, то время начала выполнения последнего запросаstate_change_age
interval
Время, прошедшее с последнего изменения состояния (поле state
)transaction_last_commit_age
interval
Время, прошедшее с фиксации последней транзакции (при включенном параметре track_commit_timestamp
)wait_event_type
text
Тип события, которого ждет обслуживающий процесс, если это имеет место; в противном случае — NULL
wait_event
text
Имя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, а в противном случае — NULL
state
text
Общее текущее состояние этого серверного процесса:
–active
: серверный процесс выполняет запрос;
–idle
: серверный процесс ожидает новой команды от клиента;
–idle in transaction
: серверный процесс находится внутри транзакции, но в настоящее время не выполняет никакой запрос;
–idle in transaction
(aborted): состояние подобноidle in transaction
, за исключением того, что один из операторов в транзакции вызывал ошибку;
–fastpath function call
: серверный процесс выполняет fast-path функцию;
–disabled
: состояние отображается для серверных процессов, у которых параметрtrack_activities
отключенquery
text
Текст последнего запроса этого серверного процесса -
Представление locks_tree:
Поле Тип Описание main_pid
int4
Идентификатор серверного процесса (PID, Process ID), удерживающего блокировку pid
int4
Идентификатор серверного процесса (PID, Process ID), ожидающего эту блокировку lock_queue
text
Список идентификаторов процессов, ожидающих блокировку, созданную процессом main_pid
, разделенных знаком>
locktype
text
Тип блокируемого объекта: relation
– отношение;extend
– расширение отношения;frozenid
– замороженный идентификатор;page
– страница;tuple
– кортеж;transactionid
– идентификатор транзакции;virtualxid
– виртуальный идентификатор;object
– объект;userlock
– пользовательская блокировка;advisory
– рекомендательнаяrelation
text
– Отношение, являющееся целью блокировки;
–NULL
, если целью блокировки не является отношение или его часть.
Перед именем отношения указывается признак репликации объекта и его тип.
Признаки репликации:
–Ordinary
: обычные объекты;
–Unlogged
: объекты, созданные с признакомUnlogged
, или их зависимости;
–Temporary
: объекты, созданные с признакомTemporary
, или их зависимости;
Типы объектов:
–Table
: таблицы;
–Index
: индексы, включаяprimary key
;
–Sequence
: последовательности;
–TOAST
:TOAST
таблицы;
–View
: представления;
–MatView
: материализованные представления;
–CompositeType
: составные типы;
–ForeignTable
: внешние таблицы;
–PartitionedTable
: партиции;
–PartitionedIndex
: индексы партицийmode
text
Название режима блокировки, которая удерживается или запрашивается процессом username
name
Имя пользователя, создавшего подключение.
ВНИМАНИЕ: переключение ролей черезSET ROLE
,SET SESSION AUTHORIZATION
не меняют отображаемого имени пользователяdatabase
name
– База данных, к которой относится цель блокировки;
–0
(ноль), если разделяемый объект;
–NULL
, если целью является идентификатор транзакцииclient_app_name
text
Название приложения, подключенного к этому серверному процессу client_addr
text
IP-адрес клиента, подключенного к этому серверному процессу.
Значения:
–null
означает, что клиент подключен как внутренний процесс (автоочистка);
–-1
означает, что клиент подключен через сокет Unix на стороне сервераxact_age
interval
Время, прошедшее с начала текущей транзакции в этом процессе или null
при отсутствии активной транзакции. Если текущий запрос был первым в своей транзакции, то значение в этом столбце совпадает со значением столбцаquery_age
query_age
interval
Время, прошедшее с начала выполнения активного в данный момент запроса, или, если state
неactive
, то время начала выполнения последнего запросаstate_change_age
interval
Время, прошедшее с последнего изменения состояния (поле state
)wait_event
text
Имя ожидаемого события, если обслуживающий процесс находится в состоянии ожидания, а в противном случае — NULL
state
text
Общее текущее состояние этого серверного процесса:
–active
: серверный процесс выполняет запрос;
–idle
: серверный процесс ожидает новой команды от клиента;
–idle in transaction
: серверный процесс находится внутри транзакции, но в настоящее время не выполняет никакой запрос;
–idle in transaction
(aborted): состояние подобноidle in transaction
, за исключением того, что один из операторов в транзакции вызывал ошибку;
–fastpath function call
: серверный процесс выполняет fast-path функцию;
–disabled
: состояние отображается для серверных процессов, у которых параметрtrack_activities
отключенquery
text
Текст последнего запроса этого серверного процесса
Область видимости ограничена полномочиями пользователя, который выполняет запрос к представлениям и базе данных.
В целях ограничения длительных запросов глубина очереди ограничена в 1000 pid (глубина вложенности pid).
Расширение, в первую очередь, предназначено для оперативного анализа блокировок сессий и выявления слабых мест производительности.
-
Построение дерева блокировок определенной сессии с целью определить блокирующую и устранить ее:
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
процессов, ожидающих блокировки. Если заблокированные процессы отсутствуют, будет получен пустой список.Пример вывода результата выполнения запроса:Раскрыть type=sqlblocked_pid ------------- 8053 (2 rows)
-
Список блокирующих процессов:
SELECT DISTINCT main_pid FROM locks_tree;
Будет получен списокpid
процессов, блокирующих другие процессы. Будет получен пустой список, если блокирующие процессы отсутствуют.Пример вывода результата выполнения запроса:Раскрыть type=sqlmain_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
заблокированного процесса и длительность блокировки.Пример вывода результата выполнения запроса:Раскрыть type=sqlblocked_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
блокирующего процесса;- время начала транзакции в процессе;
- время начала ожидания блокировки.
Пример вывода результата выполнения запроса:Раскрыть type=sqlmain_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 минут.Пример вывода результата выполнения запроса:Раскрыть type=sqlmain_pid | pg_terminate_backend ----------+---------------------- 7576 | t (1 row)