OOM Killer e MySQL: Como Evitar que o Linux Mate seu Banco de Dados

Introdução: O Fantasma das Quedas Inesperadas

No ecossistema de administração de servidores Linux, poucos erros são tão frustrantes quanto o encerramento inesperado de um serviço crítico. Você acorda com notificações de “Database Connection Error” e, ao verificar o status, percebe que o serviço do MySQL simplesmente desapareceu. Não há erros no error.log do MySQL que expliquem uma falha interna. É aqui que entra o OOM Killer MySQL.

Neste guia extenso, vamos mergulhar nas entranhas do kernel Linux para entender por que ele decide “assassinar” o seu banco de dados e como configurar seu ambiente para que isso nunca mais aconteça.

Se o OOM Killer está sendo ativado no seu servidor, é sinal de problemas graves de memória e performance. Para entender o cenário completo, veja o guia de performance de servidores Linux.

O OOM Killer deve ser analisado junto com outros sinais do sistema. Veja também:

Parte 1: Entendendo a Arquitetura da Memória no Linux

Para entender o OOM Killer MySQL, primeiro precisamos entender como o Linux gerencia a memória RAM. O kernel opera sob um princípio de “overcommit”. Isso significa que ele permite que os processos solicitem mais memória do que realmente existe fisicamente, baseando-se na premissa de que nem todos os processos usarão toda a memória alocada ao mesmo tempo.

O Conceito de Overcommit

Imagine um restaurante que aceita reservas para 100 pessoas, mas só tem 80 cadeiras, acreditando que alguns clientes vão se atrasar ou faltar. Se todos aparecerem ao mesmo tempo, o gerente (Kernel) terá que expulsar alguém para o restaurante não colapsar.

Quando o sistema atinge um ponto de exaustão de memória (incluindo a RAM e o Swap), o kernel invoca a função out_of_memory(). É o início do julgamento do OOM Killer.


Parte 2: A Anatomia do OOM Killer

O Out-of-Memory Killer não age de forma caótica. Ele segue um algoritmo de pontuação para determinar qual processo é o menos “valioso” ou o mais “culpado” pelo esgotamento.

Como o oom_score é calculado?

O kernel atribui a cada processo um valor chamado oom_score, que você pode consultar em /proc/[PID]/oom_score. Os critérios incluem:

  1. Porcentagem de memória utilizada: Quanto mais RAM o processo usa, maior a pontuação.
  2. Tempo de vida: Processos que rodam há muito tempo são levemente protegidos, mas o uso massivo de RAM anula esse benefício.
  3. Processos de Root: Antigamente tinham um bônus de proteção, mas hoje o foco é puramente na liberação de memória.

Como o MySQL geralmente detém a maior fatia de RAM no servidor (para manter índices e dados em cache), o OOM Killer MySQL se torna uma consequência matemática quase inevitável se o servidor estiver subdimensionado.

O OOM Killer é consequência de falhas na gestão de recursos. Confira como melhorar a performance de servidores Linux.


Parte 3: Diagnosticando o “Crime” (Logs e Comandos)

Se o seu banco de dados sumiu, o primeiro passo não é reiniciar o serviço, mas sim coletar evidências forenses. O OOM Killer MySQL deixa rastros claros nos logs do sistema.

O Comando dmesg

O comando mais rápido para identificar o problema é:

dmesg -T | grep -i "out of memory"

O parâmetro -T converte os timestamps em datas legíveis. Você verá linhas indicando o total_vm, anon-rss e, finalmente, a mensagem: Killed process [PID] (mysqld).

Analisando o /var/log/syslog ou /var/log/messages

Em sistemas baseados em Debian/Ubuntu ou RHEL/CentOS, os logs detalhados mostram uma tabela de todos os processos e seus respectivos consumos no momento exato do crash. Procure pela linha oom_reap.

Parte 4: O Coração do Problema – InnoDB Buffer Pool

Se o seu servidor Linux é o corpo, o InnoDB Buffer Pool é o estômago do MySQL. É aqui que o banco de dados armazena em cache os dados das tabelas e os índices para evitar leituras lentas no disco (I/O).

Muitos administradores cometem o erro de configurar o innodb_buffer_pool_size baseando-se apenas na RAM total, esquecendo que o sistema operacional e outras threads também precisam de espaço. Quando o Buffer Pool tenta expandir ou manter dados enquanto o sistema está sob pressão, o OOM Killer MySQL é acionado para “limpar” o maior consumidor.

A Regra de Ouro da Alocação

Para evitar o OOM Killer MySQL, a recomendação técnica varia conforme o tamanho da sua instância:

  • Servidores com < 1GB de RAM: Não use MySQL com configurações padrão; use instâncias leves ou aumente a RAM.
  • Servidores entre 2GB e 8GB: Aloque cerca de 60% a 70% da RAM para o Buffer Pool.
  • Servidores com > 32GB (Dedicados): Você pode chegar a 80%, deixando 20% para o kernel e buffers de rede.

Problemas de memória estão diretamente ligados à performance geral. Veja a estratégia de otimização de servidores Linux.


Parte 5: O Cálculo de Memória por Conexão (O Vilão Silencioso)

Um erro comum que leva ao OOM Killer MySQL é ignorar que cada nova conexão ao banco de dados consome uma fatia extra de RAM. Não é apenas o cache global que conta.

Existem buffers que são alocados por thread (por conexão). Se você tem um max_connections configurado como 500, e cada conexão pode usar 10MB de buffers temporários, você tem um consumo potencial de 5GB de RAM além do que já foi definido no Buffer Pool.

Equação de Consumo Máximo de Memória

Para prever se o seu servidor sofrerá um ataque do OOM Killer MySQL, use esta fórmula simplificada:

$$Memória\_Total = Global\_Buffers + (Per\_Thread\_Buffers \times max\_connections)$$

Onde os Global Buffers incluem:

  • innodb_buffer_pool_size
  • innodb_log_buffer_size
  • key_buffer_size

E os Per-Thread Buffers incluem:

  • read_buffer_size
  • read_rnd_buffer_size
  • sort_buffer_size
  • join_buffer_size
  • thread_stack

Se o resultado dessa soma for maior que a sua RAM física disponível (descontando o que o SO usa), o OOM Killer MySQL é apenas uma questão de tempo.


Parte 6: Memória Swap – A Rede de Segurança

A ausência de uma partição Swap é o caminho mais rápido para o OOM Killer MySQL. O Swap é um espaço no disco que o Linux usa como “extensão” da RAM. Embora o MySQL sofra uma queda drástica de performance se começar a fazer swapping (devido à lentidão do disco em comparação à RAM), ter Swap evita que o processo seja morto imediatamente.

Por que o Swap é essencial?

  1. Evita o pânico imediato: O kernel move páginas de memória inativas (como processos de sistema pouco usados) para o disco, liberando RAM real para o MySQL.
  2. Monitoramento: Se você notar que o uso de Swap está crescendo, você tem tempo de agir antes do OOM Killer MySQL ser acionado.
  3. Veja o artigo: Qual deve ser o tamanho da sua partição de swap?

Como criar um arquivo Swap rapidamente:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

Parte 7: Otimização de Queries e Tabelas Temporárias

Muitas vezes, o OOM Killer MySQL não é culpa de uma configuração errada, mas de uma query mal escrita. Quando você executa um SELECT complexo com GROUP BY ou ORDER BY em colunas sem índice, o MySQL cria uma tabela temporária em memória.

Se essa tabela exceder o tamanho definido em tmp_table_size ou max_heap_table_size, o MySQL tentará convertê-la em uma tabela em disco. No entanto, o processo de gerenciamento dessa memória durante a transição pode causar um pico de consumo que atrai a atenção do OOM Killer MySQL.

Parte 8: Ajustes de Kernel e o parâmetro sysctl

Muitas vezes, a solução para o OOM Killer MySQL não está dentro do my.cnf, mas sim nas entranhas do arquivo /etc/sysctl.conf. O Linux possui parâmetros que controlam como ele lida com o esgotamento de memória e o “overcommit”.

Veja o artigo: Tuning de sysctl para Produção: Guia Definitivo de Performance Linux

O Parâmetro vm.swappiness

Este valor (de 0 a 100) define a agressividade com que o Linux move processos da RAM para o Swap.

  • Valor 10 a 60: Recomendado para a maioria dos servidores.
  • Valor 1: O kernel só usará o Swap em último caso, o que pode atrasar, mas não impedir o OOM Killer MySQL.
  • Valor 0: Pode causar pânico no kernel em versões mais antigas.

Para ajustar temporariamente: sysctl -w vm.swappiness=10.

O Parâmetro vm.overcommit_memory

Este é o “botão de pânico”. Ele define se o kernel deve permitir que os processos peçam mais memória do que existe.

  • 0 (Heuristic): O padrão. O kernel decide se aceita ou não.
  • 2 (Don’t Overcommit): O kernel só permite alocações dentro de um limite rigoroso (RAM + % do Swap). Isso evita o OOM Killer MySQL matando o processo, mas pode fazer com que o MySQL retorne erros de “Out of memory” internamente ao tentar iniciar ou alocar buffers.

Parte 9: Monitoramento Proativo (Evitando o Assassinato)

A melhor forma de lidar com o OOM Killer MySQL é nunca deixar que ele precise agir. Para isso, o monitoramento visual é indispensável.

Prometheus e Grafana

Utilizar o mysqld_exporter junto ao Prometheus permite que você visualize o gráfico de uso do InnoDB Buffer Pool versus a RAM livre do sistema. Se a linha de “Free RAM” estiver em tendência de queda constante, você receberá um alerta antes do crash.

Alertas de OOM no Slack/Discord

Você pode criar um script simples que monitora o dmesg e envia um alerta imediato se o termo “Out of Memory” aparecer. Isso permite uma intervenção manual (como o reinício de serviços secundários) antes que o banco caia.


Parte 10: Estratégias de Recuperação Pós-Incidente

Se o OOM Killer MySQL já aconteceu, a recuperação envolve mais do que apenas um systemctl restart mysql.

  1. Verificação de Integridade: O MySQL (especialmente com InnoDB) é resiliente, mas quedas abruptas podem corromper tabelas temporárias ou exigir um longo tempo de Crash Recovery ao iniciar. Verifique o error.log durante o boot.
  2. Análise de Process List: Se o MySQL voltar e o uso de RAM subir rapidamente, use SHOW FULL PROCESSLIST; para identificar se há uma query “zumbi” ou um relatório pesado sendo gerado que está devorando os buffers.
  3. Redimensionamento Vertical: Se o seu cálculo de memória (visto na Parte 5) mostrar que você está usando 95% da RAM em condições normais, não há otimização que salve: você precisa de um upgrade de hardware para afastar o OOM Killer MySQL.

Parte 11: Otimização de Tabelas e Fragmentação

A fragmentação de tabelas pode causar um uso ineficiente do Buffer Pool. Quando você deleta muitos registros, o MySQL mantém “buracos” nas páginas de dados. O Buffer Pool acaba carregando essas páginas meio vazias para a RAM, desperdiçando espaço precioso.

Executar um OPTIMIZE TABLE nome_da_tabela; periodicamente (em horários de baixo tráfego) ajuda a compactar os dados no disco e, consequentemente, melhora a eficiência do uso da memória, reduzindo a pressão que atrai o OOM Killer MySQL.

Evitar o OOM Killer exige ajustes completos no sistema. Veja como melhorar a performance do servidor Linux.


Conclusão Técnica: O Equilíbrio entre Performance e Estabilidade

Dominar o OOM Killer MySQL exige uma compreensão profunda de que o banco de dados não vive isolado; ele é um inquilino no servidor Linux. Configurar o MySQL para usar toda a RAM disponível parece uma boa ideia para performance, mas é um convite para o desastre em sistemas multitarefa.

Manter uma margem de segurança de pelo menos 15% de RAM livre, configurar um Swap adequado e monitorar o oom_score dos seus processos são as colunas que sustentam um ambiente de produção estável. Lembre-se: é melhor uma query um pouco mais lenta devido ao limite de cache do que um banco de dados offline porque o kernel decidiu que ele era grande demais para sobreviver.

Para evitar quedas e instabilidade, é essencial otimizar o ambiente completo. Consulte o guia de como otimizar servidores Linux.


Resumo de Configurações Recomendadas para o my.cnf:

Veja também o artigo:Tuning MariaDB e MySQL: 5 Ajustes no my.cnf (Foco InnoDB).

[mysqld]
# Proteção contra OOM Killer MySQL
innodb_buffer_pool_size = 70% da RAM total
innodb_buffer_pool_instances = 8 (para reduzir contenção)
max_connections = 150 (ajuste conforme sua RAM)
max_heap_table_size = 64M
tmp_table_size = 64M
# Buffers por thread - Cuidado com estes!
sort_buffer_size = 2M
join_buffer_size = 2M

Conclusão: O Equilíbrio Vital entre MySQL e Kernel Linux

Chegamos ao fim deste mergulho profundo sobre o OOM Killer MySQL. Como vimos ao longo deste guia, a queda de um banco de dados por falta de memória raramente é um evento aleatório; é quase sempre o resultado final de uma configuração que ignorou os limites físicos do hardware ou a natureza multitarefa do kernel Linux.

O OOM Killer MySQL não deve ser visto como um “vilão” ou um erro do sistema, mas sim como o último mecanismo de defesa de um sistema operacional que está tentando sobreviver. Sem ele, o servidor entraria em um estado de kernel panic, travando completamente e, potencialmente, causando corrupção de dados muito mais grave do que um simples encerramento de processo.

Lições Aprendidas para o Administrador de Bancos de Dados

Para garantir que o seu ambiente de produção seja resiliente, as lições fundamentais que discutimos podem ser resumidas em três pilares:

  1. Respeito aos Limites de Hardware: Nunca configure o seu innodb_buffer_pool_size no limite máximo da RAM disponível. O MySQL precisa de “espaço para respirar” para suas threads internas e o sistema operacional precisa de memória para gerenciar I/O e processos de rede.
  2. Monitoramento é Prevenção: O uso de ferramentas como Prometheus, Grafana ou mesmo scripts simples de monitoramento de log permite que você identifique a aproximação do OOM Killer MySQL horas ou dias antes de o evento ocorrer. A análise do oom_score é um termômetro vital para a saúde do servidor.
  3. Configuração de Redes de Segurança: O Swap, embora lento, é essencial. Ajustar parâmetros como vm.swappiness e oom_score_adj permite que você dite as regras do jogo para o kernel, protegendo o MySQL em momentos de pico de tráfego.

O Futuro da Gestão de Memória

Com a ascensão de ambientes conteinerizados como Docker e Kubernetes, o OOM Killer MySQL ganha novos contornos. Em clusters de alta disponibilidade, o encerramento de um pod por limite de memória (OOMKilled) é um sinal claro de que os limits e requests do Kubernetes precisam de revisão imediata. Independentemente da tecnologia, o princípio permanece o mesmo: a memória é o recurso mais precioso e finito do seu servidor.

Ao implementar as otimizações de my.cnf, ajustar os parâmetros de kernel no sysctl e manter uma rotina de análise de queries lentas, você transforma o seu servidor de uma “vítima em potencial” em uma fortaleza de dados. A estabilidade do seu OOM Killer MySQL não depende da sorte, mas de uma engenharia precisa e de uma vigilância constante.


Check-list Final de Estabilidade

  • [ ] O innodb_buffer_pool_size está abaixo de 80% da RAM livre?
  • [ ] O Swap está ativo e configurado corretamente?
  • [ ] O log dmesg foi verificado para descartar incidentes passados?
  • [ ] As queries que geram grandes tabelas temporárias foram otimizadas?
  • [ ] O max_connections está condizente com a RAM disponível por thread?

Seguindo este manual, você garante que o “matador de processos” do Linux nunca mais tenha motivos para escolher o seu banco de dados como alvo. A performance é importante, mas a disponibilidade é o que mantém os negócios rodando.

FAQ

O que é o OOM Killer?

É um mecanismo do kernel Linux que encerra processos para liberar memória quando o sistema está em estado crítico.

Por que o OOM Killer escolhe o MySQL?

Devido ao alto consumo de RAM e ao tempo de atividade longo, o MySQL recebe um oom_score elevado.

Como evitar o crash do MySQL por falta de memória?

Ajustando o innodb_buffer_pool_size e monitorando o consumo de buffers por conexão.

Veja Mais:

Performance de Servidores Linux: Guia Completo 2026
Servidor Lento: Como Identificar o Gargalo
I/O de disco servidor Linux: Como Resolver Gargalos
CPU 100% no Linux: O Que Verificar Primeiro no Servidor

Como Usar vmstat para Achar Gargalo no Linux em Minutos
Load Average no Linux: Como Interpretar Corretamente
Como Achar Gargalo com Iostat: Guia Definitivo e Prático
Iowait Alto: Causas Reais e Soluções
Swap Alto com RAM Livre: Por Que Isso Acontece e como Resolver
Tuning de sysctl para Produção: Guia Definitivo de Performance Linux
Como Ajustar limits.conf no Linux: Guia para Alta Performance
Guia Completo de Monitoramento Linux com vmstat, iostat e sar
Memory Leak Linux: Como Detectar e Corrigir
No space left on device com espaço livre? Como resolver (Guia Completo)
Como identificar processo que consome CPU no Linux (Guia Completo)
Como Limitar CPU por Processo no Linux com cgroups (Guia Completo)
Upgrade de CPU ou Otimizar? Guia Completo
RAM Cheia no Linux: O Guia Definitivo para Resolver Travamentos em 2026
Buffers e Cache: Quando Deixam de Ajudar e Viram um Problema?
Out of Memory (OOM): Causas Reais, Diagnóstico e Como Resolver
Como evitar OOM Killer Linux em Produção: Guia Definitivo 2026
Gargalo no Linux: Como Identificar se o Problema é CPU ou RAM?
Disco Lento no Linux: Guia Completo para Identificar e Resolver
Latência de Disco no Linux Alta: Causas, Diagnóstico e Soluções

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *