PostgreSQL trata kill -9 em uma conexão como se fosse um crash geral
Um post publicado em 9 de outubro de 2026 por Shridhar Khanal explica por que um sinal enviado a um único processo filho do PostgreSQL derruba todas as conexões e dispara recuperação de WAL, mesmo sem ninguém reiniciar o serviço.
O sintoma: um crash recovery sem motivo aparente
Em um artigo publicado em 9 de outubro de 2026 no Planet PostgreSQL↳PostgreSQL11 conteúdosPostgreSQL via SSL com GolangData · abr 20195 itens legais sobre data types do PostgreSQLData · mar 20195 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data →, o DBA Shridhar Khanal, da Stormatics, descreve um cenário familiar para quem administra Postgres em produção: uma linha de log como server process (PID 48213) was terminated by signal 1: Hangup, seguida de recuperação automática. Todas as conexões caem, a aplicação cospe erros por meio minuto, e depois tudo volta como se nada tivesse acontecido.
O detalhe estranho, segundo Khanal, é que o sinal 1 é justamente o SIGHUP, o mesmo que o PostgreSQL usa para recarregar configuração sem derrubar nada. Entender por que ele aparece num log de crash exige entender o que são sinais do sistema operacional e como o PostgreSQL reage a cada um deles.
O que é um sinal, afinal
Um sinal é uma notificação enviada por outro processo ou pelo próprio sistema operacional a um processo em execução. Ele não carrega dado algum: apenas avisa que algo aconteceu, como "pare", "cancele o que está fazendo" ou "o terminal caiu". Cada sinal tem nome e número, e os dois são intercambiáveis: comandos usam o nome, enquanto o log do PostgreSQL mostra o número seguido de uma descrição curta.
Os sinais mais relevantes para quem opera PostgreSQL, segundo o artigo, são estes:
| Número | Nome | Significado original | Resposta do PostgreSQL |
|---|---|---|---|
| 1 | SIGHUP | terminal desconectado | recarrega a configuração |
| 2 | SIGINT | interrupção (Ctrl+C) | cancela a query atual, via pg_cancel_backend() |
| 3 | SIGQUIT | saída imediata (Ctrl+\) | encerra a sessão sem limpeza |
| 9 | SIGKILL | matar | ninguém trata nem ignora; o processo simplesmente morre |
| 13 | SIGPIPE | pipe quebrado | ignorado; o PostgreSQL trata a conexão perdida por conta própria |
| 15 | SIGTERM | pedido de término | encerra a sessão de forma limpa, via pg_terminate_backend() |
Um sinal não faz nada por si só: o que acontece depende do programa que o recebe. Um processo pode rodar um código próprio para aquele sinal (um signal handler), ignorá-lo, ou não fazer nada especial, caso em que o Linux↳Linux34 conteúdosKali Linux em um Servidor VPS: como, quando e por que usar?DevSecOps · dez 2024Construindo um Windows Service ou Linux Daemon com Worker Service & .NET Core – Parte 2Dev (Back & Front) · jul 2020Criando uma WebApi utilizando .NET, Linux e VSCodeDev (Back & Front) · ago 2019Ver tudo em DevSecOps → aplica a ação padrão. Para o SIGHUP, a ação padrão é encerrar o programa.
Por que PostgreSQL sobrevive ao SIGHUP e a maioria dos programas não
Quem já rodou um pg_dump longo via SSH e viu a conexão cair com a Wi-Fi sabe o efeito prático dessa ação padrão: ao fechar a sessão, o sistema envia SIGHUP aos processos daquele terminal, e como pg_dump não tem tratamento para esse sinal, o Linux simplesmente o encerra. É por isso que DBAs costumam rodar jobs longos assim:
nohup pg_dump mydb > mydb.sql &nohup significa "no hang-up": instrui o job a ignorar o SIGHUP, para que continue rodando mesmo depois que a sessão se fecha. O PostgreSQL, por outro lado, tem no próprio código-fonte um tratamento para o sinal 1: quando ele chega, o processo relê a configuração e segue em frente em vez de morrer. É esse comportamento que aparece toda vez que alguém executa SELECT pg_reload_conf(); — o sinal chega ao processo principal, que o repassa aos demais, e nenhum deles morre.
A arquitetura por trás do susto
O PostgreSQL não roda como um processo único. Ele roda como uma família de processos, com o postmaster como pai: inicia primeiro, aceita conexões, sobe os demais processos e fica de olho neles. Cada conexão ganha um backend↳Back-end49 conteúdosIntegração front-end com backend: 7 decisões que evitam caos entre APIs, BFF e GraphQLDev (Back & Front) · abr 2026Como criar uma FAKE API REST para testes — JSONPlaceholderDev (Back & Front) · set 2025Construindo um aplicativo de bate-papo de IA simples com Spring AI e AngularDev (Back & Front) · jul 2025Ver tudo em Dev (Back & Front) → próprio, e processos de segundo plano cuidam de tarefas como checkpoint e autovacuum.
Todos esses processos compartilham uma área de memória, a shared memory, onde ficam dados em cache, locks e outros estados compartilhados. Em resumo: essa memória compartilhada é parte do que torna o PostgreSQL rápido, mas é também o motivo pelo qual a falha de um único processo pode afetar todas as conexões de uma vez.
Duas linhas de log que parecem iguais, mas não são
O PostgreSQL escreve duas linhas bem diferentes envolvendo SIGHUP, e confundir as duas é o que gera o mistério descrito por Khanal:
received SIGHUP, reloading configuration files: é um recibo. O postmaster recebeu o sinal 1 e está recarregando. Está tudo bem.server process (PID 48213) was terminated by signal 1: Hangup: é um atestado de óbito. Um filho do postmaster morreu, e a causa foi o sinal 1.
O rótulo "server process" não significa que o processo pertencia ao PostgreSQL: significa apenas que ele era filho do postmaster. Em versões mais novas, esse atestado pode aparecer com um rótulo mais específico, como client backend, em vez de server process.
Por que a morte de um processo filho reseta tudo
Quando um processo morre, o Linux limpa a memória dele, fecha seus arquivos e avisa o pai. O que o Linux não consegue limpar é a shared memory do PostgreSQL, porque ele não sabe o que há dentro dela. Um processo morto de repente pode ter estado segurando um lock, ou no meio da escrita de uma página de dados — e o postmaster não tem como verificar, então assume o pior cenário.
Por isso, quando o postmaster descobre que um filho foi morto por um sinal, ele: encerra todos os outros processos; reseta a shared memory; e reproduz o write-ahead log (WAL) para trazer o banco de volta a um estado consistente. O processo postmaster em si nunca para, então seu PID continua o mesmo e o servidor nunca parece ter reiniciado de fato. Esse comportamento automático é controlado pelo parâmetro restart_after_crash, ligado por padrão.
O ponto central do artigo de Khanal é que o postmaster reage a como um filho morreu, não a o que esse filho era. Se, por qualquer motivo, um processo que não é do PostgreSQL acabar como filho do postmaster e for morto por um sinal sem handler, a mesma regra se aplica: o postmaster vê um filho morto por sinal, assume que a memória compartilhada pode estar comprometida e reseta tudo, mesmo que aquele processo jamais tenha tocado em shared memory.
A versão cotidiana do problema: o kill -9
Não é preciso um processo estranho para disparar esse reset: o gatilho mais comum, segundo o artigo, é um kill -9 bem-intencionado. Alguém encontra o PID de uma query lenta no top e mata o processo. A query para, mas junto com ela caem todas as outras conexões do servidor, e o log mostra terminated by signal 9: Killed, seguido da mesma recuperação de crash. O OOM killer do Linux usa o mesmo sinal 9, então ficar sem memória RAM dispara exatamente o mesmo reset.
O caminho seguro é deixar o próprio PostgreSQL fazer a parada. Primeiro, identificar o processo:
SELECT pid, usename, state, now() - query_start AS running_for, query
FROM pg_stat_activity
WHERE state = 'active'
ORDER BY running_for DESC;Depois, cancelar a query antes de encerrar a sessão:
-- Passo 1: cancela a query, mantém a conexão
SELECT pg_cancel_backend(48213);
-- Passo 2: se não bastar, encerra a sessão
SELECT pg_terminate_backend(48213);As duas funções passam pelo tratamento interno de sinais do PostgreSQL, então o processo se limpa sozinho e só aquela sessão é afetada — nada de reset geral. Para usá-las, é preciso ser superusuário, estar conectado com o mesmo papel da sessão-alvo, ou pertencer ao papel pg_signal_backend.
O que fica em aberto
O artigo de Khanal é o primeiro de uma série e deixa duas perguntas propositalmente sem resposta: como um processo que o PostgreSQL nunca iniciou acaba virando filho do postmaster, e quem de fato enviou o sinal 1 no caso descrito. A segunda parte, prometida pelo autor, promete um teste reproduzível e recomendações para evitar que isso aconteça em produção.
Para quem opera PostgreSQL em ambiente real, a lição imediata já vale a leitura: antes de recorrer a kill -9 sob pressão, vale parar e checar pg_stat_activity. Um pg_cancel_backend() bem aplicado custa um comando a mais e evita meio minuto de erros em cascata para todos os usuários conectados, não só para a sessão que estava incomodando.
Fonte: Planet PostgreSQL
Este artigo foi escrito por Roberto Diniz, colunista de banco de dados. Conteúdo produzido por agente de IA da redação iMasters, sob revisão editorial humana. Saiba como produzimos no expediente.
Thread pool no Percona Server: como configurar para ganhar throughput sob alta concorrência
Benchmark da Percona mostra que o thread pool pode multiplicar o throughput por quase 18 vezes em cenários de alta concorrência, mas também pode piorar o desempenho se mal configurado. Entenda os parâmetros que decidem o resultado.











