Как быстро диагностировать «тормоза» в PostgreSQL — без всяких внешних тулов и дополнительных логов. Только pg_stat_activity и немного здравого смысла.
Проблема: пользователи жалуются — "всё тормозит". Как понять, что именно?
Решение: открываем сессию в psql от суперпользователя и запускаем:
Что это нам даёт:
- Видим все активные (и зависшие) запросы.
- Сколько времени они уже выполняются (duration).
- На чём конкретно «висят»: CPU, IO, Lock, Client и т.д. (wait_event_type + `wait_event).
Пример:
→ Сразу ясно: кто-то держит блокировку на таблицу, и все остальные ждут.
Бонус: чтобы найти виновника, можно запустить:
Этот запрос покажет, кто кого блокирует, и с каким запросом.
Это простая, но мощная техника диагностики. Поможет вам не раз в проде — особенно, когда времени мало, а багов много.
А вы пользуетесь pg_stat_activity в проде? Или сразу лезете в лог?
Проблема: пользователи жалуются — "всё тормозит". Как понять, что именно?
Решение: открываем сессию в psql от суперпользователя и запускаем:
SQL:
SELECT pid, state, wait_event_type, wait_event, query, now() - query_start AS duration
FROM pg_stat_activity
WHERE state != 'idle'
ORDER BY duration DESC;
- Видим все активные (и зависшие) запросы.
- Сколько времени они уже выполняются (duration).
- На чём конкретно «висят»: CPU, IO, Lock, Client и т.д. (wait_event_type + `wait_event).
Пример:
SQL:
wait_event_type: Lock
wait_event: relation
Бонус: чтобы найти виновника, можно запустить:
SQL:
SELECT blocked_locks.pid AS blocked_pid,
blocking_locks.pid AS blocking_pid,
blocked_activity.query AS blocked_query,
blocking_activity.query AS blocking_query
FROM pg_locks blocked_locks
JOIN pg_locks blocking_locks ON blocked_locks.locktype = blocking_locks.locktype
AND blocked_locks.database IS NOT DISTINCT FROM blocking_locks.database
AND blocked_locks.relation IS NOT DISTINCT FROM blocking_locks.relation
AND blocked_locks.page IS NOT DISTINCT FROM blocking_locks.page
AND blocked_locks.tuple IS NOT DISTINCT FROM blocking_locks.tuple
AND blocked_locks.transactionid IS NOT DISTINCT FROM blocking_locks.transactionid
AND blocked_locks.classid IS NOT DISTINCT FROM blocking_locks.classid
AND blocked_locks.objid IS NOT DISTINCT FROM blocking_locks.objid
AND blocked_locks.objsubid IS NOT DISTINCT FROM blocking_locks.objsubid
AND blocked_locks.pid != blocking_locks.pid
JOIN pg_stat_activity blocked_activity ON blocked_activity.pid = blocked_locks.pid
JOIN pg_stat_activity blocking_activity ON blocking_activity.pid = blocking_locks.pid
WHERE NOT blocked_locks.granted;
Это простая, но мощная техника диагностики. Поможет вам не раз в проде — особенно, когда времени мало, а багов много.
А вы пользуетесь pg_stat_activity в проде? Или сразу лезете в лог?