kill -9 um processo postgres

22

Uma consulta SELECT postgres ficou fora de controle em nosso servidor de banco de dados e começou a consumir toneladas de memória e a trocar até que o servidor ficou sem memória. Eu encontrei o processo específico via ps aux | grep postgres e executei kill -9 pid . Isso matou o processo e a memória foi liberada como esperado. O restante do sistema e as consultas postgres pareciam não ser afetadas. Este servidor está executando o postgres 9.1.3 no SLES 9 SP4.

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

Com isso dito, e depois de ler mais, parece que kill pid sem as flags é a maneira preferida de matar um processo postgres, mas por outros usuários na comunidade postgres, também parece que o postgres "melhorou "ao longo dos anos, tal que kill -9 em um processo / thread de consulta individual não é mais uma sentença de morte.

Alguém pode me esclarecer sobre a maneira correta de matar um processo de postgres descontrolado, bem como o quão desastroso (ou benigno) é usar o kill -9 no Postgres atualmente? Obrigado pelo insight.

    
por Banjer 07.08.2012 / 19:09

3 respostas

29

do voretaq7 A resposta abrange os pontos-chave, incluindo a maneira correta de encerrar back-ends , mas eu gostaria de adicionar um pouco mais explicações.

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

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

Quando se trata de PostgreSQL, o Pg vê um backup que é terminado por kill -9 como uma falha suportada . Ele sabe que o backend pode ter corrompido a memória compartilhada - porque você poderia ter interrompido a gravação de uma página em shm ou a modificação de um, por exemplo - então termina e reinicia todos os outros backends quando percebe que um backend desapareceu de repente e saiu com um código de erro diferente de zero.

Você verá isso nos relatórios.

Se parecer que não faz mal, porque a Pg está reiniciando tudo após o travamento e seu aplicativo está se recuperando das conexões perdidas de forma limpa. Isso não faz uma boa ideia. Se nada mais for travado, as falhas de backend são menos bem testadas do que as partes com funcionamento normal do Pg e são muito mais complicadas / variadas, então as chances de um bug escondido no tratamento de falhas e recuperação de backend são maiores.

BTW, se você kill -9 o postmaster, em seguida, remover postmaster.pid e iniciá-lo novamente sem certificar-se de que todos os backends postgres tenham desaparecido, coisas muito ruins podem acontecer . Isso poderia acontecer facilmente se você acidentalmente matasse o postmaster em vez de um backend, visse o banco de dados caiu, 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 -9 em torno de Pg e não deve excluir postmaster.pid .

Uma demonstração:

Para ver exatamente o que acontece quando você usa kill -9 , experimente estas etapas simples. Abra dois terminais, abra o psql em cada um deles e, em cada execução, execute SELECT pg_backend_pid(); . Em outro terminal kill -9 one dos PIDs. Agora execute SELECT pg_backend_pid(); em ambas as sessões do psql novamente. Observe como eles ambos 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)

Veja como ambas sessões foram quebradas? É por isso que você não usa kill -9 em um backend.

    
por 09.08.2012 / 01:57
28

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

Sério - Não mate os backends do Postgres assim - TERRÍVEIS as coisas podem acontecer (mesmo com todos os aprimoramentos de estabilidade que foram feitos desde os 7.x dias) que podem destruir todo o seu DB, e seu desenvolvedor é bastante direito de mastigar você por fazer isso.

Existe, de fato, uma maneira abençoada e aprovada de fazer isso a partir do Postgres - É mesmo no Manual do Postgres , embora essa postagem SO faça um trabalho melhor de explicá-la ...

SELECT pg_cancel_backend(pid)
Envia um sinal de cancelamento ( SIGINT ) para o backend especificado, o que cancela a consulta atualmente em execução.

select pg_terminate_backend(pid)
Envia um sinal de término ( SIGTERM ) para o backend especificado, o que cancela a consulta e aborta o backend (encerrando sua conexão).

IDs de back-end podem ser obtidas na tabela pg_stat_activity (ou ps )

    
por 07.08.2012 / 19:43
8

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

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

Veja Interromper (longa) a execução da consulta SQL no PostgreSQL ... a partir do StackOverflow.

    
por 07.08.2012 / 19:20