Диагностические запросы в PostgreSQL

СУБД PostgreSQL накапливает статистику о своей работе. К этой информации можно обратиться с помощью запросов к представлениям. Ниже мы разберем основные из них.

Просмотр установленных блокировок

Для этого используется представление pg_locks.

Copy
select   lock.locktype,   lock.relation::regclass,   lock.mode,   lock.transactionid as tid,   lock.virtualtransaction as vtid,   lock.pid,   lock.granted from pg_catalog.pg_locks lock   left join pg_catalog.pg_database db     on db.oid = lock.database where (db.datname = 'ИмяБазы' or db.datname is null)   and not lock.pid = pg_backend_pid() order by lock.pid;

Здесь и далее условие not pid = pg_backend_pid() исключает записи текущей сессии.

Выполняющиеся запросы

Используется представление pg_stat_activity, которое показывает информацию о текущей активности процессов и в частности – о выполняемых запросах.

Copy
select query, state, waiting, pid from pg_stat_activity where datname = 'ИмяБазы' and not (state = 'idle' or pid = pg_backend_pid())

Кто кого заблокировал

Чтобы увидеть блокирующий и заблокированный запросы, необходимо объединить два предыдущих запроса в один.

Copy
select   coalesce(bgl.relation::regclass::text, bgl.locktype) as locked_item,   now() - bda.query_start as waiting_duration,   bda.pid as blocked_pid,   bda.query as blocked_query,   bdl.mode as blocked_mode,   bga.pid as blocking_pid,   bga.query as blocking_query,   bgl.mode as blocking_mode from pg_catalog.pg_locks bdl   join pg_stat_activity bda     on bda.pid = bdl.pid   join pg_catalog.pg_locks bgl     on bgl.pid != bdl.pid     and (bgl.transactionid = bdl.transactionid       or bgl.relation = bdl.relation and bgl.locktype = bdl.locktype)   join pg_stat_activity bga     on bga.pid = bgl.pid     and bga.datid = bda.datid where not bdl.granted   and bga.datname = 'ИмяБазы'

Узнать имя базы и ее OID

OID базы соответствует имени каталога, в котором лежат таблицы этой базы.

Copy
select datname, oid from pg_database

Узнать имя файла определенной таблицы

Copy
select pg_relation_filepath('ИмяТаблицы')