← Voltar ao blog
MySQL 20 de março de 2026 5 min de leitura

MySQL Todo Dia: backup incremental diário com mysqlpump e S3

Script pronto para rodar backup full semanal e incrementais diários de MySQL 8 usando mysqlpump, binlogs e storage S3-compatível.

MySQL Todo Dia: backup incremental diário com mysqlpump e S3

Introdução

Não rodar backup todo dia é corda no pescoço. Em ambiente MySQL 8 você não precisa esperar janela de manutenção infinita: dá para combinar mysqlpump, binlogs e um storage S3-compatível para ter backups incrementais comprimidos e versionados. Claro que existe o xtrabackup, mas, hoje vamos abordar algo 100% nativo, simples, fácil, barato e bonitinho.

Pré-requisitos

  • MySQL 8.0 com GTID e binlogs habilitados.

  • Bucket em storage compatível com S3 (MinIO, Wasabi, AWS S3).

  • Ferramentas instaladas: mysqlpump, awscli ou equivalente.

Backup full semanal

Rode um full toda semana para resetar a cadeia incremental:

#!/bin/bash
set -euo pipefail
DATE=$(date +%Y%m%d-%H%M)
FULL=/backups/mysql/full-$DATE.sql.gz
mysqlpump --exclude-databases=sys,performance_schema           --users --events --routines           --single-transaction           | gzip > "${FULL}"
aws s3 cp "${FULL}" s3://mysql-backups/full/

Incremental diário com binlogs

Use mysqlbinlog para extrair apenas o delta desde o último corte:

#!/bin/bash
set -euo pipefail
LAST_FILE=$(aws s3 ls s3://mysql-backups/incremental/ | tail -n1 | awk '{print $4}')
START_POS=${LAST_FILE##*-}
START_FILE=${LAST_FILE%%-*}
DATE=$(date +%Y%m%d-%H%M)
INC=/backups/mysql/inc-$DATE
mysqlbinlog --raw --read-from-remote-server   --host=127.0.0.1 --user=backup --password=...   --start-position=${START_POS} --start-datetime="$(date '+%F %T' -d '-1 day')"   --stop-never   ${START_FILE} > "${INC}.bin"
gzip "${INC}.bin"
aws s3 cp "${INC}.bin.gz" s3://mysql-backups/incremental/

Automação com cron e retenção

Agende o incremental (domingo a sábado) e o full (domingo) no cron:

0 2 * * 0 /usr/local/bin/mysql-full-backup.sh
0 2 * * 1-6 /usr/local/bin/mysql-inc-backup.sh

Configure políticas de lifecycle no bucket para manter 30 dias de incrementais e 12 semanas de full.

Restore rápido

  1. Baixe o último full e os incrementais posteriores.

  2. Restaure o full: gunzip -c full.sql.gz | mysql.

  3. Aplique os binlogs em ordem: for f in inc-*.bin.gz; do gunzip -c $f | mysqlbinlog - | mysql; done.

Fechamento

Não tem glamour: backup só é bom quando restaura. Combinando mysqlpump, binlogs e S3 você ganha RPO diário sem derrubar aplicação. Ajuste o ciclo conforme o volume e teste o restore todo mês.