PostgreSQL pg_blocking_pids: найти блокирующие запросы
Если запрос ждёт блокировку, pg_blocking_pids возвращает PID сессий, которые его блокируют. Соедините их с pg_stat_activity, чтобы увидеть возраст ожидания и короткий фрагмент SQL. Сначала проверьте запрос на небольшой выборке и изучите план выполнения на своих данных.
Рабочий пример
SELECT waiting.pid AS waiting_pid,
blocker.pid AS blocker_pid,
clock_timestamp() - waiting.query_start AS waiting_for,
left(blocker.query, 120) AS blocker_query
FROM pg_stat_activity AS waiting
CROSS JOIN LATERAL unnest(pg_blocking_pids(waiting.pid)) AS blocked_by(pid)
JOIN pg_stat_activity AS blocker ON blocker.pid = blocked_by.pid;pg_blocking_pids учитывает прямых блокировщиков и работает надёжнее ручного self-join pg_locks в типичной диагностике. Повторите запрос, если ситуация меняется быстро.
Частый вопрос
Как освободить зависшую сессию?
Сначала свяжитесь с владельцем транзакции. При подтверждённой необходимости используйте pg_cancel_backend(pid) для запроса; pg_terminate_backend завершает всю сессию и действует жёстче.