Блокировку в PostgreSQL снимают через завершение удерживающей ее операции: PostgreSQL предоставляет функции pg_cancel_backend для отмены текущего запроса сессии и pg_terminate_backend для завершения самой сессии. Блокировка освобождается, как только удерживающая ее транзакция завершается. Сначала нужно узнать pid процесса, который держит объект.
Как снять блокировку
- Отмените активный запрос блокирующей сессии, не разрывая соединение – самый мягкий способ:
SELECT pg_cancel_backend(12345);
- Если запрос не отменяется или сессия висит в состоянии idle in transaction, завершите соединение целиком:
SELECT pg_terminate_backend(12345);
- Число 12345 – это pid удерживающего процесса. Определить его можно функцией pg_blocking_pid, передав ей номер ожидающей сессии:
SELECT pg_blocking_pids(67890);
На что обратить внимание
pg_cancel_backend прерывает только текущий запрос, pg_terminate_backend разрывает всю сессию – ее незавершенная транзакция откатывается. Для выполнения нужны права суперпользователя, роль-владелец сессии или членство в роли pg_signal_backend. Причина зависшей блокировки (например, оставленная открытой транзакция в приложении) при этом не устраняется – завершение сессии снимает следствие, а не источник.
Однократное завершение сессии убирает текущую блокировку, но повторяющиеся ожидания указывают на системную причину – ее видно только в динамике. PGLens сохраняет историю блокировок и ожиданий в отдельной базе, что позволяет восстановить хронологию инцидента и найти запросы или приложения, регулярно удерживающие объекты.