← Voltar ao blog
    Banco de Dados8 min
    Como configurar memória corretamente no MySQL 8

    Como configurar memória corretamente no MySQL 8.

    Um MySQL 8 pode parecer estável até o momento em que o pico de conexões coincide com uma consulta cara, um backup e a pressão de memória do sistema operacional. É nesse ponto que saber como configurar memória corretamente no MySQL 8 deixa de ser uma tarefa de tuning e passa a ser uma disciplina de continuidade operacional. Em ambientes transacionais, alocar memória sem modelo de capacidade é uma das formas mais rápidas de trocar baixa latência por swap, OOM Killer e indisponibilidade.

    A configuração correta não nasce de valores copiados de um tutorial. Ela depende da RAM física, do papel do servidor, da concorrência real, do volume de dados ativos, do mecanismo de armazenamento e da margem exigida para o sistema operacional, monitoramento, backups e processos auxiliares. Produção crítica não comporta percentuais mágicos.

    O princípio da memória no MySQL 8

    A memória do MySQL se divide, na prática, em duas categorias: global e por conexão. A memória global é reservada ou utilizada pela instância como um todo. A memória por conexão pode crescer à medida que usuários, aplicativos e jobs concorrentes executam operações. O risco está justamente na segunda categoria: um valor aparentemente pequeno, multiplicado por centenas ou milhares de sessões, pode ultrapassar a memória disponível.

    O cálculo que precisa orientar a operação é simples em conceito, embora exija medições reais:

    memória potencial = memória global + (memória por sessão × conexões simultâneas) + reserva do sistema operacional

    O termo decisivo é conexões simultâneas, não o número médio de conexões. Se um aplicativo abre 800 conexões em um pico, é esse cenário que deve ser suportado ou controlado. Configurar `max_connections` muito acima da capacidade do host não cria resiliência. Apenas adia uma falha mais difícil de diagnosticar.

    Também é necessário separar servidor dedicado de servidor compartilhado. Em um host exclusivo para MySQL, a instância pode usar uma parcela maior da RAM. Em uma máquina que executa agentes, ETL, backup local, proxy ou outros serviços, a folga deve ser maior. Consumir toda a RAM disponível é erro de arquitetura, não sinal de eficiência.

    Como configurar memória corretamente no MySQL 8 em produção

    Comece pelo inventário operacional. Registre a memória física, a RAM efetivamente disponível ao MySQL, o uso de swap, o máximo histórico de conexões, os picos de throughput, o tamanho do dataset ativo e a taxa de leituras físicas no armazenamento. Sem essa linha de base, qualquer alteração é tentativa e erro.

    Em seguida, defina um orçamento de memória. Em servidores Linux dedicados, é comum destinar a maior parte da RAM ao MySQL, mas preservando espaço para kernel, cache de página, ferramentas de observabilidade e eventos anormais de carga. A proporção exata depende do perfil. Um banco com intenso uso de tabelas InnoDB terá uma distribuição diferente de uma instância com muitas tabelas temporárias, relatórios analíticos ou conexões curtas e numerosas.

    Aplique alterações gradualmente, com janela de observação e plano de reversão. Nem toda variável pode ser ajustada dinamicamente, e uma mudança válida em homologação pode se comportar de forma distinta sob concorrência de produção. Documente o valor anterior, a hipótese técnica, o impacto esperado e os indicadores que validarão a decisão.

    InnoDB Buffer Pool: a principal alocação

    Para a maioria dos ambientes transacionais, `innodb_buffer_pool_size` é a variável mais relevante. Ela define a área de memória usada pelo InnoDB para manter páginas de dados e índices em cache. Quando o conjunto de dados mais acessado cabe no buffer pool, o banco reduz leituras no disco e mantém latência mais previsível.

    O erro comum é configurar o buffer pool no limite da RAM física. O MySQL precisa de outras estruturas globais e de memória alocada por sessão. O sistema operacional também precisa respirar. Se o buffer pool ocupa uma parcela excessiva da máquina, uma variação de conexões ou uma operação de ordenação pode levar o host a swapar ou encerrar processos por falta de memória.

    Em um servidor dedicado, o buffer pool frequentemente recebe a maior parcela do orçamento do MySQL. Mas o número deve nascer da capacidade total, não de uma regra fixa. Avalie o volume de leituras de disco, a proporção de acessos atendidos em memória, a atividade de páginas sujas e o tempo de checkpoint. Buffer pool grande demais também pode ampliar o tempo de recuperação após uma queda, especialmente quando há pressão de I/O.

    `innodb_buffer_pool_instances` merece atenção em máquinas com buffer pool grande e alta concorrência. Dividir o pool pode reduzir contenção interna, mas criar muitas instâncias em um ambiente menor não entrega ganho automático. No MySQL 8, a decisão deve ser validada por métricas de carga e waits, não por hábito.

    Conexões e buffers por sessão: onde a memória escapa

    Variáveis como `sort_buffer_size`, `join_buffer_size`, `read_buffer_size`, `read_rnd_buffer_size` e `thread_stack` são alocadas por sessão, total ou parcialmente conforme a operação. `tmp_table_size` e `max_heap_table_size` também influenciam a memória que consultas podem consumir com tabelas temporárias internas em determinadas situações.

    Aumentar esses parâmetros para acelerar uma consulta específica é uma decisão perigosa quando a instância atende muitas sessões. Um `sort_buffer_size` de 8 MB parece irrelevante isoladamente. Sob 500 conexões realizando ordenações, a projeção muda rapidamente. E nem todas as consultas necessitam desse buffer. Na maior parte dos casos, corrigir índice, plano de execução ou modelo de consulta oferece ganho superior e risco menor do que inflar buffers globais.

    O mesmo vale para `max_connections`. Esse limite deve refletir a capacidade segura da instância e o desenho de pool de conexões do aplicativo. Se o banco recebe conexões demais, aumentar o teto pode apenas permitir que mais sessões disputem CPU, locks, buffer e I/O ao mesmo tempo. A medida correta pode estar no pooler, no limite de concorrência do aplicativo, na revisão de queries ou na separação de cargas.

    Variáveis que exigem decisão técnica

    Além do InnoDB Buffer Pool, algumas estruturas merecem avaliação direta:

    • `tmp_table_size` e `max_heap_table_size`: limitam o tamanho de tabelas temporárias em memória. Valores muito altos ampliam o risco por conexão; valores muito baixos podem aumentar temporários em disco.
    • `table_open_cache`: reduz custo de abertura de tabelas, mas exige descritores de arquivo e memória. Dimensione conforme o número de tabelas ativas e a concorrência.
    • `performance_schema`: é indispensável para investigação e observabilidade, mas consome memória. Desabilitar instrumentos sem critério pode reduzir visibilidade exatamente quando ocorre um incidente.
    • `innodb_log_buffer_size`: influencia operações de escrita e grandes transações. Crescer esse buffer pode ajudar em casos específicos, mas não substitui controle de transações longas.

    Há trade-offs legítimos. Uma plataforma com relatórios pesados pode aceitar mais temporários em disco para proteger a memória do banco transacional. Uma operação de pagamentos pode priorizar cache de índices e limitar agressivamente conexões analíticas. A configuração precisa refletir o SLA e a criticidade de cada carga.

    Meça antes de concluir que falta RAM

    Uso alto de memória não significa, por si só, problema. O Linux utiliza RAM ociosa como cache de página, e isso é desejável. O sinal de risco é a combinação de swap crescente, latência elevada, falhas de alocação, aumento de abortos de conexão, OOM Killer e degradação sustentada de consultas.

    No MySQL, acompanhe conexões ativas e máximas, criação de tabelas temporárias em disco, leituras físicas do InnoDB, pressão de locks, queries lentas e consumo por threads. No sistema operacional, observe memória disponível, page faults, swap in e swap out, carga de CPU, I/O wait e mensagens do kernel. Uma análise isolada de `free` ou de uma variável do arquivo de configuração não sustenta decisão de produção.

    Também não confunda sintoma com causa. Se o buffer pool tem baixa eficiência, talvez o dataset ativo seja maior que a RAM. Mas pode haver índices ausentes, consultas que varrem tabelas inteiras, cache de aplicativo ineficiente ou uma carga analítica concorrendo com transações críticas. Adicionar memória sem corrigir a origem pode reduzir o impacto por algumas semanas e ampliar o custo do problema depois.

    Um processo seguro de mudança

    A configuração deve passar por um ciclo controlado: estabelecer baseline, projetar o pior caso de memória, testar com concorrência próxima da realidade, alterar uma variável por vez quando possível e monitorar o efeito durante o período de maior carga. Em mudanças de maior impacto, valide também restart, tempo de recuperação, comportamento de replicação e capacidade de rollback.

    Esse processo é especialmente relevante em bancos com replicação, clusters e alta disponibilidade. Um ajuste que funciona no primário pode provocar pressão de memória em uma réplica menos dimensionada. Backups lógicos, jobs de manutenção e processos de recuperação também consomem recursos e precisam entrar no cálculo.

    A HTI Tecnologia trata memória como parte da engenharia operacional do banco, não como uma coleção de parâmetros. O objetivo não é fazer o MySQL usar mais RAM. É garantir que ele mantenha previsibilidade sob carga, preserve a capacidade de recuperação e não transforme um pico previsível em incidente.

    Se a sua instância só permanece estável em condições ideais, ela não está corretamente dimensionada. A configuração de memória precisa ser revisada antes do próximo pico de vendas, fechamento financeiro, campanha ou crescimento de base colocar essa fragilidade em produção.