Poupe até 53% em Servidores VPS, escolha agora. Oferta limitada.

Migrar banco de dados MySQL entre servidores Linux sem perda

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:

  1. Faça o dump completo do banco com mysqldump no servidor de origem
  2. Transfira o arquivo .sql para o servidor de destino via scp ou rsync
  3. Crie o banco de dados e o usuário no servidor de destino
  4. Importe o dump com o cliente mysql
  5. Exporte e recrie os usuários e privilégios manualmente
  6. 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, rsync e gzip disponí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=utf8mb4 tanto 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 GRANTS e recriando com CREATE USER e GRANT no servidor de destino, pois o mysqldump padrão não os inclui.

Leia também

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

  • 0 Os usuários acharam isso útil
  • MySQL, migração, Linux, banco-de-dados, VPS, dump, AviraHost
Esta resposta foi útil?

Artigos Relacionados

Otimizar cache Redis para aplicações PHP no Ubuntu 22.04

Para otimizar o cache Redis para aplicações PHP no Ubuntu 22.04, instale e configure o Redis,...

Configurar Alertas Automáticos com Zabbix no Ubuntu

Para configurar alertas automáticos com Zabbix no Ubuntu, instale o Zabbix Server, configure...

Otimizar MySQL: como reduzir uso de memória e acelerar consultas

Otimizar MySQL é o processo de ajustar configurações e consultas para reduzir o consumo de...

Entenda o que é Swap no Linux: como funciona e quando usar

Swap no Linux é um espaço em disco usado como extensão da memória RAM quando esta se esgota. O...

Guia Definitivo: Configurar Nginx como Proxy Reverso

Para configurar o Nginx como proxy reverso, instale o Nginx, crie um arquivo de configuração de...