Como posso mover um banco de dados de um servidor para outro?

136

Como posso mover tabelas MySQL de um servidor físico para outro?

Como este cenário exato: Eu tenho um servidor MySQL que usa a tabela innodb e tem tamanho de aproximadamente 20 GB.

Quero movê-lo para um novo servidor, qual é a maneira mais eficiente de fazer isso?

John
fonte
4
Eu usaria o xtrabackup percona.com/docs/wiki/… É muito parecido com copiá-lo, mas você pode manter o servidor funcionando e assumindo que você usa principalmente tabelas innodb (que você disse ter), você pode considerá-lo um "quente" backup também.
Jonathan
Não me beneficio de outras pessoas que usam esta ferramenta. É gratuito / de código aberto e, apesar de ter sido fabricado por uma empresa, é fácil de usar e você não precisa considerar a compra de suporte dessa empresa.
Jonathan

Respostas:

80

Minha maneira favorita é canalizar um comando sqldump para um comando sql. Você pode fazer todos os bancos de dados ou um específico. Então, por exemplo,

mysqldump -uuser -ppassword myDatabase | mysql -hremoteserver -uremoteuser -premoteserverpassword 

Você pode fazer todos os bancos de dados com

mysqldump --all-databases -uuser -ppassword | mysql -hremoteserver -uremoteuser -premoteserver 

O único problema é quando o banco de dados é muito grande e o tubo entra em colapso. Nesse caso, você pode fazer tabela por tabela ou qualquer um dos outros métodos mencionados abaixo.

David Hall
fonte
4
Dica: Se nenhum dos bancos de dados permitir conexões remotas, passe direto netcat.
Bart van Heukelom
1
Para que isso funcionasse, eu tive que criar um banco de dados vazio com o mesmo nome no servidor remoto e, em seguida, adicionar o nome desse banco de dados ao final do comando.
Zugwalt 18/11/2013
1
Isso é elegante, mas sem compactação dificilmente rápido o suficiente para o banco de dados de 20 GB.
Daddy32
Esta solução é adequada apenas para uma rede totalmente controlada (se e somente se estiver em uma rede privada segura, leia: não a Internet)! Mas solução rápida e fácil!
tdaget
Isso é muito rápido! Mas o que o @Zugwalt disse também era verdade para mim. O comando não funcionou até eu criar o banco de dados (vazio) e adicionar o nome do banco de dados ao final do comando.
Skeets
65

Recentemente, mudei um banco de dados de 30 GB com a seguinte estratégia:

Servidor antigo

  • Pare o servidor mysql
  • Copie o conteúdo do datadir para outro local no disco ( ~/mysqldata/*)
  • Inicie o servidor mysql novamente (o tempo de inatividade foi de 10 a 15 minutos)
  • comprimir os dados ( tar -czvf mysqldata.tar.gz ~/mysqldata)
  • copie o arquivo compactado para o novo servidor

Novo servidor

  • instale o mysql (não inicie)
  • descompacte o arquivo compactado ( tar -xzvf mysqldata.tar.gz)
  • move o conteúdo do mysqldata para o datadir
  • Verifique se o seu innodb_log_file_size é o mesmo no novo servidor ou, se não for, não copie os arquivos de log antigos (o mysql os gerará )
  • Inicie o mysql
Derek Downey
fonte
1
Pule a cópia após compactar / descompactar. Transmita o alcatrão pela rede usando ssh ou (se e somente se houver uma rede privada segura lida: não a Internet) use o netcat para evitar a sobrecarga de criptografia. Além disso, se em uma rede local pular o gzipping, se você tem um tubo de rede rápida você encontrará a transferência de um gargalo em uma fiação núcleo atrelada fazendo a compressão
atxdba
Isso funciona para o innodb e o myisam? Além disso, os usuários do mysql também estão no datadir?
giorgio79
2
@ giorgio79 com certeza desde que você mova os arquivos ibdata também. Por padrão, esses estão no datadir. Usuários do MySQL são armazenados na pasta mysql em um espaço de tabela do usuário.
Derek Downey
2
Este procedimento funcionará para mudar do Windows para o Linux?
ypercubeᵀᴹ
2
@ TypoCubeᵀᴹ desculpe-me por demorar mais de dois anos para responder, mas teria me ajudado se alguém dissesse definitivamente: "Sim, funciona do Windows para o Linux". No meu caso, fui do Windows Server 2012 R2 para o Cent OS (Red Hat 4.8.5-11) . A versão específica do mysql era Maria DB 10.1 . Conforme prescrito, parei os dois serviços mysql, sincronizei o diretório de dados e, ao iniciar o serviço mysql no novo servidor, todos os bancos de dados, tabelas e usuários do banco de dados estavam completamente intactos.
precisa saber é o seguinte
30

De acordo com o Guia de Estudo de Certificação do MySQL 5.0 , Capítulo 32, Seção 32.3.4, Páginas 456.457, descreve as Condições de Portabilidade Binária que trazem o seguinte:

A portabilidade binária é importante se você deseja fazer um backup binário feito em uma máquina e usá-lo em outra máquina com arquitetura diferente. Por exemplo, usar um backup binário é uma maneira de copiar bancos de dados de um servidor MySQL para outro.

Para o MyISAM, portabilidade binária significa que você pode copiar diretamente os arquivos de uma tabela MyISAM de um servidor MySQL para outro em uma máquina diferente e o segundo servidor poderá acessar a tabela.

Para o InnoDB, portabilidade binária significa que você pode copiar diretamente os arquivos do espaço de tabela de um servidor MySQL em uma máquina para outro servidor em uma máquina diferente e o segundo servidor poderá acessar o espaço de tabela. Por padrão, todas as tabelas do InnoDB gerenciadas por um servidor são armazenadas juntas no espaço de tabela; portanto, a portabilidade do espaço de tabela depende da capacidade de todas as tabelas individuais do InnoDB serem portáteis. Se mesmo uma tabela não for portátil, o espaço de tabela também não será.

As tabelas MyISAM e os espaços de tabela do InnoDB são portáteis binárias de um host para outro, se duas condições forem atendidas:

  • Ambas as máquinas devem usar aritmética de número inteiro com dois complemento
  • Ambas as máquinas devem usar o formato de ponto flutuante IEEE ou as tabelas não devem conter colunas de ponto flutuante (FLOAT ou DOUBLE)

Na prática, essas duas condições apresentam pouca restrição. A aritmética de número inteiro com complemento de dois e o formato de ponto flutuante IEEE são a norma no hardware moderno. Uma terceira condição para a portabilidade binária do InnoDB é que você use nomes em minúsculas para tabelas e bancos de dados. Isso ocorre porque o InnoDB armazena esses nomes internamente (em seu dicionário de dados) em minúsculas no Windows. O uso de nomes em minúsculas permite a portabilidade binária entre o Windows e o Unix. Para forçar o uso de nomes em minúsculas, você pode colocar as seguintes linhas em um arquivo de opções:

[mysqld]
lower_case_table_names=1

Se você configurar o InnoDB para usar espaços de tabela por tabela, as condições de portabilidade binária serão estendidas para incluir os arquivos .ibd das tabelas do InnoDB também. (As condições para os espaços de tabela compartilhados ainda se aplicam porque contém o dicionário de dados que armazena informações sobre todas as tabelas do InnoDB.)

Se as condições de portabilidade binária não forem satisfeitas, você pode copiar as tabelas MyISAM ou InnoDB de um servidor para outro despejando-as usando algum formato de texto (por exemplo, com mysqldump) e recarregando-as no servidor de destino.

Existem duas maneiras principais, com base no mecanismo de armazenamento, de mover tabelas individuais.

Para o exemplo dado, vamos supor o seguinte:

  1. datadir é / var / lib / mysql
  2. banco de dados chamado mydb
  3. tabela no banco de dados mydb chamada mytable .

Tabelas MyISAM

Se mydb.mytable usar o mecanismo de armazenamento MyISAM, a tabela será manifestada fisicamente como três arquivos separados

  1. /var/lib/mysql/mydb/mytable.frm (arquivo .frm)
  2. /var/lib/mysql/mydb/mytable.MYD (arquivo .MYD)
  3. /var/lib/mysql/mydb/mytable.MYI (arquivo .MYI)

O .frm contém a estrutura da tabela.
O .MYD contém os dados da tabela.
O .MYI contém a página de índice da tabela

Esses arquivos são usados ​​interdependentemente para representar a tabela do ponto de vista lógico no mysql. Como esses arquivos não têm mais associação lógica anexada, migrando uma tabela de um servidor de banco de dados para outro. Você pode até fazer isso de um servidor Windows para um servidor Linux ou um MacOS. Obviamente, você pode desligar o mysql e copiar os 3 arquivos de tabela. Você pode executar o seguinte:

LOCK TABLES mydb.mytable READ;
SELECT SLEEP(86400);
UNLOCK TABLES;

em uma sessão ssh para manter a tabela como somente leitura e manter a trava por 24 horas. Um segundo depois, execute a cópia em outra sessão ssh. Então mate a sessão do mysql com o bloqueio de 24 horas. Você não precisa esperar 24 horas.

Tabelas InnoDB

Com base na citação acima mencionada no livro Certificação, existem muitos fatores que determinam como fazer backup de uma tabela específica do InnoDB. Por uma questão de simplicidade, clareza e concisão, basta executar um mysqldump da tabela desejada usando os parâmetros --single-transaction para obter um despejo perfeito da tabela em um determinado momento. Não há necessidade de se preocupar com a semântica do InnoDB se você quiser apenas uma tabela. Você pode recarregar esse arquivo de despejo em qualquer servidor MySQL de sua escolha.

Como duas perguntas foram mescladas aqui (jcolebrand): EDIT

Se você estiver disposto a viver com um desempenho lento do banco de dados, poderá executar uma série de rsyncs do servidor antigo (ServerA) para o novo servidor (ServerB), mesmo enquanto o mysql ainda estiver em execução no ServerA.

Etapa 01) instale a mesma versão do mysql no ServerB que o ServerA possui

Etapa 02) No ServerA, execute o SET GLOBAL innodb_max_dirty_pages_pct = 0;mysql e aproximadamente 10 minutos (Isso remove páginas sujas do InnoDB Buffer Pool. Também ajuda a executar um desligamento do mysql mais rapidamente) Se o seu banco de dados for todo MyISAM, você pode pular esta etapa.

Etapa 03) rsync --archive --verbose --stats --partial --progress --human-readable ServerA:/var/lib/mysql ServerB:/var/lib/mysql

Etapa 04) Repita a Etapa 03 até que um rsync leve menos de 1 minuto

Etapa 05) service mysql stopno ServerA

Etapa 06) Execute mais um rsync

Etapa 07) scp ServerA:/etc/my.cnf ServerB:/etc/

Etapa 08) service mysql startno ServerB

Etapa 08) service mysql startno ServerA (opcional)

De uma chance !!!

EMBARGO

Você pode criar um escravo de replicação como este. Lembre-se de definir o ID do servidor explicitamente no master /etc/my.cnf e um número diferente para o id do servidor no slave /etc/my.cnf

RolandoMySQLDBA
fonte
29

Você nem precisa do mysqldump se estiver movendo um esquema de banco de dados inteiro e estiver disposto a interromper o primeiro banco de dados (para que seja consistente ao ser transferido)

  1. Pare o banco de dados (ou bloqueie-o)
  2. Vá para o diretório onde estão os arquivos de dados mysql.
  3. Transfira a pasta (e seu conteúdo) para o novo diretório de dados mysql do servidor
  4. Iniciar o backup do banco de dados
  5. No novo servidor, emita um comando 'create database'.
  6. Recrie os usuários e conceda permissões.

Não me lembro se o mysqldump lida com usuários e permissões, ou apenas com os dados ... mas mesmo se o fizer, isso é muito mais rápido do que fazer um despejo e executá-lo. Eu usaria isso apenas se precisasse despejar um banco de dados mysql para reinserir em outro RDBMS, se precisasse alterar as opções de armazenamento (innodb vs. myisam) ou talvez se estivesse alterando as principais versões do mysql (mas Eu acho que fiz isso entre 4 e 5, no entanto)

Joe
fonte
Isso é mais eficiente, especialmente se um for um administrador de sistema / DBA. BTW mysqldump usando --all-databasesdespeja o esquema mysql. Iniciar o mysql na próxima máquina traz as permissões, desde que você transfira a pasta de dados para a outra máquina com a mesma versão principal do MySQL. (MySQL 5.5.x para MySQL 5.5.x, MySQL 5.1.x para MySQL 5.1.x, MySQL 5.0.x para MySQL 5.0.x)
RolandoMySQLDBA 20-11
4
@ Joe, sim, mysqldumplida com usuários e permissões, pois elas são armazenadas no mysqlesquema.
Shlomi Noach
Essa abordagem é especialmente útil com hospedagem na nuvem, como a AWS. Você pode parar o mysql, desmontar e desanexar do servidor atual; anexe e monte no novo servidor e inicie o mysql. Nenhuma cópia adicional se o volume permanecer no mesmo farm de servidores.
LateralFractal 7/10
12

Se você deseja apenas mover uma tabela específica, tente:

mysqldump -u username -ppassword databasename tablename > databasename.tablename.sql

Você pode especificar mais nomes de tabela acima, no mesmo comando. Depois que o comando for concluído, mova o arquivo databasename.tablename.sql para o outro servidor e restaure usando:

mysql -u username -ppassword databasename < databasename.tablename.sql

Observe que o arquivo .sql de volta é criado usando o programa mysqldump , e a restauração é feita diretamente no mysql .

StanleyJohns
fonte
7
  1. Se você tiver acesso ssh, poderá usar o mysqldump na linha de comando
  2. Se você não possui acesso ssh, mas possui acesso ao phpMyAdmin, pode usá-lo para exportar / importar
  3. Se você não tem acesso ao phpMyAdmin, existem alguns scripts php úteis que serão despejados e importados (no entanto, por experiência própria, nunca encontrei um que seja tão confiável quanto o phpMyAdmin).

Pode haver essa possibilidade em que você move os arquivos de banco de dados reais (para a minha instalação, eles estão localizados em / var / lib / mysql), mas não tenho muita certeza de como isso vai funcionar / funcionar.

poelinca
fonte
5

Você precisará de um tempo de inatividade. Vai demorar um pouco, dependendo da velocidade da sua rede. Eu vou assumir que você está executando o MySQL no Linux / Unix. Aqui está o processo que eu uso:

  1. Pare o daemon mysql no host de origem.
  2. Faça uma pasta tmp no host de destino para receber os arquivos.
  3. Use a tela para fazer uma sessão de shell que sobreviverá caso seu ssh seja desconectado.
  4. Use rsync para transferir os arquivos entre hosts. Algo como: rsync -avhP source user @ targethost: / path / to / folder /
  5. Execute seus casos de teste para garantir que você não perdeu nada na transferência.

Em seguida, proceda como de costume, configurando o MySQL local.

* Nota: você também pode usar o parâmetro -c com rsync para adicionar uma soma de verificação à transferência; no entanto, isso será lento dependendo da velocidade da CPU.

randomx
fonte
4

Posso confirmar que o método do DTest também funciona para copiar entre o ubuntu e o osx.

Para copiar todos os bancos de dados sem precisar fazer dumping ou similar:

Verifique se você possui um mysql limpo do mysql (instalou o dmg baixado do mysql http://cdn.mysql.com/Downloads/MySQL-5.1/mysql-5.1.63-osx10.6-x86_64.dmg ), que (VERY IMPORTANTE) nunca foi executado.

Copie o conteúdo da pasta / var / lib / mysql / da máquina ubuntu em cima de / usr / local / mysql / data / contents no mac. Para ter acesso à pasta get na máquina ubuntu, tive que usar o sudo, ou seja:

sudo cp /var/lib/mysql /home/foouser/mysql_data_folder
sudo chown -R foouser /home/foouser/mysql_data_folder

Copiei a pasta usando scp.

Antes de começar, faça uma cópia da pasta mysql no mac para garantir que você não estrague nada.

Após copiar a pasta, faça o seguinte na máquina mac:

sudo chown -R _mysql /usr/local/mysql/data/
sudo chgrp -R wheel /usr/local/mysql/data/
sudo chmod -R g+rx /usr/local/mysql/data/

Inicie o servidor mysql pela primeira vez (no painel de preferências, em Preferências do Sistema-> mysql). Todos os usuários e bancos de dados agora devem estar configurados corretamente.

Isso funcionou com o mysql 5.1.61 no ubuntu 64 bit 11.10 e o mysql 5.1.63 no osx lion (macbook pro).

paalvibe
fonte
4

Acho que todas as respostas anteriores provavelmente funcionam bem, mas realmente não tratam da questão de definir um nome de banco de dados durante a transferência.

Foi assim que fiz com o bash:

Você pode ser melhor fora de usar rsyncdo que scp, e não comprimir o arquivo se você estiver fazendo isso muitas vezes.

No meu servidor de origem:

me@web:~$ d=members
me@web:~$ mysqldump $d | gzip > $d.sql.gz
me@web:~$ scp -i .ssh/yourkeynamehere $d.sql.gz $sbox:$d.sql.gz

No meu servidor de destino:

me@sandbox:~$ d1=members
me@sandbox:~$ d2=members_sb
me@sandbox:~$ mysqladmin create $d2
me@sandbox:~$ cat $d1.sql.gz | gunzip |  mysql $d2

Em qualquer máquina, para ver o progresso:

me@sandbox:~$ ls *.gz 
me@sandbox:~$ cat $d.sql.gz | gunzip |  less

Isso tudo pressupõe que você tenha o arquivo de configuração do MySQL em seu diretório pessoal nas duas máquinas e defina as permissões:

$ echo "
[client]
user=drupal6
password=metoknow
host=ord-mysql-001-sn.bananas.com
[mysql]
database=nz_drupal" > .my.cnf
$ chmod 0600 ~/.my.cnf
ErichBSchulz
fonte
3

você está movendo para outro servidor mysql db? se for o caso, faça uma exportação para ele

# mysqldump -u username -ppassword database_name > FILE.sql

fonte
Mysqldump? É quando você lida com uma pequena quantidade de dados?
Oh Chin Boon
2
Eu acho que pequeno / grande é bastante subjetivo nos dias de hoje. Quando vi o título da pergunta, esperava que o banco de dados fosse muito maior que 20gb, considerado "grande" ...
Aaron Bertrand
3

Método linux genérico:

/etc/init.d/mysqld stop
rsync -avz source_files destination
vi /etc/my.cnf

edite o datadir (e o soquete) do mysqld e mysqld_safe (se aplicável) para apontar para o novo local e, em seguida,

/etc/init.d/mysql start

Publiquei isso porque ninguém parecia simplesmente listar a menor quantidade de etapas para fazer isso e acho que é a maneira mais simples pessoalmente.

peixes marinhos
fonte
2

Talvez esta seja a melhor maneira de fazê-lo:

Versão 1 : cópia de arquivos de dados (apenas MYISAM)

ssh server1
service mysql stop
cd $mysql-data-dir
rsync -avz dirs-or-files server2:$mysql-data-dir
service mysql start

serviço ssh server2 reinicie o mysql

  • Se os arquivos do banco de dados forem somente leitura, você pode pular a interrupção do servidor.

Versão 2 : mysqldump

Instale o pigz - nos modernos processadores Xeon ou Opteron, especialmente quando você tem 2 ou mais CPUs, é MUITO mais rápido que o gzip.

ssh server1 
mysqldump ... | pigz > backup-YYMDD.sql.gz
rsync backup-YYMDD.sql.gz server:location

ssh server2
pigz -dc location/backup-YYMDD.sql.gz | mysql ..

Versão 3 : master / slave + mysqldump / file-copy

In HA environment you should use the following trick:
setup slave server & do all backups from it
before backups - do "slave stop"; 
then do version 1 or version 2

roteiro:

touch full.start
mysqladmin -h slave-db stop-slave
echo "show slave status \G" | mysql -h slave-db > FULL/comfi-$NOW.master-position
/usr/bin/mysqldump -h slave-db --default-character-set=utf8 -A --opt --skip-lock-tables | pigz > "FULL/XXXX-$NOW.sql.gz"
mysqladmin -h slave-db start-slave
touch full.end

ln -fs "FULL/XXXX-$NOW.sql.gz" FULL.sql.gz

PS:

Para copiar pequenas tabelas, use:

tabela de esquema do mysqldump do ssh server1 | esquema do mysql do ssh server2

parf
fonte
2

Eu sugeriria as duas etapas simples para transferir todo o banco de dados de um servidor para outro.

Passo 1 : Faça um backup completo dos bancos de dados no servidor de origem usando o mysqldump .

Etapa 2 : você pode usar o comando rsync para transferir todos os bancos de dados para o servidor de destino.

Rudra
fonte