backup mysql

Backup MySQL: Guia Completo para Proteger Seus Bancos de Dados

Tem uma pergunta que faço pra todo cliente que me chama depois de perder um banco de dados: “quando foi o último backup testado?” — não “quando foi o último backup gerado”, porque gerar backup e ter um backup que realmente restaura são coisas bem diferentes. Já vi rotina de backup rodando havia meses gerando arquivos de 0 byte porque uma credencial expirou silenciosamente, e ninguém percebeu até precisar restaurar de verdade. Este guia cobre tanto gerar o backup certo quanto garantir que ele funciona quando mais importa.

mysqldump: a base de qualquer backup MySQL confiável

O comando mais usado pra backup lógico de MySQL continua sendo o mysqldump, e a diferença entre um dump básico e um dump profissional está nas flags:

mysqldump -u root -p --single-transaction --routines --triggers --events --add-drop-table nome_do_banco > backup_$(date +%Y%m%d).sql

--single-transaction é essencial em banco de produção rodando ao vivo — garante uma cópia consistente sem travar as tabelas durante o processo (só funciona corretamente com tabelas InnoDB, não MyISAM). --add-drop-table evita erro de “tabela já existe” na hora de restaurar por cima de um banco existente.

Compactando e economizando espaço

mysqldump -u root -p --single-transaction nome_do_banco | gzip > backup_$(date +%Y%m%d).sql.gz

Compactar direto no pipe evita gerar o arquivo grande descompactado no disco antes de comprimir, o que economiza espaço temporário e tempo — detalhe que faz diferença real em bancos de dezenas de gigabytes.

Automatizando com cron

Backup manual só funciona até você esquecer um dia — e esse dia costuma ser exatamente o dia em que algo dá errado. Um cron básico rodando todo dia às 3h da manhã, horário de menor movimento:

0 3 * * * mysqldump -u backup_user -p'senha' --single-transaction nome_do_banco | gzip > /backups/mysql/backup_$(date +%Y%m%d).sql.gz

Evite usar o usuário root nesse cron. Crie um usuário específico só com permissão de leitura (SELECT, LOCK TABLES, SHOW VIEW) para a rotina de backup — se esse cron ou o servidor for comprometido, o dano fica limitado.

Rotação: não guarde backup pra sempre no mesmo disco

Um script simples de rotação, mantendo os últimos 7 dias e apagando o resto, evita que o disco de backup encha silenciosamente:

find /backups/mysql/ -name "*.sql.gz" -mtime +7 -delete

E o ponto mais importante de toda a rotina: pelo menos uma cópia precisa sair do mesmo servidor. Backup guardado na mesma máquina que ele protege não sobrevive a falha de disco, ataque de ransomware ou erro de administrador que apaga a pasta errada — segue a mesma lógica da regra 3-2-1 que já detalhei em outro guia por aqui.

Testando a restauração de verdade

Backup não testado é só uma esperança, não uma garantia. Pelo menos uma vez por mês, restaure o dump mais recente num banco de teste separado e confirme que os dados batem:

mysql -u root -p banco_teste_restauracao < backup_20260730.sql.gz

Se der erro nessa restauração de teste, é bem melhor descobrir agora do que no dia em que o banco de produção realmente cair.

Problemas comuns e como resolver

1. Dump gerado com tamanho zero ou minúsculo demais. Quase sempre é credencial expirada ou permissão revogada silenciosamente no meio do caminho. Adicione verificação de tamanho mínimo no próprio script do cron e configure alerta por e-mail se o arquivo sair fora do padrão esperado.

2. Backup demora cada vez mais e passa da janela disponível. Sinal de que o banco cresceu além do que o dump lógico aguenta com folga. Nesse ponto, vale considerar backup físico (Percona XtraBackup) em vez de lógico, que copia os arquivos de dados diretamente e é ordens de magnitude mais rápido em bancos grandes.

3. Erro de "Lock wait timeout" durante o dump. Geralmente é conflito com outra transação longa rodando ao mesmo tempo. Ajuste o horário do backup pra fora dos picos de uso ou revise se há alguma query mal otimizada segurando lock por tempo excessivo nesse horário.

Perguntas frequentes

Com que frequência devo fazer backup do MySQL? Depende de quanto dado você aceita perder no pior cenário. Para a maioria dos sites e sistemas pequenos, diário já é razoável; para e-commerce ou sistema transacional, considere backup incremental mais frequente, várias vezes ao dia.

Preciso parar o banco de dados para fazer backup? Não, com --single-transaction em tabelas InnoDB o backup roda com o banco ativo, sem downtime perceptível para os usuários.

Depois de gerar o backup, o processo inverso — restaurar via linha de comando — está detalhado neste outro guia, e se sua rotina de backup abrange mais do que só banco de dados, vale revisar também como configurar backups completos com rsync em servidores Linux.

Recuperação em um ponto exato no tempo com binary log

O dump diário resolve a maioria dos casos, mas tem um cenário que ele sozinho não cobre: alguém rodou um DELETE sem WHERE às 14h e o último backup é da meia-noite — você perde 14 horas de dados só com o dump. É aí que entra o binary log (binlog) do MySQL, que registra cada alteração feita no banco depois do backup. Com o binlog habilitado (log_bin ativo no my.cnf) e um dump base recente, dá para restaurar o dump e depois "replay" só das mudanças até o segundo exato antes do incidente, usando mysqlbinlog com os parâmetros --start-datetime e --stop-datetime. Configurar isso com antecedência é trabalho de alguns minutos; tentar montar isso correndo depois que já perdeu dados é bem mais estressante — então se seu banco guarda algo que realmente importa, vale ativar o binlog antes de precisar dele, não depois.

Posted in Backup.

Patrocinadores

suporte de ti                    marketing digital