Как узнать текущие долгие запросы в базе данных
Что проверяют
Умеете ли вы искать проблему в работающей базе, а не только в коде, и различаете ли «что выполняется прямо сейчас» и «что было медленным за период». Следом спрашивают, как безопасно остановить зависший запрос и как понять, какая часть Python-приложения его отправила.
Как отвечать
В PostgreSQL текущие запросы видны в pg_stat_activity:
SELECT pid, now() - query_start AS duration, state, wait_event_type, query
FROM pg_stat_activity
WHERE state <> 'idle'
ORDER BY duration DESC;state:activeвыполняется, аidle in transactionозначает открытую транзакцию, которая ничего не делает, но держит блокировки и мешает vacuum. Часто это забытыйcommitв коде;wait_event_type: значениеLockзначит, что запрос ждёт блокировку. Кто её держит, покажетpg_blocking_pids(pid);- остановка:
pg_cancel_backend(pid)отменяет запрос,pg_terminate_backend(pid)рвёт соединение целиком. Начинают с первого; - история: расширение
pg_stat_statementsкопит суммарное и среднее время по нормализованным запросам, аlog_min_duration_statementпишет в лог всё медленнее заданного порога; - MySQL: текущие запросы в
SHOW FULL PROCESSLISTилиperformance_schema, история вslow_query_logс порогомlong_query_time, остановка черезKILL QUERY.
Со стороны Python полезно задать application_name в параметрах подключения (в psycopg или в connect_args у SQLAlchemy), тогда в pg_stat_activity видно, какой сервис или воркер Celery прислал запрос. Защита на будущее: statement_timeout на уровне роли или соединения. Найденный запрос разбирают через EXPLAIN (ANALYZE, BUFFERS).
Где спотыкаются
Смотрят только на active и пропускают idle in transaction. Такая сессия может часами держать блокировку, а остальные запросы стоят за ней в очереди.
Сразу убивают процесс или перезапускают базу. Прерванный долгий UPDATE откатывается целиком, это тоже время, а приложение с ретраями пришлёт тот же запрос снова.
Не знают, что EXPLAIN ANALYZE реально выполняет запрос. На UPDATE или DELETE в проде он изменит данные, если не обернуть его в транзакцию с ROLLBACK.