16 min de leitura · Guia técnico
Migrar banco de dados MySQL entre servidores Linux é o processo de exportar todos os dados, estruturas e configurações de um servidor de origem e importá-los em um servidor de destino com integridade total. Para realizar a migração sem perda de dados, siga estes passos:
- Faça o dump completo do banco com
mysqldumpno servidor de origem - Transfira o arquivo
.sqlpara o servidor de destino viascpoursync - Crie o banco de dados e o usuário no servidor de destino
- Importe o dump com o cliente
mysql - Exporte e recrie os usuários e privilégios manualmente
- Valide a integridade dos dados e atualize a string de conexão da aplicação
Pré-requisitos para migrar MySQL entre servidores Linux
- Acesso root ou sudo em ambos os servidores (origem e destino)
- MySQL 8.0 ou MariaDB 10.6+ instalado nos dois servidores
- Conectividade SSH entre os servidores ou acesso a um canal seguro de transferência de arquivos
- Espaço em disco suficiente no servidor de destino — ao menos o dobro do tamanho do banco para acomodar o dump e a importação simultânea
- Credenciais do MySQL com permissão de leitura total no servidor de origem e permissão de criação de banco no destino
- Distribuições testadas neste guia: Debian 12 (origem) e Rocky Linux 9 (destino)
- Utilitários
scp,rsyncegzipdisponíveis em ambos os servidores
Como exportar o banco de dados MySQL com mysqldump
A exportação com mysqldump é o método mais portável para migrar banco de dados MySQL entre servidores Linux, pois gera um arquivo SQL legível e compatível com diferentes versões do servidor. Antes de iniciar, verifique o tamanho do banco para estimar o tempo de exportação.
Acesse o servidor de origem via SSH e execute o comando abaixo para verificar o tamanho dos bancos:
mysql -u root -p -e "SELECT table_schema AS 'Banco', ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'Tamanho (MB)' FROM information_schema.tables GROUP BY table_schema;"
+--------------------+--------------+
| Banco | Tamanho (MB) |
+--------------------+--------------+
| meu_site | 245.80 |
| wordpress_db | 88.40 |
| information_schema | 0.00 |
+--------------------+--------------+
Agora execute o dump do banco desejado com charset correto e compressão para economizar espaço e tempo de transferência:
mysqldump -u root -p \
--default-character-set=utf8mb4 \
--single-transaction \
--routines \
--triggers \
--events \
meu_site | gzip > /root/backup_meu_site_$(date +%Y%m%d).sql.gz
A flag --single-transaction garante um snapshot consistente sem bloquear tabelas InnoDB durante a exportação — essencial para bancos em produção. As flags --routines, --triggers e --events incluem procedures, funções e eventos agendados no dump.
ls -lh /root/backup_meu_site_*.sql.gz
-rw-r--r-- 1 root root 38M jun 10 14:22 /root/backup_meu_site_20240610.sql.gz
Para exportar todos os bancos de uma vez, substitua o nome do banco pela flag --all-databases. Nesse caso, remova a necessidade de criar o banco manualmente no destino, pois o dump incluirá os comandos CREATE DATABASE.
Transferir o dump para o servidor de destino com segurança
A transferência segura do arquivo é etapa crítica para evitar corrupção de dados durante a migração de banco de dados MySQL. Use scp para transferências diretas ou rsync quando precisar de retomada automática em caso de interrupção.
No servidor de origem, execute:
scp /root/backup_meu_site_20240610.sql.gz root@IP_DESTINO:/root/
Se preferir rsync com verificação de integridade e retomada:
rsync -avz --progress /root/backup_meu_site_20240610.sql.gz root@IP_DESTINO:/root/
sending incremental file list
backup_meu_site_20240610.sql.gz
39,845,120 100% 12.34MB/s 0:00:03 (xfr#1, to-chk=0/1)
Após a transferência, valide a integridade do arquivo no servidor de destino comparando o hash MD5:
# No servidor de ORIGEM:
md5sum /root/backup_meu_site_20240610.sql.gz
# No servidor de DESTINO:
md5sum /root/backup_meu_site_20240610.sql.gz
Os dois hashes devem ser idênticos. Se diferirem, repita a transferência antes de prosseguir.
Se os servidores não tiverem conectividade direta, você pode usar um intermediário como seu computador local ou um bucket de armazenamento. Para ambientes cPanel, consulte o artigo Conectando remotamente ao MySQL - cPanel para entender como liberar o acesso remoto ao banco antes da transferência.
Importar o banco de dados MySQL no servidor de destino
Com o arquivo no servidor de destino, o próximo passo da migração de banco de dados MySQL é criar o banco receptor e realizar a importação com o charset correto. Acesse o servidor de destino via SSH.
Primeiro, crie o banco de dados no MySQL do servidor de destino:
mysql -u root -p -e "CREATE DATABASE meu_site CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
Agora descompacte e importe o dump em um único pipeline para economizar espaço em disco:
gunzip -c /root/backup_meu_site_20240610.sql.gz | mysql -u root -p \
--default-character-set=utf8mb4 \
meu_site
Para bancos grandes, é recomendável monitorar o progresso da importação. Em outro terminal, execute:
watch -n 5 'mysql -u root -p -e "SHOW PROCESSLIST\G" 2>/dev/null | grep -A5 "Query"'
Após a conclusão, verifique se todas as tabelas foram importadas corretamente:
mysql -u root -p meu_site -e "SHOW TABLES; SELECT COUNT(*) AS total_tabelas FROM information_schema.tables WHERE table_schema='meu_site';"
+---------------------------+
| Tables_in_meu_site |
+---------------------------+
| categorias |
| pedidos |
| produtos |
| usuarios |
+---------------------------+
+--------------+
| total_tabelas|
+--------------+
| 4 |
+--------------+
Atenção: se o dump foi gerado com --all-databases, não especifique o nome do banco no comando de importação. Use apenas mysql -u root -p < arquivo.sql.
Migrar usuários e privilégios do MySQL manualmente
Um ponto frequentemente negligenciado ao migrar banco de dados MySQL é a exportação dos usuários e suas permissões. O mysqldump padrão não inclui os dados da tabela mysql.user, então é necessário exportá-los separadamente no servidor de origem.
No servidor de origem, liste os usuários existentes:
mysql -u root -p -e "SELECT user, host FROM mysql.user WHERE user NOT IN ('root','mysql.sys','mysql.infoschema','mysql.session');"
+-------------+-----------+
| user | host |
+-------------+-----------+
| app_user | localhost |
| app_user | % |
| readonly_db | 10.0.0.% |
+-------------+-----------+
Para cada usuário, exporte os privilégios com:
mysql -u root -p -e "SHOW GRANTS FOR 'app_user'@'localhost';"
+----------------------------------------------------------------------+
| Grants for app_user@localhost |
+----------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'app_user'@'localhost' |
| GRANT ALL PRIVILEGES ON `meu_site`.* TO 'app_user'@'localhost' |
+----------------------------------------------------------------------+
No servidor de destino, recrie o usuário e seus privilégios:
mysql -u root -p <<EOF
CREATE USER 'app_user'@'localhost' IDENTIFIED BY 'senha_segura_aqui';
GRANT ALL PRIVILEGES ON meu_site.* TO 'app_user'@'localhost';
FLUSH PRIVILEGES;
EOF
Para automatizar a exportação de todos os grants de uma vez, use o script abaixo no servidor de origem:
mysql -u root -p -N -e "SELECT CONCAT('SHOW GRANTS FOR ''', user, '''@''', host, ''';') FROM mysql.user WHERE user NOT IN ('root','mysql.sys','mysql.infoschema','mysql.session')" | mysql -u root -p | sed 's/$/;/' > /root/grants_export.sql
Transfira o arquivo grants_export.sql para o destino e importe com mysql -u root -p < /root/grants_export.sql.
Validar a migração e atualizar a string de conexão
Após importar os dados e recriar os usuários, a validação é a etapa final para confirmar que a migração de banco de dados MySQL foi concluída sem perda. Execute verificações de integridade antes de apontar a aplicação para o novo servidor.
Verifique a contagem de registros nas tabelas principais e compare com o servidor de origem:
mysql -u root -p meu_site -e "
SELECT 'usuarios' AS tabela, COUNT(*) AS registros FROM usuarios
UNION ALL
SELECT 'produtos', COUNT(*) FROM produtos
UNION ALL
SELECT 'pedidos', COUNT(*) FROM pedidos;"
+----------+------------+
| tabela | registros |
+----------+------------+
| usuarios | 1842 |
| produtos | 356 |
| pedidos | 12490 |
+----------+------------+
Teste a conexão com o usuário da aplicação:
mysql -u app_user -p -h localhost meu_site -e "SELECT 1 AS conexao_ok;"
+-------------+
| conexao_ok |
+-------------+
| 1 |
+-------------+
Com a validação concluída, atualize o arquivo de configuração da sua aplicação (por exemplo, wp-config.php para WordPress ou .env para aplicações Laravel) com o novo host, usuário e senha do banco de dados. Para aplicações em servidores com acesso remoto ao MySQL, veja como configurar corretamente em Acessando servidores VPS Linux da AviraHost.
Se estiver usando um VPS e quiser otimizar o desempenho do MySQL após a migração, consulte as Dicas de Otimização de Servidores Linux para ajustes de configuração recomendados.
Problemas comuns e como resolver
Sintoma: Erro "Access denied for user" ao importar o dump
Causa: O usuário MySQL no servidor de destino não tem permissão para criar tabelas ou inserir dados no banco especificado, ou a senha está incorreta.
Solução: Confirme que o banco foi criado antes da importação e que o usuário tem os privilégios corretos. Execute GRANT ALL PRIVILEGES ON meu_site.* TO 'app_user'@'localhost'; FLUSH PRIVILEGES; como root antes de repetir a importação.
Sintoma: Caracteres especiais aparecem como "?" ou "’" após a migração
Causa: O dump foi exportado ou importado sem especificar o charset utf8mb4, causando conversão incorreta de caracteres acentuados e símbolos especiais.
Solução: Refaça o dump adicionando --default-character-set=utf8mb4 tanto no mysqldump quanto no comando mysql de importação. Verifique também se o banco de destino foi criado com CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci.
Sintoma: Importação trava ou encerra com "MySQL server has gone away"
Causa: O valor de max_allowed_packet no servidor de destino é muito baixo para processar inserções de linhas grandes, ou o timeout de conexão foi atingido durante a importação de bancos volumosos.
Solução: Edite o arquivo /etc/mysql/mysql.conf.d/mysqld.cnf (Debian/Ubuntu) ou /etc/my.cnf (Rocky Linux/AlmaLinux) e aumente os valores:
[mysqld]
max_allowed_packet = 256M
net_read_timeout = 3600
net_write_timeout = 3600
wait_timeout = 28800
Reinicie o MySQL com systemctl restart mysql e repita a importação.
Sintoma: Procedures e triggers não foram migrados
Causa: O mysqldump foi executado sem as flags --routines e --triggers, que são opcionais e não ativas por padrão em algumas versões.
Solução: Refaça o dump incluindo explicitamente --routines --triggers --events. Para verificar se há procedures no banco de origem, execute: SHOW PROCEDURE STATUS WHERE Db='meu_site';
Sintoma: Diferença na contagem de registros entre origem e destino
Causa: Novos dados foram inseridos no banco de origem durante o processo de exportação e transferência, ou o dump foi interrompido antes de completar.
Solução: Verifique o tamanho do arquivo .sql.gz e compare os hashes MD5. Se houver discrepância, coloque a aplicação em modo de manutenção, refaça o dump e reimporte. Para bancos em produção com alto volume de escrita, considere usar replicação MySQL para sincronização contínua antes do corte.
Perguntas frequentes sobre migração de banco de dados MySQL
É possível migrar o MySQL sem downtime?
Sim, é possível minimizar o downtime usando replicação MySQL (master-slave) ou colocando a aplicação em modo de manutenção apenas durante a troca de DNS/conexão. Para bancos pequenos, o downtime costuma ser de segundos a poucos minutos. Para bancos grandes em produção, a replicação é a abordagem recomendada, pois permite sincronizar os dados continuamente e realizar o corte com interrupção mínima.
O que acontece com o encoding dos dados durante a migração?
Se o dump for feito sem especificar o charset correto, caracteres especiais como acentos podem ser corrompidos. Sempre use as flags --default-character-set=utf8mb4 no mysqldump e no mysql durante a importação para garantir que o encoding seja preservado corretamente. Verifique também a collation do banco de destino para que seja compatível com a do banco de origem.
Como migrar apenas um banco de dados específico e não todos?
Use o comando mysqldump seguido do nome do banco: mysqldump -u root -p nome_do_banco > backup.sql. Para importar no destino, crie o banco antes e execute: mysql -u root -p nome_do_banco < backup.sql. Isso migra apenas aquele banco sem afetar os demais, mantendo os outros bancos do servidor de destino intactos.
As permissões de usuário do MySQL são migradas automaticamente?
Não. O mysqldump padrão não exporta os usuários e privilégios do MySQL. É necessário exportar a tabela mysql.user separadamente ou recriar os usuários manualmente no servidor de destino com os comandos CREATE USER e GRANT adequados. Ignorar esta etapa resulta em erros de conexão da aplicação mesmo com os dados corretamente importados.
Qual o tamanho máximo de banco que posso migrar com mysqldump?
O mysqldump funciona bem para bancos de até alguns gigabytes. Para bancos muito grandes (acima de 10 GB), ferramentas como mydumper/myloader ou a replicação nativa do MySQL oferecem melhor desempenho e menor risco de timeout durante a exportação e importação. O mydumper realiza dumps paralelos e é significativamente mais rápido para bancos de grande volume.
Conclusão
- Sempre use
--default-character-set=utf8mb4tanto na exportação quanto na importação para evitar corrupção de caracteres especiais em português. - Valide a integridade com MD5 e contagem de registros antes de apontar a aplicação para o novo servidor — uma migração aparentemente bem-sucedida pode ter dados faltando se o dump foi interrompido.
- Não esqueça de migrar os usuários e privilégios manualmente usando
SHOW GRANTSe recriando comCREATE USEReGRANTno servidor de destino, pois omysqldumppadrão não os inclui.
Leia também
- Passo a passo para transferir PostgreSQL entre servidores preservando encoding
- Solucionar lentidão no MySQL 8.0 antes que derrube sua aplicação
- Guia: Laravel não conecta ao MySQL no Debian 12
Precisa de ajuda com migração de banco de dados MySQL?
Migrar bancos de dados em produção exige atenção a cada detalhe — desde o charset até os privilégios de usuário. Um VPS com suporte técnico especializado pode fazer toda a diferença para garantir que sua migração ocorra sem perda de dados e com o menor tempo de inatividade possível.
Conheça os planos de VPS da AviraHost e migre seu MySQL com segurança