PostgreSQL LinuxWindowsсервер PostgreSQL

PostgreSQL: Как проверить блокирующие транзакции через pg_stat_activity

  • Обновлено
  • Чтение ≈ 3 минуты

Краткий ответ

При зависшем запросе PostgreSQL представление pg_stat_activity позволяет найти сеанс, ожидающий блокировку, и блокирующие backend через pg_blocking_pids(). Это диагностика, а не разрешение на безусловное завершение чужих транзакций.

В этой статье
  1. Симптом и границы применимости
  2. Как отличить возможные причины
  3. Пошаговая диагностика и безопасное исправление
  4. Как проверить, что проблема устранена
  5. Если исправление не помогло

#Симптом и границы применимости

При зависшем запросе PostgreSQL представление pg_stat_activity позволяет найти сеанс, ожидающий блокировку, и блокирующие backend через pg_blocking_pids(). Это диагностика, а не разрешение на безусловное завершение чужих транзакций.

#Как отличить возможные причины

Возможная причинаКак узнатьЧто делать
Долгая открытая транзакцияСеанс idle in transaction удерживает блокировки после незавершённого UPDATE.Долгое xact_start и ожидающие запросыНайти владельца операции
DDL против DMLИзменение таблицы ожидает другие транзакции.wait_event_type=LockСогласовать окно миграции
Недостаточная видимостьУчётная запись не видит полные запросы других ролей.NULL в поле queryЗапросить pg_read_all_stats

#Пошаговая диагностика и безопасное исправление

  1. 1. Подключитесь к правильному экземпляруОткройте psql с учётной записью для мониторинга и выберите рабочую базу. Убедитесь через current_database(), что исследуете нужный экземпляр; запрос статистики сам данные не меняет.
  1. 2. Получите список ожидающих сеансовВыполните выборку с pid, state, wait_event_type и возрастом транзакции. Не предполагайте, что каждый state=active выполняет полезную работу: он может ожидать блокировку.
  2. psql; чтение
    SQLКоманда
    psql; чтение. Текст запросов может содержать чувствительные значения — не публикуйте вывод.
    SELECT pid, usename, state, wait_event_type, wait_event, now()-xact_start AS xact_age, left(query,160) AS query FROM pg_stat_activity WHERE datname=current_database() AND pid<>pg_backend_pid() ORDER BY xact_start NULLS LAST LIMIT 40;
  1. 3. Найдите конкретный блокирующий процессВызовите pg_blocking_pids для ожидающих сеансов; именно он учитывает внутренние правила блокировок. Связь с PID и время помогут найти приложение-владельца.
  2. psql, чтение
    SQLКоманда
    psql, чтение. Пустой массив означает отсутствие блокирующих PID в момент проверки.
    SELECT pid, pg_blocking_pids(pid) AS blockers, wait_event_type, state FROM pg_stat_activity WHERE datname=current_database() AND wait_event_type='Lock';
  1. 4. Проверьте источник долгой транзакцииНайдите сервер приложения и журнал операции по application_name, client_addr, времени и PID. Если видите idle in transaction, это повод проверить забытый COMMIT/ROLLBACK, а не сразу разрывать соединение.
  1. 5. Оцените последствия отмены командыpg_cancel_backend(pid) отменяет текущий запрос, pg_terminate_backend(pid) разрывает весь сеанс и откатывает незавершённую транзакцию; обе операции способны повредить текущий бизнес-процесс. Не запускайте их только по цифре PID.
  1. 6. Устраните причину на тестеВ коде приложения сократите транзакцию, уберите ожидание пользователя внутри BEGIN/COMMIT и добавьте разумный lock_timeout для особо чувствительных миграций. Проверьте, что явный ROLLBACK выполняется при ошибке.
  1. 7. Повторите проверку блокировокПосле согласованного исправления дважды снимите pg_stat_activity в момент нагрузки; отсутствие долговременных ожидающих сеансов важнее однократного исчезновения конкретного PID.
  1. 8. Зафиксируйте наблюдение в мониторингеСохраняйте число сеансов, ожидающих Lock, и максимальный возраст транзакции без полного SQL с персональными данными. Настройте оповещение при продолжительном idle in transaction.

#Как проверить, что проблема устранена

В тестовом сценарии ожидающие команды завершаются, pg_blocking_pids не показывает постоянного блокирующего PID, запросы не застревают повторно.

#Если исправление не помогло

Если блокировки возвращаются, сравните их по application_name и порядку операций. При отсутствии доступа к статистике попросите роль pg_read_all_stats, а не статус суперпользователя для приложения.

Так эту ошибку тоже называют

Источники и обновления

Последнее обновление статьи: 2 ноября 2026. Версии программ и интерфейсы меняются — если шаги не совпадают с вашей версией, сверяйтесь с документацией производителя.