Backup MySQL com mysqldump e Restaurar Banco de Dados no Linux

Aprenda a fazer backup MySQL com mysqldump e restaurar banco de dados no Linux com comandos prontos, consistência transacional e validação.

Perder um banco MySQL por dropar tabela errada, corromper arquivo de dados ou subir migration ruim acontece com qualquer time. A diferença entre incidente curto e dia inteiro de pânico é ter backup recente, validado e restaurável. Este tutorial cobre o fluxo completo de backup com mysqldump e restore subsequente, incluindo os flags que realmente importam em produção.

O foco aqui é prático: comandos prontos pra copiar, parâmetros explicados no contexto e validação do arquivo gerado antes que você precise dele de verdade. A persona é developer que conhece MySQL básico (SELECT/INSERT) mas nunca configurou rotina de backup própria — provavelmente migrando de hospedagem compartilhada pra uma VPS própria onde a responsabilidade agora é sua.

Tempo estimado: 15-20 minutos pra executar o tutorial completo num banco de exemplo. Em produção real, o dump em si demora proporcional ao tamanho do banco (~1 GB/min em SSD NVMe típico).

Pré-requisitos

O que você precisa ter

Ubuntu 22.04 LTS ou 24.04 LTS (Debian também serve) com MySQL 8.0 ou MariaDB 10.6+ instalado e rodando. Acesso sudo no servidor e credenciais do usuário root do MySQL ou de um usuário com privilégios SELECT, LOCK TABLES, SHOW VIEW e EVENT no banco que vai ser dumpado. Espaço livre em disco no mínimo igual ao tamanho do banco (verifique com df -h).

Pra confirmar que o mysqldump está disponível, rode:

mysqldump --version

A saída deve mostrar algo como mysqldump Ver 8.0.x for Linux on x86_64. Se o comando não for encontrado, instale o pacote client:

sudo apt update
sudo apt install -y mysql-client

Pra MariaDB, o binário equivalente é o próprio mariadb-dump (alias de mysqldump em distribuições recentes).

Backup do banco com mysqldump

O mysqldump lê o estado atual do MySQL e gera um arquivo SQL com todos os comandos necessários pra recriar o banco do zero — CREATE DATABASE, CREATE TABLE, INSERT de cada linha, triggers, views e procedures. É um formato portátil e versionável (você pode até commitar no Git, embora não seja o uso primário).

01

Faça o dump simples de um banco específico:

mysqldump -u root -p meubanco > meubanco-2026-05-29.sql

O -u root define o usuário, -p pede a senha interativamente (mais seguro que passar -psenha na linha de comando, que vaza no histórico do shell e em ps aux). O redirecionamento > salva a saída no arquivo nomeado.

Inclua a data no nome do arquivo desde o começo — ajuda na rotação e evita sobrescrita acidental.

02

Adicione os flags de consistência transacional pra produção:

mysqldump -u root -p \
  --single-transaction \
  --routines \
  --triggers \
  --events \
  --quick \
  meubanco > meubanco-2026-05-29.sql

O --single-transaction envolve o dump em START TRANSACTION com isolation REPEATABLE READ, gerando um snapshot consistente sem bloquear escritas em tabelas InnoDB. Esse é o flag crítico em produção: sem ele, escritas paralelas podem deixar o dump inconsistente.

Os flags --routines, --triggers e --events incluem stored procedures, triggers e eventos agendados — coisas que são fáceis de esquecer e que você só percebe que faltam quando restaura e o sistema quebra. --quick faz o dump linha-por-linha em vez de carregar tabelas inteiras em RAM, importante pra tabelas grandes.

03

Comprima na hora pra economizar espaço:

mysqldump -u root -p \
  --single-transaction --routines --triggers --events --quick \
  meubanco | gzip > meubanco-2026-05-29.sql.gz

O pipe pra gzip reduz o arquivo em 70-85% pra dumps típicos (texto SQL comprime muito bem). Pra bancos de 10 GB, isso é diferença entre 2 GB e 10 GB ocupando seu disco de backup.

Pra compressão melhor (mais lenta), troque gzip por zstd -19 ou xz -9.

04

Faça backup de todos os bancos de uma vez (útil pra snapshot diário do servidor inteiro):

mysqldump -u root -p \
  --all-databases \
  --single-transaction \
  --routines --triggers --events \
  --master-data=2 \
  | gzip > full-2026-05-29.sql.gz

O --all-databases inclui também os bancos do sistema (mysql, sys, performance_schema) — preserva usuários e grants. O --master-data=2 grava a posição do binlog no dump como comentário, útil pra point-in-time recovery se você tiver binlogs habilitados.

Senha em arquivo de configuração

Pra evitar digitar senha em scripts automatizados, crie ~/.my.cnf com [client] + user=root + password=senha e permissão 600 (chmod 600 ~/.my.cnf). O mysqldump lê automaticamente — você roda mysqldump meubanco > arquivo.sql sem -u nem -p. Nunca coloque senha em script versionado.

Validação do arquivo de backup

Backup que você nunca testou restaurar é boato, não backup. Antes de confiar no arquivo, valide três coisas: integridade do arquivo, sintaxe SQL e que o dump cobre o que você espera.

05

Verifique se o arquivo não foi truncado:

ls -lh meubanco-2026-05-29.sql.gz
gzip -t meubanco-2026-05-29.sql.gz && echo "OK: arquivo íntegro"

O gzip -t testa a integridade da compressão sem descomprimir. Se falhar, o arquivo está corrompido (geralmente disco cheio durante o dump ou crash no meio). Re-rode o dump.

06

Confira o conteúdo do dump:

zcat meubanco-2026-05-29.sql.gz | head -30
zcat meubanco-2026-05-29.sql.gz | grep -c "^INSERT INTO"
zcat meubanco-2026-05-29.sql.gz | grep "^CREATE TABLE" | wc -l

O head mostra o cabeçalho com versão do mysqldump e configurações. O grep -c INSERT conta linhas de insert (sanity check de volume de dados). O grep CREATE TABLE | wc -l conta tabelas — bate com o que você espera ter no banco?

Pra comparar com o servidor original:

mysql -u root -p -e "SELECT COUNT(*) AS tabelas FROM information_schema.tables WHERE table_schema='meubanco';"

Os números devem coincidir.

Restaurar banco de dados a partir do dump

Restore é o caminho inverso: ler o arquivo SQL e enviar pro servidor MySQL que executa cada comando em sequência. Isso pode ser num servidor novo, no mesmo servidor após drop acidental, ou pra clonar dados de produção pra ambiente de staging.

07

Crie o banco vazio de destino (só se ainda não existir):

mysql -u root -p -e "CREATE DATABASE meubanco CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"

Use utf8mb4 sempre — suporta emoji e caracteres asiáticos completos. Pular esse passo é OK se o dump foi feito com --databases (que inclui o CREATE DATABASE no arquivo) ou --all-databases.

08

Restaure o dump comprimido direto via pipe:

zcat meubanco-2026-05-29.sql.gz | mysql -u root -p meubanco

O zcat descomprime na memória e envia pro mysql client, que executa cada comando contra o banco meubanco. Pra arquivo .sql não comprimido, use redirecionamento:

mysql -u root -p meubanco < meubanco-2026-05-29.sql

A operação demora proporcional ao tamanho (cada INSERT roda individualmente por padrão). Pra dumps grandes, deixe rodando em tmux ou screen pra não interromper se a sessão SSH cair.

09

Acompanhe o progresso em dumps grandes:

pv meubanco-2026-05-29.sql.gz | zcat | mysql -u root -p meubanco

O pv (pipe viewer) mostra barra de progresso e velocidade. Instale com sudo apt install -y pv. Sem ele, o restore roda silencioso — você não sabe se está em 10% ou 90%.

Restore num banco existente sobrescreve dados

Se o banco já tem tabelas, o dump (que contém DROP TABLE IF EXISTS) vai apagar as versões atuais e recriar. Em produção, faça o restore num banco com nome diferente primeiro (meubanco_restore) e valide antes de promover via RENAME.

Verificação pós-restore

Restore que não foi verificado é meio restore. Cheque três coisas: as tabelas voltaram, a contagem de linhas bate e a aplicação consegue abrir conexão.

10

Confirme estrutura e contagens:

mysql -u root -p meubanco -e "SHOW TABLES;"
mysql -u root -p meubanco -e "SELECT COUNT(*) FROM usuarios;"

A primeira lista as tabelas; a segunda conta linhas numa tabela que você sabe quantas linhas tinha antes. Discrepâncias indicam dump incompleto (faltou flag) ou restore interrompido.

Flag crítico InnoDB --single-transaction
Inclui procedures --routines
Inclui triggers --triggers
Dump streaming --quick
Posição binlog --master-data=2

Resolução de problemas

Erro “Access denied” durante o dump

O usuário não tem privilégio em alguma tabela. Verifique grants com SHOW GRANTS FOR 'usuario'@'localhost';. Pra dump completo, o usuário precisa de SELECT, LOCK TABLES, SHOW VIEW, EVENT e TRIGGER. A solução mais simples é rodar como root.

Restore falha com “Unknown collation utf8mb4_0900_ai_ci”

O dump foi feito em MySQL 8.0+ e você está restaurando em 5.7 ou MariaDB antigo. Edite o arquivo (sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' arquivo.sql) ou regere o dump com --compatible=mysql57.

”MySQL server has gone away” no meio do restore

max_allowed_packet muito pequeno no servidor de destino. Aumente em /etc/mysql/mysql.conf.d/mysqld.cnf com max_allowed_packet = 256M, reinicie o MySQL e tente de novo.

Próximos passos

Backup manual é o começo — automatize com cron e copie pra storage externa (rclone pra B2/S3 funciona bem). Considere também replicação master-slave pra ter cópia quente disponível em segundos, e habilite binary logs pra point-in-time recovery dentro do dia.

Se você está rodando MySQL em produção, uma VPS Hostini já vem com SSD NVMe e snapshots de disco como camada adicional de proteção sobre o backup lógico do mysqldump — recovery rápido pra desastres de infraestrutura, sem substituir o dump SQL que é portátil entre servidores.

Perguntas frequentes

Qual a diferença entre mysqldump e snapshot do disco?

mysqldump gera um arquivo SQL portátil (texto com CREATE TABLE e INSERTs), restaurável em qualquer servidor MySQL compatível, inclusive em versão diferente. Snapshot de disco é uma cópia binária — mais rápida em bancos grandes, mas só restaura no mesmo motor/versão e exige cuidado com transações em voo. Pra bancos abaixo de 50 GB, mysqldump é o padrão.

mysqldump trava as tabelas durante o backup?

Por padrão sim, com FLUSH TABLES WITH READ LOCK em MyISAM. Em InnoDB, use --single-transaction pra fazer o dump dentro de uma transação consistente sem bloquear escritas. Esse é o flag mais importante pra bancos em produção.

Posso restaurar o dump em uma versão diferente do MySQL?

Sim, desde que vá da versão mais antiga pra mais nova (5.7 → 8.0, por exemplo). O reverso pode falhar por sintaxe nova não suportada. Pra cross-version downgrade, gere o dump com --compatible=mysql57 no servidor mais novo.

Como faço backup só de algumas tabelas?

Passe os nomes das tabelas após o nome do banco: mysqldump -u root -p meubanco usuarios pedidos > parcial.sql. Isso dumpa só usuarios e pedidos do banco meubanco. Útil pra migrar dados específicos sem mover o banco inteiro.

O arquivo .sql ficou enorme — como reduzir?

Comprima com gzip no pipe: mysqldump ... | gzip > backup.sql.gz. A compressão tipicamente reduz 70-85% do tamanho. Pra restaurar, use zcat backup.sql.gz | mysql -u root -p meubanco. Evita ocupar espaço temporário em disco durante a operação.

Como agendar o backup pra rodar todo dia automaticamente?

Use cron: crie /etc/cron.daily/mysql-backup com o script de dump e rotação. Grave a senha em ~/.my.cnf com permissão 600 pra não passar em linha de comando. Combine com rsync ou rclone pra copiar pra storage externa logo após o dump.

Tópicos:
Próximos passos Cloud Ryzen com NVMe e proteção DDoS sempre ativa.Coloque em produção numa VPS Hostini →
Esse tutorial foi útil?
Falar no WhatsApp