kill -9 um processo do postgres

25

Uma consulta SELECT do postgres ficou fora de controle em nosso servidor de banco de dados e começou a consumir toneladas de memória e trocar até o servidor ficar sem memória. Eu encontrei o processo específico via ps aux | grep postgrese executei kill -9 pid. Isso acabou com o processo e a memória foi liberada conforme o esperado. As demais consultas do sistema e do postgres não foram afetadas. Este servidor está executando o postgres 9.1.3 no SLES 9 SP4.

No entanto, um de nossos desenvolvedores me criticou por ter matado um processo do postgres kill -9, dizendo que ele derrubaria todo o serviço do postgres. Na realidade, não. Eu fiz isso antes de um punhado de vezes e não vi nenhum efeito colateral negativo.

Dito isso, e depois de ler mais, parece que kill pidsem as bandeiras é a maneira preferida de eliminar um processo descontrolado do postgres, mas, para outros usuários da comunidade do postgres, também parece que o postgres "melhorou" ao longo dos anos, de modo que kill -9em um processo / thread de consulta individual não é mais uma sentença de morte.

Alguém pode me esclarecer sobre a maneira correta de eliminar um processo descontrolado do postgres, bem como o quão desastroso (ou benigno) o uso do kill -9Postgres atualmente? Obrigado pela compreensão.

Banjer
fonte

Respostas:

31

A resposta do voretaq7 cobre os pontos principais, incluindo a maneira correta de finalizar back-end, mas eu gostaria de adicionar um pouco mais de explicação.

kill -9(ou seja SIGKILL) nunca deve ser seu padrão de primeira escolha . Deve ser seu último recurso quando o processo não responde às solicitações normais de desligamento e um SIGTERM( kill -15) não teve efeito. Isso é verdade para Pg e praticamente todo o resto.

kill -9 não dá ao processo morto a chance de fazer nenhuma limpeza.

Quando se trata do PostgreSQL, o Pg vê um backup encerrado por kill -9um travamento . Ele sabe que o back-end pode ter corrompido a memória compartilhada - porque você poderia interrompê-lo no meio da gravação de uma página no shm ou na modificação de uma, por exemplo - para terminar e reiniciar todos os outros back - ends quando perceber que um back-end desapareceu repentinamente e saiu com um código de erro diferente de zero.

Você verá isso relatado nos logs.

Se parece não causar nenhum dano, é porque a Pg está reiniciando tudo após a falha e seu aplicativo está se recuperando das conexões perdidas de forma limpa. Isso não faz uma boa ideia. Se nada mais houver falhas de back-end são menos testadas do que as partes de funcionamento normal da Pg e são muito mais complicadas / variadas, então as chances de um erro à espreita na manipulação e recuperação de falhas de back-end são maiores.

BTW, se você kill -9remover o remetente postmaster.pide iniciá-lo novamente, sem ter certeza de que todo o postgresback - end se foi, coisas muito ruins podem acontecer . Isso pode acontecer facilmente se você acidentalmente matou o postmaster em vez de um back-end, viu o banco de dados cair, tentou reiniciá-lo, removeu o arquivo .pid "obsoleto" quando a reinicialização falhou e tentou reiniciá-lo novamente. Essa é uma das razões pelas quais você deve evitar acenar kill -9na página e não deve excluir postmaster.pid.

Uma demonstração:

Para ver exatamente o que acontece quando você é kill -9um back-end, tente estas etapas simples. Abra dois terminais, abra o psql em cada um e em cada execução SELECT pg_backend_pid();. Em outro terminal, kill -9um dos PIDs. Agora execute as SELECT pg_backend_pid();duas sessões psql novamente. Observe como os dois perderam suas conexões?

Sessão 1, que matamos:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6357
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6463
(1 row)

Sessão 2, que foi um dano colateral:

$ psql regress
psql (9.1.4)
Type "help" for help.

regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6283
(1 row)

[kill -9 of session one happens at this point]

regress=# select pg_backend_pid();
WARNING:  terminating connection because of crash of another server process
DETAIL:  The postmaster has commanded this server process to roll back the current transaction and exit, because another server process exited abnormally and possibly corrupted shared memory.
HINT:  In a moment you should be able to reconnect to the database and repeat your command.
server closed the connection unexpectedly
        This probably means the server terminated abnormally
        before or while processing the request.
The connection to the server was lost. Attempting reset: Succeeded.
regress=# select pg_backend_pid();
 pg_backend_pid 
----------------
           6464
(1 row)

Viu como as duas sessões foram interrompidas? É por isso que você não faz kill -9um back-end.

Craig Ringer
fonte
1
Todas as respostas muito boas aqui e muito humildes, devo acrescentar. Eu poderia marcar todos eles como aceitos, mas o @Craig Ringer tem alguns pontos extras aqui e realmente o deixa empolgado. Mais uma vez obrigado SF por me limpar dos meus maus hábitos!
Banjer
2
@ Craig: Que resposta excelente; e para incluir uma demonstração, eu gostaria de poder votar 100x. Sou desenvolvedor de software que trabalha com o PG diariamente e desde os dias 6.x e sua resposta é imediata! Agradável!
Quilo
2
Boa resposta. Um adendo: se você tiver um processo de back-end que não funcionará absolutamente - nem com pg_terminate_backend, nem com a reinicialização de uma pilha de servidores, nem com qualquer coisa, você pode matá-lo como quiser, mas verifique se possui um backup de trabalho do seu banco de dados. Você pode fazer isso de duas maneiras: pode usar pg_basebackupou semelhante (ou apenas rsynce pg_start\stop_backup) para fazer backup do diretório de dados (testar os backups antes de continuar!), Ou pode usar pg_dump[all]para salvar seus dados. Somente então você deve considerar kill -9, ou uma reinicialização, ou o que seja.
Zac B
1
@ ZacB Sim, e se você o matar, verifique se todos os back-ends morrem. O mais importante é nunca excluir postmaster.pid. Sempre.
Craig Ringer
29

I found the particular process via ps aux | grep postgres and ran kill -9 pid.
NÃO! RUIM! PASSO LONGE DO BACKEND!

Sério - Não mate back-end do Postgres assim - coisas terríveis podem acontecer (mesmo com todos os aprimoramentos de estabilidade que foram feitos desde os dias 7.x) que podem prejudicar todo o banco de dados e o desenvolvedor está certo em mastigar você por fazer isso.

De fato, existe uma maneira abençoada e aprovada de fazer isso no Postgres - é mesmo no manual do Postgres, embora o SO post faça um trabalho melhor de explicá-lo ...

SELECT pg_cancel_backend(pid)
Envia um SIGINTsinal cancel ( ) para o back-end especificado, que cancela a consulta atualmente em execução.

select pg_terminate_backend(pid)
Envia um SIGTERMsinal terminate ( ) para o back-end especificado, que cancela a consulta e anula o back-end (descartando sua conexão).

Os IDs de back-end podem ser obtidos na pg_stat_activitytabela (ou ps)

voretaq7
fonte
4
Caso alguém esteja se perguntando sobre as coisas terríveis, dado que kill -9não é diferente de desligar repentinamente o sistema no que diz respeito ao processo finalizado: a página é muito tolerante a falhas de back-end (como a kill -9) e nunca deve haver corrupção de dados. Não vai ser a corrupção se você matar o postmaster , postmaster.pid remover, e reiniciá-lo sem também matando todos os back-end em primeiro lugar. Isso vai destruir a sua base de dados, mas leva muito mais do que apenas um kill -9a um backend. kill -9não dá ao postmaster tempo para matar os back-ends, e é por isso que é perigoso.
Craig Ringer
2
... como um caso de consultoria de emergência que tive na semana passada. O banco de dados foi corrompido, perdeu dois dias de trabalho porque seus backups estavam falhando (e eles não testaram automaticamente suas restaurações), ficaram inativos por 48 horas. Não apague postmaster.pid.
Craig Ringer
8

Matar um processo do cliente PostgreSQL deve ser bom. Matar um processo de daemon do PostgreSQL pode fazer com que você seja repreendido.

Como os daemons SQL também possuem controles internos de processo, a maneira preferida é tentar usar esse canal primeiro.

Consulte Parar (longo) a execução de consulta SQL no PostgreSQL ... do StackOverflow.

Jeff Ferland
fonte
4
kill -9nunca deve ser sua escolha padrão, é um último recurso. Envie um SIGTERMcom kill -TERMou simples kille se o destinatário não responder depois de um tempo, somente então você deve considerar kill -KILL( kill -9).
Craig Ringer