Como depurar uma consulta ociosa?

13

Eu tenho uma consulta em lote que estou executando diariamente no meu banco de dados. No entanto, parece que ele fica parado no estado inativo e estou tendo muita dificuldade em depurar o que está acontecendo.

A consulta é uma agregação em uma tabela que está sendo inserida simultaneamente, o que eu acho que está de alguma forma relacionado ao problema. (A agregação está nos dados dos dias anteriores, portanto, as inserções não devem afetar os resultados.)

Pistas

  1. Estou executando isso dentro de um script python usando sqlalchemy. No entanto, eu configurei o nível de transação para confirmação automática, portanto, não acho que as coisas estejam envolvendo dentro de uma transação. Por outro lado, não vejo a consulta travar quando a executo manualmente no terminal sql.

  2. Ao consultar pg_stat_activity, a consulta entra inicialmente no banco de dados como state='active'. Após talvez 15 segundos, o estado muda para 'inativo' e, adicionalmente, o xact_startestá definido como NULL. O sinalizador de espera nunca é definido como verdadeiro.

  3. Antes de descobrir o autocommit no nível da transação para sqlalchemy, ele seria interrompido no estado, 'idle in transaction'e não 'idle'. E possivelmente trava um pouco menos frequentemente desde que fez essa alteração?

Sinto que não estou preparada para me aprofundar mais do que nisto. Qualquer feedback, mesmo explicando mais sobre diferentes estados e internos relevantes do postgres sem dar uma resposta definitiva, seria muito apreciado.

Kurt Spindler
fonte
2
Se o estado estiver ocioso e NÃO estiver aguardando, a consulta será concluída, mas a conexão com o banco de dados não está fechada. ocioso na transação também significa que a consulta está concluída, mas não COMMITfoi emitida para finalizar a transação. Parece que seu problema pode estar em outro lugar do que a db ..
Joishi Bodio
Sim, acho que você está certo. O problema está no modo como o Python está lidando com a consulta, não no problema com o banco de dados.
Kurt Spindler

Respostas:

6

A primeira coisa que você precisa separar aqui são as palavras consulta , transação e conexão .

  1. Pista: sua consulta é executada - está no estado ativo. Depois disso, a consulta termina, mas a conexão permanece ativa - o estado ocioso. Não há nenhuma transação (que foi confirmada), portanto a xact_starté nula. Portanto, você deve fechar a conexão após a consulta ter êxito.

  2. Dica: Antes que a confirmação automática estivesse na consulta, ela era deixada no meio da transação, então primeiro você precisaria commite depois close connection.

Simo Kivistö
fonte