Como automatizar backups de bancos de dados MySQL

1. Introdução aos backups automatizados no MySQL

Automatizar backups de bancos de dados MySQL é uma prática essencial para qualquer ambiente de produção. A perda de dados pode ocorrer por diversos motivos: falhas de hardware, erros humanos, ataques cibernéticos ou corrupção de dados. Um backup automatizado garante que você tenha cópias consistentes e recuperáveis sem depender de ações manuais que podem ser esquecidas ou executadas incorretamente.

Existem duas abordagens principais para backup no MySQL:

  • Backup lógico (mysqldump): Gera comandos SQL que recriam o banco de dados. É portátil entre versões e arquiteturas, mas pode ser lento para bases muito grandes.
  • Backup físico (cópia de arquivos): Copia diretamente os arquivos de dados do MySQL. É mais rápido para grandes volumes, mas exige que o banco esteja parado ou use ferramentas específicas como Percona XtraBackup.

A estratégia de backup deve incluir:
- Backup full: Cópia completa do banco, geralmente semanal.
- Backup incremental: Apenas alterações desde o último backup, usando binary logs.
- Backup diferencial: Alterações desde o último backup full.

A retenção deve ser definida com base na criticidade dos dados: backups diários podem ser mantidos por 7 dias, backups semanais por 30 dias e backups mensais por 6 meses.

2. Preparando o ambiente para automação

Antes de criar scripts, é necessário preparar o ambiente. Certifique-se de ter o cliente MySQL e o mysqldump instalados:

# Verificar instalação
mysql --version
mysqldump --version

# Instalar se necessário (Ubuntu/Debian)
sudo apt-get update
sudo apt-get install mysql-client

Crie um usuário dedicado no MySQL com permissões mínimas para realizar backups:

mysql -u root -p
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'senha_segura';
GRANT SELECT, LOCK TABLES, SHOW VIEW, TRIGGER, EVENT ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;

Defina diretórios de saída seguros:

sudo mkdir -p /var/backups/mysql
sudo chmod 750 /var/backups/mysql
sudo chown backup_user:backup_user /var/backups/mysql

3. Script básico de backup com mysqldump

Abaixo está um script bash completo para backup de um banco único com compressão e timestamp:

#!/bin/bash

# Configurações
DB_USER="backup_user"
DB_PASSWORD="senha_segura"
DB_NAME="meu_banco"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME}_${DATE}.sql.gz"

# Cria diretório se não existir
mkdir -p "$BACKUP_DIR"

# Executa o backup com mysqldump e comprime
mysqldump --user="$DB_USER" --password="$DB_PASSWORD" \
  --single-transaction --routines --triggers --events \
  "$DB_NAME" | gzip > "$BACKUP_FILE"

# Verifica se o backup foi bem-sucedido
if [ $? -eq 0 ]; then
    echo "Backup concluído: $BACKUP_FILE"
else
    echo "ERRO: Falha no backup do banco $DB_NAME" >&2
    exit 1
fi

# Remove backups mais antigos que 7 dias
find "$BACKUP_DIR" -name "${DB_NAME}_*.sql.gz" -mtime +7 -delete

Salve o script como backup_mysql.sh e torne-o executável:

chmod +x backup_mysql.sh

4. Automatizando com cron (Linux) ou Agendador de Tarefas (Windows)

No Linux, use o cron para executar o script automaticamente. Edite o crontab:

crontab -e

Adicione a linha para backup diário às 2h da manhã:

0 2 * * * /caminho/para/backup_mysql.sh >> /var/log/mysql_backup.log 2>&1

Para logs e notificações, modifique o script para enviar e-mail em caso de falha:

# No script, após o comando mysqldump
if [ $? -ne 0 ]; then
    echo "Falha no backup de $DB_NAME" | mail -s "ALERTA: Backup MySQL" admin@exemplo.com
fi

No Windows, use o Agendador de Tarefas para executar um script PowerShell equivalente.

5. Estratégias avançadas de backup

Para backup de múltiplos bancos, use um loop no script:

#!/bin/bash
DB_LIST=("banco1" "banco2" "banco3")

for DB in "${DB_LIST[@]}"; do
    mysqldump --user="$DB_USER" --password="$DB_PASSWORD" \
      --single-transaction "$DB" | gzip > "${BACKUP_DIR}/${DB}_${DATE}.sql.gz"
done

Para backup incremental com binary logs, habilite os binlogs no MySQL:

# Adicione no my.cnf
[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
expire_logs_days=7

Faça backup dos binlogs periodicamente:

mysqlbinlog --read-from-remote-server --host=localhost \
  --user=backup_user --password=senha_segura \
  mysql-bin.000001 > /var/backups/binlog_001.sql

Para backups físicos quentes, use Percona XtraBackup:

# Instalação
sudo apt-get install percona-xtrabackup-80

# Backup full
xtrabackup --backup --target-dir=/var/backups/xtra/full

# Preparar para restauração
xtrabackup --prepare --target-dir=/var/backups/xtra/full

6. Restauração e validação dos backups

Para restaurar um backup lógico:

# Restaurar banco completo
gunzip < /var/backups/mysql/meu_banco_20250101_020000.sql.gz | mysql -u root -p

# Restaurar banco específico
mysql -u root -p meu_banco < /caminho/para/dump.sql

Valide a integridade dos backups criando um script de teste:

#!/bin/bash
# Script de validação: restaura em banco de teste e verifica
TEST_DB="test_restore_$(date +%s)"

mysql -u root -p <<EOF
CREATE DATABASE $TEST_DB;
EOF

gunzip < /var/backups/mysql/meu_banco_latest.sql.gz | mysql -u root -p $TEST_DB

# Verifica se há tabelas
TABLES=$(mysql -u root -p -N -e "USE $TEST_DB; SHOW TABLES;" 2>/dev/null)
if [ -z "$TABLES" ]; then
    echo "ERRO: Backup corrompido ou vazio"
    mysql -u root -p -e "DROP DATABASE $TEST_DB;"
    exit 1
else
    echo "Backup válido: $TABLES"
    mysql -u root -p -e "DROP DATABASE $TEST_DB;"
fi

7. Monitoramento e boas práticas

Monitore o espaço em disco e implemente rotação automática:

# No script de backup
DISK_USAGE=$(df /var/backups | tail -1 | awk '{print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 80 ]; then
    echo "ALERTA: Disco com $DISK_USAGE% de uso" | mail -s "Espaço crítico" admin@exemplo.com
fi

Use variáveis de ambiente para evitar expor senhas:

# Crie um arquivo .env
DB_PASSWORD="senha_segura"
BACKUP_DIR="/var/backups/mysql"

# No script, carregue o arquivo
source /caminho/.env

Documente todo o processo em um plano de recuperação de desastres (DRP), incluindo:
- Localização dos backups
- Procedimentos de restauração
- Contatos de emergência
- SLAs de recuperação (RTO e RPO)

Referências