Как отладить Idle Query?

13

У меня есть пакетный запрос, который я ежедневно выполняю в своей базе данных. Тем не менее, похоже, что он застрял в режиме ожидания, и мне очень трудно отлаживать происходящее.

Запрос представляет собой агрегацию для таблицы, которая одновременно вставляется, что, я думаю, как-то связано с этой проблемой. (Агрегирование данных за предыдущие дни, поэтому вставки не должны влиять на результаты.)

Улики

  1. Я запускаю это внутри скрипта Python, используя sqlalchemy. Тем не менее, я установил уровень транзакции для автоматической фиксации, так что я не думаю, что что-то запутывается внутри транзакции. С другой стороны, я не вижу зависания запроса, когда запускаю его вручную в терминале sql.

  2. При запросе pg_stat_activityзапрос изначально поступает в базу данных как state='active'. Примерно через 15 секунд состояние меняется на «режим ожидания» и дополнительно xact_startустанавливается на NULL. Флаг ожидания никогда не устанавливается в true.

  3. Прежде чем я понял, AutoCommit уровня транзакций для SQLAlchemy, было бы вместо этого повесить в состоянии , 'idle in transaction'а не 'idle'. И это может зависать немного реже после внесения этого изменения?

Я чувствую, что я не в состоянии копать глубже, чем я на этом. Будем весьма благодарны за любые отзывы, даже более подробно объясняющие различные состояния и соответствующие внутренние компоненты postgres, но не дающие однозначного ответа.

Курт Шпиндлер
источник
2
Если состояние неактивно и оно НЕ ожидает, тогда запрос завершен, но соединение с БД не закрыто. idle in транзакция также означает, что запрос завершен, но COMMITдля завершения транзакции не было выдано ни одного запроса . Похоже, ваша проблема может быть не в БД, а в другом месте
Джоиши Бодио
Я думаю, ты прав. Проблема в том, как Python обрабатывает запрос, а не проблема с базой данных.
Курт Шпиндлер

Ответы:

6

Первое, что вы должны выделить здесь, это слова запрос , транзакция и соединение .

  1. Подсказка: ваш запрос выполняется - он находится в активном состоянии. После этого запрос заканчивается, но соединение остается - состояние ожидания. Нет транзакции (она была зафиксирована), поэтому она xact_startявляется нулевой. Поэтому вы должны закрыть соединение после успешного выполнения запроса.

  2. Подсказка: до того, как автокоммит был включен, запрос был оставлен в середине транзакции, поэтому сначала вам нужно будет, commitа затем close connection.

Симо Кивистё
источник