Come risincronizzare il DB Mysql se Master e slave hanno un database diverso in caso di replica Mysql?


139

Mysql Server1funziona come MASTER .
Mysql Server2funziona come SLAVE .

Ora la replica DB sta avvenendo da MASTER a SLAVE .

Server2viene rimosso dalla rete e riconnetterlo dopo 1 giorno. Dopodiché c'è una mancata corrispondenza nel database in master e slave.

Come risincronizzare nuovamente il DB perché dopo aver ripristinato il DB preso da Master a Slave non si risolve il problema?

Risposte:


287

Questa è la procedura passo-passo completa per risincronizzare da zero una replica master-slave:

Al maestro:

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

E copia i valori del risultato dell'ultimo comando da qualche parte.

Senza chiudere la connessione al client (perché rilascerebbe il blocco di lettura) emettere il comando per ottenere un dump del master:

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

Ora puoi rilasciare il blocco, anche se il dump non è ancora terminato. Per farlo, esegui il seguente comando nel client MySQL:

UNLOCK TABLES;

Ora copia il file di dump sullo slave usando scp o il tuo strumento preferito.

Allo schiavo:

Apri una connessione a mysql e digita:

STOP SLAVE;

Carica il dump dei dati del master con questo comando della console:

mysql -uroot -p < mysqldump.sql

Sincronizza registri slave e master:

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

Dove i valori dei campi precedenti sono quelli che hai copiato in precedenza.

Infine, digita:

START SLAVE;

Per verificare che tutto funzioni di nuovo, dopo aver digitato:

SHOW SLAVE STATUS;

tu dovresti vedere:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Questo è tutto!


8
Con la dabatase tipizzata INNODB e altri tipi di colonne complessi come BLOB e DATE definiti, raccomando di utilizzare i seguenti parametri:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Ken Pega

4
È RESET_SLAVEnecessario? Nota che queste istruzioni ripristinano l'utente e la password della replica, quindi dovrai reinserirli conCHANGE MASTER TO...
Mike S.

25
Se si utilizza il flag --master-data quando si chiama mysqldump sul master, il comando CHANGE MASTER TO viene scritto nel file di dump e quindi salva la fase di esecuzione dopo aver importato il file di dump nello slave.
udog,

3
Non bloccare il master (non richiede Percona) plusbryan.com/mysql-replication-without-downtime Un altro vantaggio di questo è il dump SQL fornito anche con la riga "CHANGE MASTER" necessaria (commentata)
mahemoff

2
C'è un modo per automatizzare questo?
Metafaniel,

26

La documentazione per questo sul sito MySQL è tristemente obsoleta ed è piena di armi da fuoco (come Interactive_timeout). Emettere TABELLE DI FLUSH CON READ LOCK come parte dell'esportazione del master generalmente ha senso solo se coordinato con un'istantanea di archiviazione / filesystem come LVM o zfs.

Se stai per usare mysqldump, dovresti invece fare affidamento sull'opzione --master-data per proteggerti dagli errori umani e rilasciare i blocchi sul master il più rapidamente possibile.

Supponiamo che il master sia 192.168.100.50 e lo slave sia 192.168.100.51, ogni server ha un ID server distinto configurato, il master ha il login binario e lo slave ha sola lettura = 1 in my.cnf

Per mettere in scena lo slave per poter avviare la replica subito dopo aver importato il dump, emettere un comando CHANGE MASTER ma omettere il nome e la posizione del file di registro:

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

Emettere il GRANT sul master affinché lo slave utilizzi:

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

Esporta il master (nella schermata) usando la compressione e acquisendo automaticamente le coordinate del log binario corrette:

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

Copia il file replication.sql.gz sullo slave e quindi importalo con zcat nell'istanza di MySQL in esecuzione sullo slave:

zcat replication.sql.gz | mysql

Avviare la replica inviando il comando allo slave:

slaveserver> START SLAVE;

Facoltativamente, aggiornare /root/.my.cnf sullo slave per memorizzare la stessa password di root del master.

Se sei su 5.1+, è meglio prima impostare binlog_format del master su MIXED o ROW. Fare attenzione che gli eventi registrati di riga sono lenti per le tabelle prive di chiave primaria. Di solito è meglio della configurazione alternativa (e predefinita) dell'istruzione binlog_format = (sul master), poiché è meno probabile che produca dati errati sullo slave.

Se devi (ma probabilmente non dovresti) filtrare la replica, fallo con le opzioni slave replicate-wild-do-table = dbname.% O replicate-wild-ignore-table = badDB.% E usa solo binlog_format = row

Questo processo manterrà un blocco globale sul master per la durata del comando mysqldump ma non avrà alcun impatto sul master.

Se sei tentato di usare mysqldump --master-data --all-database - single-transazione (perché stai usando solo tabelle InnoDB), potresti essere meglio servito con MySQL Enterprise Backup o l'implementazione open source chiamata xtrabackup (per gentile concessione di Percona)


3
Se vuoi semplicemente ricostruire uno slave esistente, puoi seguire il processo sopra, saltando un paio di passaggi: il comando GRANT e il comando CHANGE MASTER manuale
obsoleto il

Domanda 1: Su Windows, quale sarebbe un equivalente di zcat. Domanda 2: come funziona mysqldumpcon database di grandi dimensioni in termini di prestazioni? Qualche modo di usare SELECT INTO OUTFILEe LOAD DATAsenza intoppi nel processo suggerito? (Dato che generalmente si esibiscono più velocemente)
Ifedi Okonkwo,

Non c'è bisogno di andare STOP SLAVEda qualche parte nel processo?
David V.

16

A meno che non si stia scrivendo direttamente allo slave (Server2), l'unico problema dovrebbe essere che Server2 non ha alcun aggiornamento che si è verificato da quando è stato disconnesso. Basta riavviare lo slave con "START SLAVE;" dovrebbe riportare tutto alla velocità.


2
È possibile controllare i registri del cestino e vedere se coprono il periodo di tempo in cui il sistema non è stato sincronizzato. Se mancano giorni questo potrebbe essere un problema più grande e richiedere di eseguire un dump completo per ripristinare i dati mancanti.
nelaaro,

7

Penso che l'utilità di Maatkit ti aiuti! Puoi usare mk-table-sync. Si prega di consultare questo link: http://www.maatkit.org/doc/mk-table-sync.html


Penso che dovrà interrompere temporaneamente le scritture durante l'esecuzione della sceneggiatura.
Ztyx,

Funziona ancora alla grande. Gli strumenti sono stati rinominati però e ora si chiama pt-table-sync. In realtà, però, ho scoperto che il loro strumento di riavvio pt-slave funziona come per magia.
mlerley,

7

Sono in ritardo a questa domanda, tuttavia ho riscontrato questo problema e, dopo molte ricerche, ho trovato queste informazioni da Bryan Kennedy: http://plusbryan.com/mysql-replication-without-downtime

Su Master esegui un backup come questo:
mysqldump --skip-lock-tables --single-transazione --flush-logs --hex-blob --master-data = 2 -A> ~ / dump.sql

Ora, esamina la testa del file e annota i valori per MASTER_LOG_FILE e MASTER_LOG_POS. Ne avrai bisogno in seguito: head dump.sql -n80 | grep "MASTER_LOG"

Copia il file "dump.sql" su Slave e ripristinalo: mysql -u mysql-user -p <~ / dump.sql

Connetti a Slave mysql ed esegui un comando come questo: CAMBIA MASTER A MASTER_HOST = 'master-server-ip', MASTER_USER = 'replica-user', MASTER_PASSWORD = 'slave-server-password', MASTER_LOG_FILE = 'valore dall'alto', MASTER_LOG_POS = valore dall'alto; INIZIA SLAVE;

Per verificare l'avanzamento di Slave: MOSTRA STATO SLAVE;

Se tutto va bene, Last_Error sarà vuoto e Slave_IO_State segnalerà "In attesa che il master invii l'evento". Cerca Seconds_Behind_Master che indica quanto è distante. YMMV. :)


3
Funziona e se lo slave è già impostato e non è più sincronizzato, non è necessario eseguire CHANGE MASTER; basta specificare --master-data=1(o semplicemente --master-data).
LSerni,

5

Ecco cosa faccio di solito quando uno slave mysql non è più sincronizzato. Ho esaminato mk-table-sync ma ho pensato che la sezione Rischi fosse spaventosa.

Sul master:

SHOW MASTER STATUS

Le colonne in uscita (File, Posizione) ci saranno utili tra un po '.

Sullo schiavo:

STOP SLAVE

Quindi scaricare il master db e importarlo nello slave db.

Quindi eseguire quanto segue:

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

Dove [File] e [Posizione] sono i valori emessi dallo "SHOW MASTER STATUS" eseguito sopra.

Spero che questo ti aiuti!


5
Questo sembra rotto, dal momento che apparentemente non lo fai FLUSH TABLES WITH READ LOCK;prima di SHOW MASTER STATUSscaricare il database principale. Penso che ciò potrebbe comportare, ad esempio, errori di chiave duplicati sullo slave poiché si imposta effettivamente lo stato principale su un punto nel tempo precedente al prelievo del dump, quindi si riprodurrà la cronologia già inclusa nel dump. (Se fai le cose nell'ordine che hai descritto.)
KajMagnus

5

In seguito alla risposta di David ...

L'utilizzo SHOW SLAVE STATUS\Gfornirà un output leggibile dall'uomo.


Qualche modo per sfogliare l'output?
Josiah

'pager more' Penso che lo farà
Ian

3

a volte devi solo dare un calcio allo schiavo

provare

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

abbastanza spesso, schiavi, rimangono bloccati ragazzi :)


... e controlla Positionsul master usando show master status;contro Exec_Master_Log_Pos:sullo Slave usando show slave status \G. Lo schiavo dovrebbe raggiungere il padrone. Ha funzionato per me usando mysql 5.6 proprio ora dopo una breve interruzione di rete.
Mike S,

10
Questo è fuorviante, una volta resettato lo schiavo, la salvezza ha perso totalmente la conoscenza di dove si trova il padrone.
Qian Chen,

2

Ecco una risposta completa che speriamo possa aiutare gli altri ...


Voglio configurare la replica mysql usando master e slave, e poiché l'unica cosa che sapevo era che utilizzava i file di registro per la sincronizzazione, se lo slave si disconnette e non si sincronizza, in teoria dovrebbe solo riconnettersi al suo master e continua a leggere il file di registro da dove era stato interrotto, come menzionato dall'utente Malonso.

Ecco quindi il risultato del test dopo aver configurato master e slave come indicato da: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

A condizione che tu usi la configurazione master / slave consigliata e non scrivi allo slave, lui e io dove siamo (per quanto riguarda mysql-server 5.x). Non ho nemmeno bisogno di usare "START SLAVE;", ha appena raggiunto il suo padrone. Ma c'è un valore predefinito di 88000 che riprova ogni 60 secondi, quindi immagino che se si esaurisce la necessità di avviare o riavviare lo slave. Ad ogni modo, per quelli come me che volevano sapere se avere uno slave andare offline e fare nuovamente il backup richiede un intervento manuale .. no, non lo fa.

Forse il poster originale aveva corruzione nei file di registro? Ma molto probabilmente non è solo un server che va fuori linea per un giorno.


estratto da /usr/share/doc/mysql-server-5.1/README.Debian.gz che probabilmente ha senso anche per i server non debian:

* ULTERIORI NOTE SULLA REPLICAZIONE
===============================
Se il server MySQL agisce come uno slave di replica, non dovresti
impostare --tmpdir in modo che punti a una directory su un filesystem basato sulla memoria o su
una directory che viene cancellata al riavvio dell'host del server. Una replica
slave ha bisogno di alcuni dei suoi file temporanei per sopravvivere al riavvio della macchina, quindi
che può replicare tabelle temporanee o operazioni LOAD DATA INFILE. Se
i file nella directory dei file temporanei vengono persi al riavvio del server,
la replica non riesce.

puoi usare qualcosa come sql: mostra variabili come 'tmpdir'; per scoprirlo.


Entrambi i database si sincronizzeranno automaticamente tra loro? Ad esempio, scrivo a Master, Slave verrà aggiornato automaticamente?
TransformBinary

2

Aggiungendo alla risposta popolare per includere questo errore:

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

Replica da schiavo in un colpo solo:

In una finestra terminale:

mysql -h <Master_IP_Address> -uroot -p

Dopo il collegamento,

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

Lo stato appare come di seguito: Notare che il numero di posizione varia!

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

Esporta il dump in modo simile a come ha descritto " usando un altro terminale "!

Esci e connettiti al tuo DB (che è lo slave):

mysql -u root -p

Digita i comandi seguenti:

STOP SLAVE;

Importa il Dump come indicato (ovviamente in un altro terminale!) E digita i comandi seguenti:

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

Una volta effettuato l'accesso, imposta il parametro server_id (di solito, per i DB nuovi / non replicati, questo non è impostato di default),

set global server_id=4000;

Adesso avvia lo schiavo.

START SLAVE;
SHOW SLAVE STATUS\G;

L'output dovrebbe essere lo stesso che ha descritto.

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

Nota: una volta replicati, il master e lo slave condividono la stessa password!


Entrambi i database si sincronizzeranno automaticamente tra loro? Ad esempio, scrivo a Master, Slave verrà aggiornato automaticamente?
TransformBinary

1

Ricostruzione dello slave mediante LVM

Ecco il metodo che usiamo per ricostruire gli slave MySQL usando Linux LVM. Ciò garantisce un'istantanea coerente, pur richiedendo tempi di inattività minimi sul master.

Impostare la percentuale massima di pagine sporche innodb su zero sul server MySQL principale. Ciò costringerà MySQL a scrivere tutte le pagine sul disco, accelerando notevolmente il riavvio.

set global innodb_max_dirty_pages_pct = 0;

Per monitorare il numero di pagine sporche, eseguire il comando

mysqladmin ext -i10 | grep dirty

Una volta che il numero smette di diminuire, hai raggiunto il punto per continuare. Quindi reimpostare il master per cancellare i vecchi registri bin / registri di inoltro:

RESET MASTER;

Eseguire lvdisplay per ottenere LV Path

lvdisplay

L'output sarà simile a questo

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

Arrestare il database principale con il comando

service mysql stop

Successivamente fai uno snapshot, mysql_snapshot sarà il nuovo nome del volume logico. Se i binlog sono posizionati sull'unità del sistema operativo, anche quelli devono essere istantanei.

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

Riavvia master con comando

service mysql start

Ripristina l'impostazione di pagine sporche sul valore predefinito

set global innodb_max_dirty_pages_pct = 75;

Eseguire di nuovo lvdisplay per assicurarsi che l'istantanea sia presente e visibile

lvdisplay

Produzione:

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

Montare l'istantanea

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

Se hai uno slave MySQL esistente in esecuzione, devi interromperlo

service mysql stop

Successivamente è necessario cancellare la cartella di dati MySQL

cd /var/lib/mysql
rm -fr *

Torna al maestro. Ora sincronizza di nuovo l'istantanea con lo slave MySQL

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

Una volta completato rsync, è possibile smontare e rimuovere l'istantanea

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

Creare l'utente di replica sul master se il vecchio utente di replica non esiste o la password è sconosciuta

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

Verificare che i file di dati / var / lib / mysql siano di proprietà dell'utente mysql, in tal caso è possibile omettere il comando seguente:

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

Successivamente registra la posizione del binlog

ls -laF | grep mysql-bin

Vedrai qualcosa di simile

..
-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

Qui il file di registro principale è il numero di file più alto in sequenza e la posizione del registro bin è la dimensione del file. Registra questi valori:

master_log_file=mysql-bin.000020
master_log_post=65657162

Quindi avviare lo slave MySQL

service mysql start

Eseguire il comando change master sullo slave eseguendo quanto segue:

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 avvia lo schiavo

SLAVE START;

Controlla lo stato degli slave:

SHOW SLAVE STATUS;

Assicurarsi che Slave IO sia in esecuzione e che non vi siano errori di connessione. In bocca al lupo!

BR, Juha Vehnia

Di recente l'ho scritto sul mio blog che si trova qui ... Ci sono alcuni dettagli in più, ma la storia è la stessa.

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


0

Ho creato un repository GitHub con uno script per risolvere rapidamente questo problema. Basta cambiare un paio di variabili ed eseguirlo (in primo luogo, lo script crea un backup del database).

Spero che questo ti aiuti (e anche altre persone).

Come ripristinare (risincronizzare) la replica master-slave MySQL


Vedo che lo script imposta sempre la posizione del registro principale su 1 e il nome del file di registro principale. Non so abbastanza per essere sicuro che dovrei preoccuparmi di questo o no. Potresti spiegare? Attualmente ho una posizione di oltre 1.000.000. Questo significa che proverà a ripetere le query 1mil prima di mettersi al passo? Non ci sono possibilità di corruzione nel giocare quelle domande contro i dati esistenti? Mi chiedo perché non nello script quando si esegue un dump mysql utilizzare l'opzione --master-data = 2 e quindi estrarre il file e posare fuori dal dump per impostarli?
Josiah

0

Stiamo usando la tecnica di replica master-master di MySQL e se un server MySQL dice che 1 viene rimosso dalla rete, si riconnette dopo il ripristino della connessione e tutti i record che sono stati impegnati nel server 2 che era nella rete vengono trasferiti al server 1 che ha perso la connessione dopo il ripristino. Per impostazione predefinita, il thread slave nei tentativi di MySQL si connette al suo master ogni 60 secondi. Questa proprietà può essere modificata in quanto MySQL ha un flag "master_connect_retry = 5" dove 5 è in sec. Ciò significa che vogliamo riprovare ogni 5 secondi.

Ma devi assicurarti che il server che ha perso la connessione non mostri alcun commit nel database quando si ottiene un errore chiave duplicato Codice di errore: 1062


0

Maestro :

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

scp master:/tmp/dump.sql.gz slave:/tmp/ Sposta il file di dump sul server slave

Schiavo:

STOP SLAVE;

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

START SLAVE;
SHOW SLAVE STATUS;  

NOTA :
sul master è possibile eseguire SET GLOBAL expire_logs_days = 3per mantenere i binlog per 3 giorni in caso di problemi relativi agli slave.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.