Como configurar backup automático no MySQL com cron

1. Introdução ao backup de MySQL com cron

A perda de dados em um banco MySQL pode ocorrer por diversos motivos: falhas de hardware, erros humanos, ataques cibernéticos ou corrupção de arquivos. Para administradores de servidores, automatizar backups regulares não é uma opção — é uma necessidade operacional. O cron, agendador de tarefas nativo do Linux, oferece uma solução leve e confiável para executar scripts de backup em intervalos predefinidos, sem intervenção manual.

Este guia apresenta um passo a passo prático para configurar backup automático no MySQL utilizando cron, cobrindo desde a preparação do ambiente até a implementação de notificações de falha. Os pré-requisitos incluem: acesso ao MySQL com privilégios de leitura (SELECT, LOCK TABLES), um usuário com permissão para editar o crontab e o cron instalado (presente por padrão na maioria das distribuições Linux).

2. Preparando o ambiente para backups

O primeiro passo é criar um diretório dedicado para armazenar os backups. Recomenda-se utilizar /var/backups/mysql por questões de organização e segurança:

sudo mkdir -p /var/backups/mysql

Em seguida, ajuste as permissões para que apenas o usuário que executará o script tenha acesso de leitura e escrita:

sudo chown -R $USER:$USER /var/backups/mysql
sudo chmod 700 /var/backups/mysql

Verifique se as ferramentas essenciais estão instaladas. O mysqldump e o mysql fazem parte do pacote mysql-client, e o gzip é utilizado para compactação:

which mysqldump mysql gzip

Caso algum comando não seja encontrado, instale o pacote necessário. No Ubuntu/Debian:

sudo apt install mysql-client gzip

3. Criando um script de backup manual

Crie um arquivo de script shell, por exemplo backup_mysql.sh, no diretório /usr/local/bin:

#!/bin/bash

# Variáveis de configuração
DB_USER="seu_usuario"
DB_PASSWORD="sua_senha"
DB_NAME="nome_do_banco"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz"

# Executa o mysqldump e compacta
mysqldump -u $DB_USER -p$DB_PASSWORD $DB_NAME | gzip > $BACKUP_FILE

# Verifica se o backup foi bem-sucedido
if [ $? -eq 0 ]; then
    echo "Backup realizado com sucesso: $BACKUP_FILE"
else
    echo "Erro ao realizar backup do banco $DB_NAME"
    exit 1
fi

Torne o script executável:

chmod +x /usr/local/bin/backup_mysql.sh

Teste manualmente o script para verificar se o backup é gerado corretamente:

/usr/local/bin/backup_mysql.sh

Confira o diretório de backups:

ls -lh /var/backups/mysql/

4. Configurando o cron para execução automática

Para agendar a execução automática do script, edite o crontab do usuário atual:

crontab -e

Adicione a seguinte linha para executar o backup diariamente à meia-noite:

0 0 * * * /usr/local/bin/backup_mysql.sh >> /var/log/mysql_backup.log 2>&1

A sintaxe do cron segue o padrão: minuto, hora, dia do mês, mês, dia da semana. O redirecionamento >> /var/log/mysql_backup.log 2>&1 salva tanto a saída padrão quanto os erros em um arquivo de log.

Para testar a tarefa sem esperar o horário agendado, execute o script manualmente e verifique o log:

tail -f /var/log/mysql_backup.log

Se o log não for criado, verifique as permissões do diretório /var/log ou redirecione para um arquivo no diretório home.

5. Gerenciando retenção de backups antigos

Sem uma política de retenção, o diretório de backups pode crescer indefinidamente e consumir todo o espaço em disco. Adicione ao script a lógica de limpeza utilizando o comando find com a opção -mtime:

# Remove backups com mais de 7 dias
find $BACKUP_DIR -type f -name "*.sql.gz" -mtime +7 -delete

O script completo com rotação fica:

#!/bin/bash

DB_USER="seu_usuario"
DB_PASSWORD="sua_senha"
DB_NAME="nome_do_banco"
BACKUP_DIR="/var/backups/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="$BACKUP_DIR/${DB_NAME}_$DATE.sql.gz"
RETENTION_DAYS=7

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

# Executa o backup
mysqldump -u $DB_USER -p$DB_PASSWORD $DB_NAME | gzip > $BACKUP_FILE

if [ $? -eq 0 ]; then
    echo "Backup realizado: $BACKUP_FILE"
    # Remove backups antigos
    find $BACKUP_DIR -type f -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
    echo "Backups com mais de $RETENTION_DAYS dias removidos."
else
    echo "Erro no backup do banco $DB_NAME"
    exit 1
fi

6. Monitoramento e notificações de falhas

Para ser notificado em caso de falha, é possível configurar o envio de e-mail diretamente no script. Primeiro, instale o pacote mailutils (no Ubuntu/Debian):

sudo apt install mailutils

Modifique o script para incluir notificação em caso de erro:

ADMIN_EMAIL="admin@exemplo.com"

if [ $? -eq 0 ]; then
    echo "Backup realizado: $BACKUP_FILE"
    find $BACKUP_DIR -type f -name "*.sql.gz" -mtime +$RETENTION_DAYS -delete
else
    echo "Erro no backup do banco $DB_NAME" | mail -s "Falha no backup MySQL" $ADMIN_EMAIL
    exit 1
fi

Verifique também os logs do cron para depuração:

grep backup_mysql /var/log/syslog

Em sistemas com systemd, utilize:

journalctl -u cron | grep backup_mysql

7. Boas práticas e segurança

Nunca exponha senhas diretamente no script. Crie um arquivo de configuração .my.cnf no diretório home do usuário que executará o cron:

[client]
user=seu_usuario
password=sua_senha
host=localhost

Proteja o arquivo com permissões restritas:

chmod 600 ~/.my.cnf

Modifique o script para utilizar o arquivo de configuração:

mysqldump --defaults-extra-file=~/.my.cnf $DB_NAME | gzip > $BACKUP_FILE

Outras recomendações importantes:
- Restrinja o acesso ao diretório de backups apenas ao usuário do cron (chmod 700)
- Para ambientes críticos, considere backups incrementais com ferramentas como mysqlbinlog ou replicação com MySQL Replication
- Teste periodicamente a restauração dos backups para garantir a integridade dos dados

Com essa configuração, você terá um sistema automatizado de backups do MySQL que roda diariamente, mantém apenas os arquivos dos últimos 7 dias e notifica o administrador em caso de falha. Ajuste os parâmetros de horário e retenção conforme a necessidade do seu ambiente.

Referências