Quando o sistema travou e você não sabe o que fazer
Às vezes você aperta um botão errado ou deixa um script rodar em loop e o servidor simplesmente para de responder. A primeira reação é tentar entrar no terminal, ver que não consegue, e aí pensa: bom, agora vou ter que ligar pra alguém. Eu passei por isso numa sexta à tarde, por volta das 17h. Um job do cron tinha entrado em loop, consumindo toda a memória RAM de um servidor de banco PostgreSQL. O processo principal morreu, mas o postgres ficou num estado que eu chamaria de "semi-morto": não respondia conexões novas, mas também não terminava os processos filhos. Liguei pro cliente às 18h dizendo que ia precisar de uns 40 minutos pra resolver, e eles não ficaram muito felizes com isso.
O problema real que as pessoas ignoram
A maioria dos tutoriais fala só de dar kill -9 em tudo e reiniciar. Isso funciona na maioria das vezes, mas tem um detalhe que quase ninguém menciona: quando você mata um processo que está escrevendo em disco, especialmente arquivos de log ou de banco de dados, você cria o cenário perfeito pra corrupção. O processo morre, o SO espera o flush dos buffers, e se o processo não responde no tempo certo, os dados ficam truncados no meio. Eu vi isso acontecer com um arquivo de WAL do PostgreSQL. O processo tinha sido morto enquanto fazia check-point. O banco aceitava conexões depois do restart, mas quando alguém tentava rodar uma consulta específica, recebia um erro de "could not read block 42 in file...". Levei duas horas pra recuperar aquilo porque não tinha backup recente do dia anterior.
Como lidar com that time you killed me de verdade
Aqui vai o que eu faço quando o servidor trava e eu preciso entrar no modo de recuperação. Não é glamouroso, mas funciona. Primeiro passo: Verifique se o sistema ainda responde ao SSH. Às vezes o serviço de rede ou o sshd está vivo mas o sistema operacional está tão sobrecarregado que leva 30 segundos pra responder cada comando. Se você tá vendo conexão estabelecida mas nenhum comando executa, o problema é outro — provavelmente deadlock no kernel, e o único jeito é reboot.
Segundo passo: Tente ver o que está consumindo recursos antes de mataranything. Comandos como top -bn1 ou ps aux --sort=-%mem | head -20 dão uma foto rápida. Se você consegue executar isso, já sabe qual processo está causando o estrago sem precisar adivinhar. No caso do meu server do PostgreSQL, foi um script Python chamado backup_loop.py que eu mesmo tinha escrito e esquecido que estava no crontab com intervalo de 30 segundos. Terceiro passo: Se o processo está preso em loop e consumindo CPU/memória, tente primeiro um kill -15 (SIGTERM). Esse sinal pede educação pro processo encerrar. Ele dá tempo pra cleanup de arquivos temporários e flush de dados. Só use kill -9 (SIGKILL) se o SIGTERM não funcionar em 10 segundos. A diferença entre esses dois sinais é o que acontece com os arquivos abertos pelo processo quando ele morre.
Eu costumava usar kill -9 por padrão. Parou de fazer isso depois que perdi dados de produção por causa disso. Agora uso o -15 sempre primeiro, e só recorro ao -9 quando realmente preciso — quando um processo ignore sinais e continua rodando como zumbi.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Quando nada disso funciona
Às vezes o sistema simplesmente não responde mais a nada. SSH cai, ping retorna mas o console não dá resposta. Nesse caso, você tem três opções reais:
- Reboot forçado pelo painel da AWS/DigitalOcean/Vultr (se for cloud, o botão "reboot" na interface resolve 90% desses casos em menos de 2 minutos)
- Entrar via console serial se seu provedor oferecer
- Ligar pros colegas no datacenter e pedir pra dar um cycle de energia manualmente
A opção um é a que eu mais uso. A dois eu só tive que usar uma vez num servidor físico remoto na Alemanha, e a três eu rezo pra nunca precisar pedir.
Prevenção: o que eu mudei depois do incidente
Depois daquela sexta-feira, eu mudei três coisas na minha configuração: Scripts que rodam no cron agora têm timeout envolvente. Em vez de deixar um script rodar até morrer ou travar, eu coloco um limite de tempo. Se o script levar mais de 5 minutos pra rodar, o timeout mata ele automaticamente. Isso evita loops infinitos que consomem recursos sem necessidade.
Monitoramento básico com alertas. Eu uso o htop configurado com cores, e coloco um alertador simples no Nagios que te avisa se um processo específico usar mais de 80% de CPU por 5 minutos consecutivos. O alerta chega por Slack, e eu vejo antes do servidor ficar inutilizável. Backups automáticos diários, sim, isso já deveria ser óbvio mas eu negligenciei por dois anos num dos meus servidores. Agora tenho um backup diário com retenção de 7 dias, testado todo mês pra garantir que os arquivos realmente podem ser restaurados. Backup sem teste de restauração é só esperança.
A questão que ninguém menciona
O problema principal de lidar com servidores travados é a falta de informação. Você entra no sistema e não faz ideia do que aconteceu. Logs podem estar cheios de lixo, o último log util pode ser do dia anterior, e o que você precisa saber é o quê exatamente causou o travamento. Uma solução simples que eu adotei: configuro o journalctl pra fazer rotação automática e manter logs das últimas 72 horas. Assim, quando algo dá errado, eu posso rodar journalctl -u nome-do-servico --since "2 hours ago" e ver exatamente o que aconteceu nos momentos antes do crash. Isso substituiu a necessidade de ter um sistema de log centralizado complexo num monte de servidores pequenos.
Eu ainda sinto aquele frio na barriga quando o servidor para de responder. Mas agora consigo resolver em 15 minutos na maioria das vezes, ao invés de 40. E o mais importante: nunca mais perdi dados porque deixei de testar o backup.