Importar e Exportar Bancos de Dados MySQL Usando a Linha de Comando
Dominar as operações de importação e exportação de bases de dados MySQL a partir da linha de comandos é uma competência indispensável para qualquer administrador de bases de dados ou engenheiro de backend. O utilitário `mysqldump` exporta uma base de dados para um ficheiro `.sql` portátil contendo todas as instruções DDL e DML necessárias para reconstruir completamente o esquema e os dados, enquanto o cliente de linha de comandos `mysql` trata do processo inverso — transmitindo esse ficheiro de volta para uma instância MySQL em execução.
Este guia abrange todos os cenários práticos: exportações de base de dados única, dumps de múltiplas bases de dados, backups apenas de estrutura, transferências comprimidas, gestão de conjuntos de caracteres e fluxos de trabalho de importação seguros — incluindo casos extremos que causam corrupção silenciosa de dados ou falhas de restauro em ambientes de produção.
Pré-requisitos
Antes de executar qualquer comando neste guia, verifique o seguinte:
- O MySQL Server (5.7, 8.0 ou 8.4) está instalado e o processo `mysqld` está em execução
- Os binários `mysqldump` e `mysql` estão no `PATH` do seu sistema (confirme com `which mysqldump`)
- Possui uma conta MySQL com, no mínimo, privilégios `SELECT`, `LOCK TABLES`, `SHOW VIEW` e `TRIGGER` para exportação; `CREATE`, `INSERT`, `ALTER` e `DROP` para importação
- Existe espaço em disco suficiente no destino — um dump comprimido pode expandir 5–10x na importação
- Tem acesso shell ao servidor (terminal local, SSH ou um ambiente de VPS Hosting gerido)
Exportar Bases de Dados com mysqldump
`mysqldump` é a ferramenta de backup lógico canónica incluída no MySQL. Serializa objetos de base de dados num script SQL legível por humanos. Ao contrário de ferramentas de backup físico como o Percona XtraBackup, `mysqldump` é agnóstico em relação ao motor de armazenamento e funciona em diferentes versões do MySQL e até em forks do MariaDB.
1. Exportar uma Única Base de Dados
“`bash
mysqldump -u [username] -p [database_name] > [filename].sql
“`
Descrição dos parâmetros:
- `-u [username]` — Conta MySQL utilizada para a ligação
- `-p` — Aciona um pedido de palavra-passe interativo (nunca passe a palavra-passe inline como `-p[password]` em sistemas partilhados; é visível na saída de `ps aux`)
- `[database_name]` — Esquema de destino a exportar
- `> [filename].sql` — Redireciona o stdout para o ficheiro de saída
Exemplo:
“`bash
mysqldump -u root -p mydatabase > mydatabase_backup.sql
“`
Isto produz um ficheiro contendo instruções `CREATE TABLE`, `INSERT` e `ALTER TABLE` suficientes para recriar `mydatabase` de raiz.
Caso extremo crítico: Por predefinição, `mysqldump` adquire um bloqueio de leitura global (`FLUSH TABLES WITH READ LOCK`) no início do dump. Em servidores InnoDB com tráfego elevado, utilize `–single-transaction` em alternativa para obter um snapshot consistente sem bloquear escritas:
“`bash
mysqldump -u root -p –single-transaction mydatabase > mydatabase_backup.sql
“`
`–single-transaction` só funciona de forma fiável com tabelas InnoDB. Se a sua base de dados contiver tabelas MyISAM, o bloqueio é inevitável.
2. Exportar Múltiplas Bases de Dados
“`bash
mysqldump -u [username] -p –databases db1 db2 > multiple_databases_backup.sql
“`
O sinalizador `–databases` instrui o `mysqldump` a incluir instruções `CREATE DATABASE` e `USE` na saída, tornando o dump autossuficiente. Sem este sinalizador, essas instruções são omitidas e o dump assume que uma base de dados de destino já está selecionada no momento da importação.
Exemplo:
“`bash
mysqldump -u root -p –databases db1 db2 > multiple_databases_backup.sql
“`
3. Exportar Todas as Bases de Dados
“`bash
mysqldump -u root -p –all-databases > all_databases_backup.sql
“`
Isto exporta todos os esquemas a que o utilizador de ligação pode aceder, incluindo as bases de dados de sistema `mysql`, `information_schema` e `performance_schema`. Evite importar bases de dados de sistema entre versões principais do MySQL — o esquema da tabela de privilégios mudou significativamente entre o MySQL 5.7 e o 8.0, e importar o esquema antigo `mysql` para uma instância 8.0 nova irá corromper a autenticação.
Para excluir esquemas de sistema:
“`bash
mysqldump -u root -p –all-databases
–ignore-table=mysql.user
–ignore-table=mysql.db
> all_user_databases_backup.sql
“`
4. Exportar Apenas a Estrutura da Tabela (Sem Dados)
“`bash
mysqldump -u root -p –no-data mydatabase > structure_only.sql
“`
Isto é inestimável para controlo de versões de esquemas, revisões de código ou criação de um ambiente de staging em branco. A saída contém apenas DDL como `CREATE TABLE`, `CREATE VIEW`, `CREATE PROCEDURE` e similares — sem linhas `INSERT`.
5. Exportar Tabelas Específicas
“`bash
mysqldump -u root -p mydatabase table1 table2 > tables_backup.sql
“`
Note que ao exportar tabelas específicas desta forma, `mysqldump` não inclui instruções `CREATE DATABASE` ou `USE`. Deve garantir que a base de dados de destino existe antes de importar.
6. Exportar com Procedimentos Armazenados, Triggers e Eventos
Por predefinição, `mysqldump` inclui triggers mas omite procedimentos armazenados, funções e eventos agendados. Para um backup completo da aplicação:
“`bash
mysqldump -u root -p
–routines
–triggers
–events
–single-transaction
mydatabase > full_backup.sql
“`
Esquecer `–routines` é uma das causas mais comuns de restauros de aplicações com falhas — o esquema e os dados estão presentes, mas a lógica de negócio está em falta.
7. Exportação Comprimida
Encaminhe a saída diretamente através de `gzip` para reduzir o tamanho do ficheiro em 60–80%:
“`bash
mysqldump -u root -p mydatabase | gzip > mydatabase_backup.sql.gz
“`
Para compressão máxima em bases de dados grandes (ao custo de tempo de CPU):
“`bash
mysqldump -u root -p mydatabase | gzip -9 > mydatabase_backup.sql.gz
“`
Importar Bases de Dados com o Cliente mysql
O cliente de linha de comandos `mysql` aceita um ficheiro SQL via redirecionamento de stdin e executa cada instrução sequencialmente no servidor de destino.
1. Importar para uma Base de Dados Existente
“`bash
mysql -u [username] -p [database_name] < [filename].sql
“`
Exemplo:
“`bash
mysql -u root -p mydatabase < mydatabase_backup.sql
“`
Importante: Se o ficheiro `.sql` foi exportado com `–databases` ou `–all-databases`, já contém diretivas `CREATE DATABASE` e `USE`. Nesse caso, não especifique um nome de base de dados na linha de comandos — fazê-lo cria um conflito:
“`bash
mysql -u root -p < all_databases_backup.sql
“`
2. Importar para uma Nova Base de Dados
A base de dados de destino deve existir antes de poder importar para ela. O MySQL não a criará automaticamente a partir de um dump de tabela simples.
Passo 1 — Criar a base de dados:
“`bash
mysql -u root -p -e "CREATE DATABASE newdatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
“`
Passo 2 — Importar o dump:
“`bash
mysql -u root -p newdatabase < mydatabase_backup.sql
“`
Especifique sempre o conjunto de caracteres e a collation explicitamente no momento da criação da base de dados. Depender das predefinições do servidor é uma fonte frequente de incompatibilidades de codificação, especialmente ao migrar entre servidores com configurações `character_set_server` diferentes.
3. Importar um Dump Comprimido
“`bash
gunzip < mydatabase_backup.sql.gz | mysql -u root -p mydatabase
“`
Ou utilizando `zcat` (equivalente na maioria das distribuições Linux):
“`bash
zcat mydatabase_backup.sql.gz | mysql -u root -p mydatabase
“`
4. Importar com Monitorização de Progresso
Para dumps grandes, o cliente `mysql` padrão não fornece qualquer feedback. Utilize `pv` (pipe viewer) para exibir uma barra de progresso em tempo real:
“`bash
pv mydatabase_backup.sql | mysql -u root -p mydatabase
“`
Instale `pv` com `apt install pv` ou `yum install pv`. Num Servidor Dedicado que gere bases de dados de produção com vários gigabytes, esta visibilidade é operacionalmente crítica.
mysqldump vs. Métodos Alternativos de Backup
| Funcionalidade | mysqldump | mysqlpump | MySQL Shell (util.dumpInstance) | Percona XtraBackup |
|---|
| — | — | — | — | — |
|---|
| Tipo de backup | Lógico (SQL) | Lógico (SQL) | Lógico (JSON/SQL) | Físico (binário) |
|---|
| Paralelismo | Thread único | Multi-thread | Multi-thread | Multi-thread |
|---|
| Backup a quente InnoDB | Com `–single-transaction` | Com `–single-transaction` | Sim | Sim |
|---|
| Formato de saída | SQL simples | SQL simples | Ficheiros fragmentados | Ficheiros InnoDB brutos |
|---|
| Velocidade de restauro | Lenta (SQL sequencial) | Moderada | Rápida | Muito rápida |
|---|
| Portabilidade entre versões | Excelente | Boa | Boa | Apenas a mesma versão principal |
|---|
| Incluído no MySQL | Sim | Sim (5.7.8+) | Instalação separada | Terceiros |
|---|
| Melhor caso de utilização | Portabilidade, BDs pequenas-médias | Dumps paralelos | Esquemas cloud/grandes | BDs de produção grandes |
|---|
Para ambientes que executam múltiplas bases de dados de produção num VPS com cPanel gerido, `mysqldump` continua a ser a opção com suporte mais universal devido à sua compatibilidade e simplicidade.
Configuração Avançada e Casos Extremos
Gerir Conjuntos de Caracteres Corretamente
As incompatibilidades de conjuntos de caracteres são responsáveis por uma proporção desproporcionada de importações corrompidas. A abordagem mais segura é ser explícito em cada etapa:
“`bash
mysqldump -u root -p
–default-character-set=utf8mb4
mydatabase > mydatabase_backup.sql
“`
“`bash
mysql -u root -p
–default-character-set=utf8mb4
mydatabase < mydatabase_backup.sql
“`
Nota: `utf8` no MySQL é um subconjunto de 3 bytes que não consegue armazenar caracteres Unicode de 4 bytes (emojis, certos ideogramas CJK). Utilize sempre `utf8mb4` para novas bases de dados.
Acelerar Importações Grandes
Por predefinição, o MySQL realiza um commit completo após cada instrução `INSERT` no dump. Para conjuntos de dados grandes, isto é catastroficamente lento. Adicione o seguinte ao início da sua sessão de importação:
“`bash
mysql -u root -p mydatabase <<EOF
SET foreign_key_checks = 0;
SET unique_checks = 0;
SET autocommit = 0;
SOURCE /path/to/mydatabase_backup.sql;
COMMIT;
SET foreign_key_checks = 1;
SET unique_checks = 1;
EOF
“`
Em alternativa, exporte com `–extended-insert` (ativado por predefinição) e `–disable-keys` para agrupar inserções e adiar a reconstrução de índices até após o carregamento dos dados.
Automatizar Backups com Cron
Uma entrada de backup automatizado de nível de produção em `/etc/cron.d/mysql-backup`:
“`bash
0 2 * * * root mysqldump -u backup_user -p'StrongPass'
–single-transaction –routines –triggers –events
mydatabase | gzip > /backups/mydatabase_$(date +%F).sql.gz
“`
Utilize um utilizador MySQL dedicado com os privilégios mínimos necessários em vez de `root`. Crie-o com:
“`sql
CREATE USER 'backup_user'@'localhost' IDENTIFIED BY 'StrongPass';
GRANT SELECT, LOCK TABLES, SHOW VIEW, TRIGGER, EVENT ON *.* TO 'backup_user'@'localhost';
FLUSH PRIVILEGES;
“`
Proteger Credenciais com .my.cnf
Passar palavras-passe na linha de comandos expõe-nas no histórico de shell e nas listas de processos. Armazene as credenciais em `~/.my.cnf`:
“`ini
[client]
user=root
password=YourSecurePassword
“`
Defina as permissões imediatamente:
“`bash
chmod 600 ~/.my.cnf
“`
Com isto configurado, todos os comandos `mysqldump` e `mysql` obtêm as credenciais automaticamente sem os sinalizadores `-u` e `-p`.
Exportação de Base de Dados Remota
Para fazer dump de uma base de dados a partir de um servidor MySQL remoto:
“`bash
mysqldump -h remote.server.com -P 3306 -u remoteuser -p remotedatabase > remote_backup.sql
“`
Certifique-se de que a instância MySQL remota permite ligações a partir do seu endereço IP e que a porta 3306 está aberta na firewall. Para transferências encriptadas, utilize um túnel SSH:
“`bash
ssh -L 3307:127.0.0.1:3306 user@remote.server.com -N &
mysqldump -h 127.0.0.1 -P 3307 -u remoteuser -p remotedatabase > remote_backup.sql
“`
Matriz de Decisão Prática
| Cenário | Comando Recomendado |
|---|
| — | — |
|---|
| Backup completo, apenas InnoDB, sem tempo de inatividade | `mysqldump –single-transaction –routines –triggers –events` |
|---|
| Migração de esquema para novo servidor | `mysqldump –no-data` + recriar BD + importar |
|---|
| Mover uma única base de dados entre servidores | `mysqldump db | gzip | ssh user@dest "gunzip | mysql db"` |
|---|
| Backup de todas as bases de dados, excluir esquemas de sistema | `–all-databases` + `–ignore-table` para tabelas de sistema |
|---|
| Restauro rápido de dump grande | Desativar `foreign_key_checks`, `unique_checks`, `autocommit` |
|---|
| Backup automático noturno | Cron + utilizador de backup dedicado + credenciais `.my.cnf` |
|---|
| Verificar integridade do backup | Importar para uma base de dados de teste e executar `SHOW TABLE STATUS` |
|---|
Principais Conclusões Técnicas
- Utilize sempre `–single-transaction` para bases de dados InnoDB para evitar bloquear escritas da aplicação durante a exportação
- Especifique sempre `utf8mb4` explicitamente — nunca dependa de suposições sobre o conjunto de caracteres predefinido do servidor
- Inclua `–routines`, `–triggers` e `–events` em cada backup completo da aplicação ou arrisca perder a lógica de negócio
- Nunca importe tabelas de esquemas de sistema (`mysql.*`) entre versões principais do MySQL
- Armazene as credenciais em `~/.my.cnf` com `chmod 600` — nunca passe palavras-passe como argumentos inline
- Para bases de dados superiores a 10 GB, avalie `mysqlpump` ou os utilitários de dump paralelo do MySQL Shell, pois `mysqldump` tornar-se-á um bottleneck
- Verifique cada backup realizando um restauro de teste num ambiente isolado antes de depender dele para recuperação de desastres
- Ao alojar múltiplas bases de dados de clientes, isole os ambientes utilizando Painéis de Controlo VPS separados para evitar acesso entre inquilinos durante operações de restauro
- Combine a sua estratégia de backup de base de dados com um Certificado SSL válido em qualquer camada de aplicação web que se ligue ao MySQL para evitar a interceção de credenciais em trânsito
FAQ
Qual é a diferença entre mysqldump e mysqlpump?
`mysqldump` é de thread único e produz um único ficheiro SQL — fiável e universalmente compatível. `mysqlpump`, introduzido no MySQL 5.7.8, suporta exportação paralela de múltiplas bases de dados e tabelas simultaneamente, reduzindo significativamente o tempo de dump em servidores multi-core. No entanto, `mysqlpump` tem problemas conhecidos com backups consistentes de bases de dados com motores mistos e é menos adequado para migrações entre versões.
Posso importar um dump do MySQL 5.7 para o MySQL 8.0?
Sim, com ressalvas. Os dados de utilizador e os esquemas de aplicação importam sem problemas. No entanto, nunca importe a base de dados de sistema `mysql` diretamente — o plugin de autenticação mudou de `mysql_native_password` para `caching_sha2_password` na versão 8.0, e importar tabelas de privilégios antigas irá quebrar a autenticação. Recrie os utilizadores manualmente utilizando instruções `CREATE USER` e `GRANT`.
Porque é que a minha importação falha com “ERROR 1005: Can’t create table” devido a restrições de chave estrangeira?
Isto acontece quando as tabelas são importadas numa ordem que viola as dependências de chave estrangeira. A solução é adicionar `SET foreign_key_checks = 0;` no início da sua sessão de importação e `SET foreign_key_checks = 1;` no final. Em alternativa, exporte com `–single-transaction` que preserva a integridade referencial no próprio ficheiro de dump.
Como exporto apenas os dados sem as instruções CREATE TABLE?
Utilize o sinalizador `–no-create-info`: `mysqldump -u root -p –no-create-info mydatabase > data_only.sql`. Isto é útil quando precisa de recarregar dados num esquema existente sem alterar a sua estrutura.
Qual é a forma mais segura de transferir um dump MySQL entre dois servidores remotos?
Encaminhe o dump diretamente via SSH sem escrever um ficheiro intermédio em disco: `mysqldump -u root -p sourcedb | ssh user@destination.server "mysql -u root -p targetdb"`. Isto é mais rápido e mais seguro do que copiar um ficheiro `.sql` em texto simples, especialmente quando se opera num ambiente de Alojamento Web Partilhado onde as quotas de disco são uma limitação.
