Como sincronizar novamente o banco de dados Mysql se o mestre e o escravo tiverem diferentes bases de dados na replicação do Mysql?


139

O Mysql Server1está sendo executado como MASTER .
O Mysql Server2está sendo executado como ESCRAVO .

Agora, a replicação do banco de dados está acontecendo de MASTER para SLAVE .

Server2é removido da rede e reconecte-o novamente após 1 dia. Depois disso, há incompatibilidade no banco de dados no mestre e no escravo.

Como sincronizar novamente o banco de dados, pois depois de restaurar o banco de dados retirado do Master para o Slave, também não resolve o problema?

Respostas:


287

Este é o procedimento passo a passo completo para ressincronizar uma replicação mestre-escravo do zero:

No mestre:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

E copie os valores do resultado do último comando em algum lugar.

Sem fechar a conexão com o cliente (porque liberaria o bloqueio de leitura), emita o comando para obter um despejo do mestre:

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

Agora você pode liberar a trava, mesmo que o despejo ainda não tenha terminado. Para fazer isso, execute o seguinte comando no cliente MySQL:

UNLOCK TABLES;

Agora copie o arquivo de despejo para o escravo usando scp ou sua ferramenta preferida.

No escravo:

Abra uma conexão com o mysql e digite:

STOP SLAVE;

Carregue o dump de dados do mestre com este comando do console:

mysql -uroot -p < mysqldump.sql

Sincronizar logs escravos e mestre:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

Onde os valores dos campos acima são os que você copiou antes.

Por fim, digite:

START SLAVE;

Para verificar se tudo está funcionando novamente, depois de digitar:

SHOW SLAVE STATUS;

Você deveria ver:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

É isso aí!


8
Com INNODB digitado dabatase e outros tipos de colunas complexas como BLOB e datas definido, eu recomendo usar os seguintes parâmetros:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Ken Pega

4
É RESET_SLAVEnecessário? Note-se que estas instruções redefinir o usuário de replicação e senha, então você vai ter que entrar novamente aqueles comCHANGE MASTER TO...
Mike S.

25
Se você usar o sinalizador --master-data ao chamar o mysqldump no mestre, o comando CHANGE MASTER TO será gravado no arquivo de despejo e, assim, salvará a etapa de executá-lo após a importação do arquivo de despejo no escravo.
udog

3
Não bloqueio do mestre (não requer Percona) plusbryan.com/mysql-replication-without-downtime Outra vantagem deste é o despejo SQL também vem com a linha necessária "CHANGE MASTER" (comentada)
mahemoff

2
Existe uma maneira de automatizar isso?
Metafaniel

26

A documentação para isso no site MySQL está lamentavelmente desatualizada e repleta de pedais (como Interactive_timeout). Emitir FLUSH TABLES WITH READ LOCK como parte de sua exportação do mestre geralmente só faz sentido quando coordenado com um instantâneo de armazenamento / sistema de arquivos, como LVM ou zfs.

Se você vai usar o mysqldump, deve confiar na opção --master-data para se proteger contra erros humanos e liberar os bloqueios no mestre o mais rápido possível.

Suponha que o mestre seja 192.168.100.50 e o escravo seja 192.168.100.51, cada servidor tenha uma identificação de servidor distinta configurada, o mestre tenha logon binário e o escravo tenha somente leitura = 1 no my.cnf

Para preparar o escravo para poder iniciar a replicação logo após importar o dump, emita um comando CHANGE MASTER, mas omita o nome e a posição do arquivo de log:

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';

Emita o GRANT no mestre para o escravo usar:

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';

Exporte o mestre (na tela) usando compactação e capturando automaticamente as coordenadas corretas do log binário:

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz

Copie o arquivo replication.sql.gz para o escravo e importe-o com o zcat para a instância do MySQL em execução no escravo:

zcat replication.sql.gz | mysql

Inicie a replicação emitindo o comando para o escravo:

slaveserver> START SLAVE;

Atualize opcionalmente o /root/.my.cnf no escravo para armazenar a mesma senha root que o mestre.

Se você estiver no 5.1+, é melhor primeiro definir o binlog_format do mestre como MIXED ou ROW. Cuidado que os eventos registrados em linha são lentos para tabelas que não possuem uma chave primária. Isso geralmente é melhor que a configuração alternativa (e padrão) da binlog_format = statement (no mestre), pois é menos provável que produza os dados incorretos no escravo.

Se você deve (mas provavelmente não deveria) filtrar a replicação, faça-o com as opções de slave replicate-wild-do-table = dbname.% Ou replicate-wild-ignore-table = badDB.% E use apenas binlog_format = row

Este processo manterá um bloqueio global no mestre pela duração do comando mysqldump, mas não afetará o mestre.

Se você está tentado a usar o mysqldump --master-data - todos os bancos de dados - única transação (porque você só usa tabelas InnoDB), talvez seja melhor atendido usando o MySQL Enterprise Backup ou a implementação de código aberto chamada xtrabackup (cortesia de Percona)


3
Se você deseja simplesmente reconstruir um escravo existente, pode seguir o processo acima, pulando algumas etapas: O GRANT e o comando manual CHANGE MASTER
Outdated

Pergunta 1: No Windows, o que seria equivalente zcat. Pergunta 2: Como isso ocorre mysqldumpcom grandes bancos de dados em termos de desempenho? Qualquer maneira de usar SELECT INTO OUTFILEe LOAD DATAsem problemas em seu processo sugerido? (Uma vez que eles geralmente executar mais rápido)
Ifedi Okonkwo

Não há necessidade de STOP SLAVEalgum lugar no processo?
David V.

16

A menos que você esteja gravando diretamente no escravo (Servidor2), o único problema deve ser que o Servidor2 esteja perdendo as atualizações que ocorreram desde que foi desconectado. Simplesmente reiniciando o escravo com "START SLAVE;" deve ter tudo de volta à velocidade.


2
Você pode verificar os logs de lixeira e ver se eles cobrem o período em que seu sistema ficou fora de sincronia. Se faltam dias, esse pode ser um problema maior e exigir que você faça um dump completo para restaurar os dados ausentes.
Nelaaro

7

Eu acho que os utilitários do Maatkit ajudam você! Você pode usar o mk-table-sync. Por favor, consulte este link: http://www.maatkit.org/doc/mk-table-sync.html


Acho que ele precisará interromper temporariamente as gravações enquanto executa o script.
Ztyx

Isso ainda funciona muito bem. As ferramentas foram renomeadas e agora são chamadas de pt-table-sync. Na verdade, porém, descobri que a ferramenta pt-slave-restart funciona como mágica.
9135 mlerley

7

Estou muito atrasado para esta pergunta, no entanto, encontrei esse problema e, depois de muita pesquisa, encontrei essas informações de Bryan Kennedy: http://plusbryan.com/mysql-replication-without-downtime

No Master, faça um backup como este:
mysqldump --skip-lock-tables - única transação --flush-logs --hex-blob --master-data = 2 -A> ~ / dump.sql

Agora, examine o cabeçalho do arquivo e anote os valores para MASTER_LOG_FILE e MASTER_LOG_POS. Você precisará deles mais tarde: head dump.sql -n80 | grep "MASTER_LOG"

Copie o arquivo "dump.sql" para o Slave e restaure-o: mysql -u mysql-user -p <~ / dump.sql

Conecte-se ao Slave mysql e execute um comando como este: CHANGE MASTER TO MASTER_HOST = 'master-server-ip', MASTER_USER = 'replication-user', MASTER_PASSWORD = 'slave-server-password', MASTER_LOG_FILE = 'value from above', MASTER_LOG_POS = valor acima; ESCRAVO DE INÍCIO;

Para verificar o progresso do escravo: MOSTRAR ESTADO DO ESCRAVO;

Se tudo estiver bem, Last_Error ficará em branco e Slave_IO_State relatará "Aguardando que o mestre envie o evento". Procure Seconds_Behind_Master, que indica o quanto está atrasado. YMMV. :)


3
Isso funciona, e se o escravo já estiver configurado e apenas ficar fora de sincronia, você não precisará executar CHANGE MASTER; basta especificar --master-data=1(ou apenas --master-data).
LSerni

5

Aqui está o que eu normalmente faço quando um escravo do mysql fica fora de sincronia. Eu observei o mk-table-sync, mas achei a seção Riscos assustadora.

No Master:

SHOW MASTER STATUS

As colunas produzidas (Arquivo, Posição) serão úteis para nós daqui a pouco.

No escravo:

STOP SLAVE

Em seguida, despeje o db principal e importe-o para o db escravo.

Em seguida, execute o seguinte:

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;

Onde [Arquivo] e [Posição] são os valores emitidos no "SHOW MASTER STATUS" executado acima.

Espero que isto ajude!


5
Isso parece quebrado, pois aparentemente você não o faz FLUSH TABLES WITH READ LOCK;antes SHOW MASTER STATUSe despeja o banco de dados mestre. Eu acho que isso pode resultar em, por exemplo, erros de chave duplicados no escravo, uma vez que você efetivamente define o status mestre em um momento antes do despejo ser executado, para reproduzir o histórico que já está incluído no despejo. (Se você fizer as coisas na ordem que você descreveu.)
KajMagnus

5

Seguindo a resposta de David ...

O uso SHOW SLAVE STATUS\Gfornecerá uma saída legível por humanos.


Alguma maneira de paginar a saída?
1937 Josiah

'pager mais' Eu acho que vai fazer isso
Ian

3

às vezes você só precisa dar um chute no escravo

experimentar

stop slave;    
reset slave;    
start slave;    
show slave status;

muitas vezes, escravos, eles ficam presos caras :)


... e monitore Positionno mestre usando show master status;contra Exec_Master_Log_Pos:no Slave usando show slave status \G. O escravo deve alcançar o mestre. Trabalhou para mim usando o mysql 5.6 agora após uma pequena interrupção na rede.
Mike S

10
Isso é enganador, uma vez que você redefine o escravo, a pomada perde totalmente o conhecimento sobre onde está o mestre.
Qian Chen

2

Aqui está uma resposta completa que, espero, ajudará outras pessoas ...


Eu quero configurar a replicação do mysql usando master e slave, e como a única coisa que eu sabia era que ele usa arquivos de log para sincronizar, se o slave ficar offline e ficar fora de sincronia, em teoria, ele só precisará se conectar novamente ao mestre e continue lendo o arquivo de log de onde parou, como o usuário malonso mencionou.

Então, aqui está o resultado do teste após a configuração do mestre e do escravo, conforme mencionado em: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

Desde que você use a configuração master / slave recomendada e não escreva para o slave, ele e eu onde estiver certo (no que diz respeito ao mysql-server 5.x). Eu nem precisei usar "START SLAVE;", ele apenas alcançou seu mestre. Mas há um padrão 88000, algo tenta novamente a cada 60 segundos, então eu acho que se você esgotar, talvez precise iniciar ou reiniciar o escravo. De qualquer forma, para quem gosta de saber se ter um escravo ficando offline e fazendo backup novamente, requer intervenção manual. Não, não.

Talvez o pôster original tenha corrompido o (s) arquivo (s) de registro? Mas provavelmente não apenas um servidor que fica fora de linha por um dia.


extraído de /usr/share/doc/mysql-server-5.1/README.Debian.gz, o que provavelmente também faz sentido para servidores não-debian:

* OUTRAS NOTAS SOBRE REPLICAÇÃO
===============================
Se o servidor MySQL estiver atuando como escravo de replicação, você não deve
configure --tmpdir para apontar para um diretório em um sistema de arquivos baseado em memória ou para
um diretório que é limpo quando o host do servidor é reiniciado. Uma replicação
escravo precisa de alguns de seus arquivos temporários para sobreviver a uma reinicialização da máquina,
que ele pode replicar tabelas temporárias ou operações LOAD DATA INFILE. E se
arquivos no diretório de arquivos temporários são perdidos quando o servidor é reiniciado,
replicação falha.

você pode usar algo como sql: show variáveis ​​como 'tmpdir'; descobrir.


O banco de dados será sincronizado automaticamente entre si? Por exemplo, eu escrevo para o Master, o Slave será atualizado automaticamente?
TransformBinary

2

Adicionando à resposta popular para incluir este erro:

"ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO",

Replicação do escravo de uma só vez:

Em uma janela do terminal:

mysql -h <Master_IP_Address> -uroot -p

Após conectar,

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

O status aparece como abaixo: Observe que o número da posição varia!

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      98  | your_DB      |                  |
+------------------+----------+--------------+------------------+

Exporte o dump de maneira semelhante à que ele descreveu " usando outro terminal "!

Saia e conecte-se ao seu próprio banco de dados (que é o escravo):

mysql -u root -p

Digite os comandos abaixo:

STOP SLAVE;

Importe o Dump conforme mencionado (em outro terminal, é claro!) E digite os comandos abaixo:

RESET SLAVE;
CHANGE MASTER TO 
  MASTER_HOST = 'Master_IP_Address', 
  MASTER_USER = 'your_Master_user', // usually the "root" user
  MASTER_PASSWORD = 'Your_MasterDB_Password', 
  MASTER_PORT = 3306, 
  MASTER_LOG_FILE = 'mysql-bin.000001', 
  MASTER_LOG_POS = 98; // In this case

Depois de logado, defina o parâmetro server_id (geralmente, para bancos de dados novos / não replicados, isso não é definido por padrão),

set global server_id=4000;

Agora, inicie o escravo.

START SLAVE;
SHOW SLAVE STATUS\G;

A saída deve ser a mesma que ele descreveu.

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

Nota: Uma vez replicado, o mestre e o escravo compartilham a mesma senha!


O banco de dados será sincronizado automaticamente entre si? Por exemplo, eu escrevo para o Master, o Slave será atualizado automaticamente?
TransformBinary

1

Reconstruindo o escravo usando LVM

Aqui está o método que usamos para reconstruir escravos MySQL usando Linux LVM. Isso garante uma captura instantânea consistente e exige um tempo de inatividade mínimo no mestre.

Defina o percentual máximo de páginas sujas do innodb como zero no servidor MySQL mestre. Isso forçará o MySQL a gravar todas as páginas no disco, o que acelerará significativamente a reinicialização.

set global innodb_max_dirty_pages_pct = 0;

Para monitorar o número de páginas sujas, execute o comando

mysqladmin ext -i10 | grep dirty

Quando o número parar de diminuir, você alcançará o ponto de continuar. Em seguida, redefina o mestre para limpar os antigos registros de bandeja / logs de retransmissão:

RESET MASTER;

Execute lvdisplay para obter o LV Path

lvdisplay

A saída ficará assim

--- Logical volume ---
LV Path                /dev/vg_mysql/lv_data
LV Name                lv_data
VG Name                vg_mysql

Encerre o banco de dados mestre com o comando

service mysql stop

Em seguida, tire uma foto, mysql_snapshot será o novo nome do volume lógico. Se houver binlogs na unidade do SO, eles também precisam ser instantâneos.

lvcreate --size 10G --snapshot --name mysql_snapshot /dev/vg_mysql/lv_data

Inicie o master novamente com o comando

service mysql start

Restaurar a configuração de páginas sujas para o padrão

set global innodb_max_dirty_pages_pct = 75;

Execute lvdisplay novamente para garantir que o instantâneo esteja lá e visível

lvdisplay

Resultado:

--- Logical volume ---
LV Path                /dev/vg_mysql/mysql_snapshot
LV Name                mysql_snapshot
VG Name                vg_mysql

Monte o instantâneo

mkdir /mnt/mysql_snapshot
mount /dev/vg_mysql/mysql_snapshot /mnt/mysql_snapshot

Se você possui um escravo do MySQL em execução, precisa interrompê-lo

service mysql stop

Em seguida, você precisa limpar a pasta de dados do MySQL

cd /var/lib/mysql
rm -fr *

De volta ao mestre. Agora rsync o instantâneo para o escravo do MySQL

rsync --progress -harz /mnt/mysql_snapshot/ targethostname:/var/lib/mysql/

Depois que o rsync for concluído, você pode desmontar e remover o instantâneo

umount /mnt/mysql_snapshot
lvremove -f /dev/vg_mysql/mysql_snapshot

Crie um usuário de replicação no mestre se o usuário de replicação antigo não existir ou a senha for desconhecida

GRANT REPLICATION SLAVE on *.* to 'replication'@'[SLAVE IP]' identified by 'YourPass';

Verifique se os arquivos de dados / var / lib / mysql pertencem ao usuário mysql, caso contrário, você pode omitir o seguinte comando:

chown -R mysql:mysql /var/lib/mysql

Em seguida, grave a posição do binlog

ls -laF | grep mysql-bin

Você verá algo como

..
-rw-rw----     1 mysql mysql  1073750329 Aug 28 03:33 mysql-bin.000017
-rw-rw----     1 mysql mysql  1073741932 Aug 28 08:32 mysql-bin.000018
-rw-rw----     1 mysql mysql   963333441 Aug 28 15:37 mysql-bin.000019
-rw-rw----     1 mysql mysql    65657162 Aug 28 16:44 mysql-bin.000020

Aqui, o arquivo de log principal é o número de arquivo mais alto na sequência e a posição do log de posição é o tamanho do arquivo. Registre estes valores:

master_log_file=mysql-bin.000020
master_log_post=65657162

Em seguida, inicie o MySQL escravo

service mysql start

Execute o comando change master no escravo, executando o seguinte:

CHANGE MASTER TO 
master_host="10.0.0.12", 
master_user="replication", 
master_password="YourPass", 
master_log_file="mysql-bin.000020", 
master_log_pos=65657162; 

Finalmente inicie o escravo

SLAVE START;

Verifique o status do escravo:

SHOW SLAVE STATUS;

Verifique se o Slave IO está em execução e se não há erros de conexão. Boa sorte!

Juha Vehnia BR

Eu escrevi isso recentemente no meu blog, que é encontrado aqui ... Existem mais alguns detalhes lá, mas a história é a mesma.

http://www.juhavehnia.com/2015/05/rebuilding-mysql-slave-using-linux-lvm.html


0

Criei um repositório do GitHub com um script para resolver esse problema rapidamente. Basta alterar algumas variáveis ​​e executá-lo (primeiro, o script cria um backup do seu banco de dados).

Espero que isso ajude você (e outras pessoas também).

Como redefinir (re-sincronizar) a replicação de mestre-escravo do MySQL


Vejo que o script sempre define a posição do log mestre como 1 e o nome do arquivo de log mestre. Não sei o suficiente para ter certeza se devo me preocupar com isso ou não. Você poderia explicar? Atualmente, tenho uma posição de mais de 1.000.000. Isso significa que ele tentará reproduzir consultas de 1 milhão antes de acelerar? Não há chances de corrupção ao reproduzir essas consultas nos dados existentes? Eu estou querendo saber por que não no script ao fazer um despejo mysql use a opção --master-data = 2 e, em seguida, puxe o arquivo e pos para fora do despejo para defini-los?
1937 Josiah

0

Estamos usando a técnica de replicação mestre-mestre do MySQL e, se um servidor MySQL diz que 1 é removido da rede, ele se reconecta após a restauração da conexão e todos os registros que foram confirmados no servidor 2 que estava na rede são transferidos para o servidor 1 que perdeu a conexão após a restauração. O escravo no MySQL tenta novamente se conectar ao seu mestre a cada 60 s por padrão. Esta propriedade pode ser alterada como MySQL com uma bandeira "master_connect_retry = 5" onde 5 está em segundos. Isso significa que queremos uma nova tentativa a cada 5 s.

Mas você precisa garantir que o servidor que perdeu a conexão não faça nenhuma confirmação no banco de dados à medida que você receber um erro de chave duplicado Código de erro: 1062


0

Mestre :

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  

scp master:/tmp/dump.sql.gz slave:/tmp/ Mover arquivo de despejo para o servidor escravo

Escravo:

STOP SLAVE;

zcat /tmp/dump.sql.gz | mysql -u root -p

START SLAVE;
SHOW SLAVE STATUS;  

NOTA :
No mestre, você pode executar SET GLOBAL expire_logs_days = 3para manter os logs de caixa por 3 dias em caso de problemas com os escravos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.