Uma consulta de longa duração do Postgres é interrompida se a conexão for perdida / interrompida?

20

Se eu abrir uma conexão com o Postgres e emitir uma consulta de longa execução e interromper a conexão (por exemplo, interrompa o processo do cliente que abriu a conexão), a consulta de longa duração continuará sendo executada ou será automaticamente interrompida? Isso é configurável?

(Estou usando o Postgresql 9.2.9)

Rob Bednark
fonte

Respostas:

32

"Depende".

Se o cliente desaparecer devido à perda de conexão de rede, a consulta geralmente será executada até recuperar linhas suficientes para preencher seu buffer de envio de rede e, em seguida, pare e fique presa até que a conexão TCP caia e, nesse ponto, será interrompida. Se ele for concluído antes de preencher o buffer de envio do TCP, ele será concluído com êxito; portanto, se for confirmado automaticamente, a consulta será confirmada.

Se o cliente for morto de uma maneira que o sistema operacional do cliente possa relatar ao servidor via TCP RST (como uma falha / falha do cliente, SIGTERM, SIGKILL, etc.), o servidor PostgreSQL definirá o sinalizador de interrupção. Na próxima vez em que a consulta procurar interrupções durante a execução, verá o sinalizador e abortará. Às vezes, uma consulta pode estar executando um trabalho pesado da CPU dentro de um código que não verifica interrupções - algumas extensões e alguns locais no núcleo do PostgreSQL - nesse caso, ela pode não notar a interrupção por um longo tempo e continuar em execução. Ele sempre verá a interrupção e o cancelamento antes de concluir e confirmar, se for a confirmação automática.

Se o cliente for morto por algo como uma reinicialização repentina do sistema operacional, para que o host do cliente repentinamente não saiba nada sobre a conexão TCP, mas ainda possa responder na rede, a consulta provavelmente será interrompida na primeira vez em que tentar escrever uma linha, como Jeff disse, porque o host do cliente enviará um TCP RST em resposta ao primeiro pacote enviado pelo servidor após a reinicialização. O PostgreSQL verifica se há interrupções em cada linha que envia.

Esse comportamento não é configurável. No que diz respeito ao PostgreSQL, se o cliente sair, seu trabalho é encerrar as consultas que o cliente estava executando. Para alterar que você precisaria de algum tipo de token de conclusão de consulta que pudesse obter no início da consulta, use para perguntar ao servidor sobre a consulta por outra conexão posteriormente. Essencialmente, você teria que implementar consultas assíncronas / em segundo plano. Possivelmente, um recurso interessante, mas não suportado atualmente.

Se a consulta for de confirmação automática ou se sua consulta estava COMMITem andamento no momento em que você matou o cliente / perdeu a conexão, é possível que uma transação esteja em um estado indeterminado, onde o cliente não sabe se ou não comprometido. Não há maneira real de descobrir, além de procurar os efeitos da transação nos dados.

Onde isso é inaceitável, você pode usar a consolidação de duas fases e um gerenciador de transações do lado do cliente.

Craig Ringer
fonte
1
Uau, exatamente o que eu estava procurando, uma excelente resposta detalhada! Obrigado @Craig_Ringer!
precisa saber é o seguinte
1
@CraigRinger, uma pergunta relacionada foi feita: O pgAdmin III permitirá que eu execute um comando SQL que funcione após desanexar do meu túnel SSH?
ypercubeᵀᴹ
2

Ele continuará em execução até tentar retornar as linhas à conexão e detectar a quebra. Portanto, para uma consulta que faz todo o trabalho antes de retornar qualquer linha, ela será executada essencialmente até a conclusão.

jjanes
fonte
Obrigado @jjanes. Você pode apontar para qualquer documentação ou código fonte que indique isso?
Rob Bednark