PostgreSQL: посмотреть зависшие запросы
Зависший запрос в PostgreSQL почти всегда либо ждёт блокировку, либо давно делает seq scan. Кто сейчас работает, видно в pg_stat_activity.
Кто сейчас не idle
SELECT pid, usename, state, wait_event_type, wait_event,
now() - query_start AS runtime, left(query, 120) AS query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY runtime DESC NULLS LAST;Смотрите runtime и wait_event. Если state = 'active' и время растёт минутами — это кандидат на отмену.
Остановить запрос
Мягко попросить прервать:
SELECT pg_cancel_backend(PID);Если не отпускает — разорвать соединение:
SELECT pg_terminate_backend(PID);Подставьте pid из предыдущего запроса. pg_terminate_backend убивает сессию целиком.
Кто кого блокирует
Цепочка waiter → locker:
SELECT blocked.pid AS waiter_pid,
blocked.usename AS waiter,
left(blocked.query, 80) AS waiter_query,
blocking.pid AS locker_pid,
blocking.usename AS locker,
left(blocking.query, 80) AS locker_query
FROM pg_stat_activity blocked
JOIN pg_locks bl ON bl.pid = blocked.pid AND NOT bl.granted
JOIN pg_locks kl ON kl.locktype = bl.locktype
AND kl.database IS NOT DISTINCT FROM bl.database
AND kl.relation IS NOT DISTINCT FROM bl.relation
AND kl.page IS NOT DISTINCT FROM bl.page
AND kl.tuple IS NOT DISTINCT FROM bl.tuple
AND kl.virtualxid IS NOT DISTINCT FROM bl.virtualxid
AND kl.transactionid IS NOT DISTINCT FROM bl.transactionid
AND kl.classid IS NOT DISTINCT FROM bl.classid
AND kl.objid IS NOT DISTINCT FROM bl.objid
AND kl.objsubid IS NOT DISTINCT FROM bl.objsubid
AND kl.pid <> bl.pid
AND kl.granted
JOIN pg_stat_activity blocking ON blocking.pid = kl.pid;Сначала смотрите locker_query: часто это открытая транзакция, которая держит замок и ничего не делает (idle in transaction). Её и завершают через pg_terminate_backend.
Смежные заметки: выгрузить таблицу в CSV, хаб PostgreSQL.



