¿Cómo volver a sincronizar la base de datos Mysql si el maestro y el esclavo tienen una base de datos diferente en caso de replicación Mysql?

139

Mysql se Server1está ejecutando como MAESTRO .
Mysql se Server2está ejecutando como ESCLAVO .

Ahora la replicación de DB está sucediendo de MASTER a SLAVE .

Server2se elimina de la red y se vuelve a conectar después de 1 día. Después de esto, no hay coincidencia en la base de datos en maestro y esclavo.

¿Cómo volver a sincronizar la base de datos nuevamente ya que después de restaurar la base de datos tomada de Maestro a Esclavo tampoco resuelve el problema?

Indu Sharma
fuente

Respuestas:

287

Este es el procedimiento completo paso a paso para volver a sincronizar una replicación maestro-esclavo desde cero:

En el maestro:

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

Y copie los valores del resultado del último comando en alguna parte.

Sin cerrar la conexión con el cliente (porque liberaría el bloqueo de lectura) emita el comando para obtener un volcado del maestro:

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

Ahora puede liberar el bloqueo, incluso si el volcado aún no ha terminado. Para hacerlo, ejecute el siguiente comando en el cliente MySQL:

UNLOCK TABLES;

Ahora copie el archivo de volcado al esclavo usando scp o su herramienta preferida.

En el esclavo:

Abra una conexión a mysql y escriba:

STOP SLAVE;

Cargue el volcado de datos del maestro con este comando de consola:

mysql -uroot -p < mysqldump.sql

Sincronizar registros esclavos y maestros:

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

Donde los valores de los campos anteriores son los que copió antes.

Por último, escriba:

START SLAVE;

Para verificar que todo vuelva a funcionar, después de escribir:

SHOW SLAVE STATUS;

deberías ver:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

¡Eso es!

David Espart
fuente
8
Con INNODB tipeado dabatase y otros tipos de columnas complejas como BLOB y DATE definidos, recomiendo usar los siguientes interruptores:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Ken Pega
44
Es RESET_SLAVEnecesario? Tenga en cuenta que estas instrucciones al usuario restablecer la replicación y la contraseña, por lo que tendrá que volver a introducir aquellos conCHANGE MASTER TO...
Mike S.
25
Si usa el indicador --master-data cuando llama a mysqldump en el maestro, el comando CHANGE MASTER TO se escribe en el archivo de volcado y, por lo tanto, guarda el paso de ejecutarlo después de importar el archivo de volcado en el esclavo.
udog
3
No bloquear el maestro (no requiere Percona) plusbryan.com/mysql-replication-without-downtime Otra ventaja de esto es que el volcado de SQL también viene con la línea necesaria "CHANGE MASTER" (comentado)
mahemoff
2
Hay alguna manera de automatizar esto?
Metafaniel
26

La documentación para esto en el sitio MySQL está lamentablemente desactualizada y plagada de pistolas (como interactive_timeout). Emitir FLUSH TABLES CON READ LOCK como parte de su exportación del maestro generalmente solo tiene sentido cuando se coordina con una instantánea de almacenamiento / sistema de archivos como LVM o zfs.

Si va a usar mysqldump, debe confiar en la opción --master-data para protegerse contra errores humanos y liberar los bloqueos en el maestro lo más rápido posible.

Suponga que el maestro es 192.168.100.50 y el esclavo es 192.168.100.51, cada servidor tiene una identificación de servidor distinta configurada, el maestro tiene un inicio de sesión binario y el esclavo tiene solo lectura = 1 en my.cnf

Para organizar el esclavo para poder iniciar la replicación justo después de importar el volcado, emita un comando CHANGE MASTER pero omita el nombre y la posición del archivo de registro:

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

Emita el GRANT en el maestro para que lo use el esclavo:

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

Exporte el maestro (en pantalla) usando compresión y capturando automáticamente las coordenadas binarias correctas del registro:

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

Copie el archivo replication.sql.gz al esclavo y luego impórtelo con zcat a la instancia de MySQL que se ejecuta en el esclavo:

zcat replication.sql.gz | mysql

Inicie la replicación emitiendo el comando al esclavo:

slaveserver> START SLAVE;

Opcionalmente, actualice el /root/.my.cnf en el esclavo para almacenar la misma contraseña de root que el maestro.

Si tiene 5.1+, lo mejor es configurar primero el binlog_format del maestro en MIXED o ROW. Tenga en cuenta que los eventos registrados en la fila son lentos para las tablas que carecen de una clave principal. Esto suele ser mejor que la configuración alternativa (y predeterminada) de binlog_format = instrucción (en el maestro), ya que es menos probable que produzca datos incorrectos en el esclavo.

Si debe (pero probablemente no debería) filtrar la replicación, hágalo con las opciones de esclavo replicate-wild-do-table = dbname.% O replicate-wild-ignore-table = badDB.% Y use solo binlog_format = row

Este proceso mantendrá un bloqueo global en el maestro durante la duración del comando mysqldump, pero de lo contrario no afectará al maestro.

Si tiene la tentación de usar mysqldump --master-data --all-bases de datos --solo-transacción (porque solo usa tablas InnoDB), quizás sea mejor usar MySQL Enterprise Backup o la implementación de código abierto llamada xtrabackup (cortesía de Percona)

Anticuado
fuente
3
Si simplemente desea reconstruir un esclavo existente, puede seguir el proceso anterior, omitiendo un par de pasos: El comando GRANT y el comando CAMBIAR MAESTRO manual
desactualizado el
Pregunta 1: En Windows, ¿cuál sería un equivalente de zcat. Pregunta 2: ¿Cómo funciona esto mysqldumpcon grandes bases de datos en términos de rendimiento? ¿Alguna forma de usar SELECT INTO OUTFILEy LOAD DATAsin problemas en su proceso sugerido? (Dado que generalmente se desempeñan más rápido)
Ifedi Okonkwo
No hay necesidad de STOP SLAVEalgún lugar en el proceso?
David V.
16

A menos que esté escribiendo directamente en el esclavo (Servidor2), el único problema debería ser que al Servidor2 le faltan las actualizaciones que ocurrieron desde que se desconectó. Simplemente reiniciando el esclavo con "START SLAVE"; debería volver a poner todo al día.

malonso
fuente
2
Puede verificar los registros de bin y ver si cubren el período de tiempo en que su sistema no estaba sincronizado. Si faltan días, este podría ser un problema mayor y requerir que realice un volcado completo para restaurar los datos faltantes.
nelaaro
7

Creo que Maatkit utilits te ayuda. Puede usar mk-table-sync. Consulte este enlace: http://www.maatkit.org/doc/mk-table-sync.html

Menor
fuente
Creo que necesitará detener temporalmente las escrituras mientras ejecuta el script.
Ztyx
Esto todavía funciona muy bien. Sin embargo, las herramientas han cambiado de nombre y ahora se llama pt-table-sync. En realidad, sin embargo, descubrí que su herramienta pt-slave-restart funciona como magia.
mlerley
7

Llegué muy tarde a esta pregunta, sin embargo, encontré este problema y, después de mucho buscar, encontré esta información de Bryan Kennedy: http://plusbryan.com/mysql-replication-without-downtime

En Master, realice una copia de seguridad como esta:
mysqldump --skip-lock-tables --single-transacción --flush-logs --hex-blob --master-data = 2 -A> ~ / dump.sql

Ahora, examine el encabezado del archivo y anote los valores para MASTER_LOG_FILE y MASTER_LOG_POS. Los necesitará más tarde: head dump.sql -n80 | grep "MASTER_LOG"

Copie el archivo "dump.sql" en Slave y restaúrelo: mysql -u mysql-user -p <~ / dump.sql

Conéctese a Slave mysql y ejecute un comando como este: CAMBIAR 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 desde arriba; INICIAR ESCLAVO;

Para verificar el progreso de Slave: MOSTRAR ESTADO DE ESCLAVO;

Si todo está bien, Last_Error estará en blanco y Slave_IO_State informará "Esperando que el maestro envíe el evento". Busque Seconds_Behind_Master que indica qué tan atrás está. YMMV. :)

Jeffery7
fuente
3
Esto funciona, y si el esclavo ya está configurado y solo se desincronizó, no necesita ejecutar CHANGE MASTER; solo especifique --master-data=1(o simplemente --master-data).
LSerni
5

Esto es lo que normalmente hago cuando un esclavo mysql se desincroniza. He mirado mk-table-sync pero pensé que la sección de Riesgos tenía un aspecto aterrador.

En el maestro:

SHOW MASTER STATUS

Las columnas de salida (Archivo, Posición) nos serán de utilidad en un momento.

En esclavo:

STOP SLAVE

Luego volcar el db maestro e importarlo al db esclavo.

Luego ejecute lo siguiente:

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

Donde [Archivo] y [Posición] son ​​los valores emitidos desde "SHOW MASTER STATUS" que se ejecutó anteriormente.

¡Espero que esto ayude!

Bryson
fuente
55
Esto parece roto, ya que aparentemente no lo haces FLUSH TABLES WITH READ LOCK;antes SHOW MASTER STATUSy vuelcas la base de datos maestra. Creo que esto podría dar lugar, por ejemplo, a errores de clave duplicados en el esclavo, ya que establece efectivamente el estado maestro en un punto en el tiempo antes de que se realizara el volcado, por lo que volverá a reproducir el historial que ya está incluido en el volcado. (Si haces las cosas en el orden que describiste).
KajMagnus
5

Continuando con la respuesta de David ...

El uso SHOW SLAVE STATUS\Gdará resultados legibles por humanos.

Greg Ackerson
fuente
¿Alguna forma de paginar la salida?
Josiah
'busca más' Creo que lo hará
Ian
3

a veces solo necesitas darle una patada al esclavo también

tratar

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

bastante a menudo, esclavos, simplemente se quedan atrapados chicos :)

El codificador de locura enmascarado
fuente
... y monitor Positionen el maestro usando show master status;contra Exec_Master_Log_Pos:en el esclavo usando show slave status \G. El esclavo debe alcanzar al maestro. Trabajó para mí usando mysql 5.6 justo ahora después de una corta interrupción de la red.
Mike S
10
Esto es engañoso, una vez que reinicia el esclavo, el ungüento perdió totalmente el conocimiento sobre dónde está el maestro.
Qian Chen
2

Aquí hay una respuesta completa que con suerte ayudará a otros ...


Quiero configurar la replicación mysql usando maestro y esclavo, y dado que lo único que sabía era que usa archivos de registro para sincronizar, si el esclavo se desconecta y se desincroniza, en teoría solo debería conectarse nuevamente a su maestro y siga leyendo el archivo de registro desde donde lo dejó, como mencionó el usuario malonso.

Así que aquí están los resultados de la prueba después de configurar el maestro y el esclavo como se menciona en: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

Siempre que use la configuración maestra / esclava recomendada y no escriba al esclavo, él y yo estamos en lo correcto (en lo que respecta a mysql-server 5.x). Ni siquiera necesitaba usar "START SLAVE;", simplemente alcanzó a su maestro. Pero hay un 88000 predeterminado que vuelve a intentar cada 60 segundos, así que supongo que si agota, es posible que deba iniciar o reiniciar el esclavo. De todos modos, para aquellos como yo que querían saber si tener un esclavo desconectado y volver a realizar una copia de seguridad requiere intervención manual ... no, no lo hace.

¿Quizás el póster original tenía corrupción en los archivos de registro? Pero lo más probable es que no sea solo un servidor que se desconecta por un día.


extraído de /usr/share/doc/mysql-server-5.1/README.Debian.gz que probablemente también tenga sentido para servidores que no sean de Debian:

* NOTAS ADICIONALES SOBRE LA REPLICACIÓN
===============================
Si el servidor MySQL está actuando como un esclavo de replicación, no debe
establezca --tmpdir para apuntar a un directorio en un sistema de archivos basado en memoria o para
un directorio que se borra cuando se reinicia el host del servidor. Una replica
El esclavo necesita algunos de sus archivos temporales para sobrevivir al reinicio de la máquina.
que puede replicar tablas temporales u operaciones LOAD DATA INFILE. Si
los archivos en el directorio de archivos temporales se pierden cuando el servidor se reinicia,
La replicación falla.

puedes usar algo como sql: muestra variables como 'tmpdir'; descubrir.

bksunday
fuente
¿Se sincronizarán ambas bases de datos automáticamente entre sí? Por ejemplo, escribo a Master, ¿Slave se actualizará automáticamente?
TransformBinary
2

Agregando a la respuesta popular para incluir este error:

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

Replicación de esclavo en un disparo:

En una ventana de terminal:

mysql -h <Master_IP_Address> -uroot -p

Después de conectar

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

El estado aparece como a continuación: ¡Tenga en cuenta que el número de posición varía!

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

¡Exporte el volcado de forma similar a como describió " usar otro terminal "!

Salga y conéctese a su propio DB (que es el esclavo):

mysql -u root -p

El tipo de los siguientes comandos:

STOP SLAVE;

Importe el volcado como se mencionó (¡en otra terminal, por supuesto!) Y escriba los siguientes comandos:

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 vez registrado, establezca el parámetro server_id (generalmente, para bases de datos nuevas / no replicadas, esto no se establece de manera predeterminada),

set global server_id=4000;

Ahora, comienza el esclavo.

START SLAVE;
SHOW SLAVE STATUS\G;

El resultado debe ser el mismo que él describió.

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

Nota: ¡Una vez replicados, el maestro y el esclavo comparten la misma contraseña!

curlyreggie
fuente
¿Se sincronizarán ambas bases de datos automáticamente entre sí? Por ejemplo, escribo a Master, ¿Slave se actualizará automáticamente?
TransformBinary
1

Reconstruyendo el esclavo usando LVM

Aquí está el método que usamos para reconstruir esclavos MySQL usando Linux LVM. Esto garantiza una instantánea consistente al tiempo que requiere un tiempo de inactividad mínimo en su maestro.

Establezca el porcentaje máximo de páginas sucias innodb en cero en el servidor MySQL maestro. Esto obligará a MySQL a escribir todas las páginas en el disco, lo que acelerará significativamente el reinicio.

set global innodb_max_dirty_pages_pct = 0;

Para controlar la cantidad de páginas sucias, ejecute el comando

mysqladmin ext -i10 | grep dirty

Una vez que el número deja de disminuir, has alcanzado el punto para continuar. A continuación, restablezca el maestro para borrar los registros de bin / registros de retransmisión antiguos:

RESET MASTER;

Ejecute lvdisplay para obtener la ruta LV

lvdisplay

La salida se verá así

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

Apague la base de datos maestra con el comando

service mysql stop

A continuación, tome una instantánea, mysql_snapshot será el nuevo nombre de volumen lógico. Si los binlogs se colocan en la unidad del sistema operativo, también deben ser instantáneas.

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

Iniciar maestro nuevamente con comando

service mysql start

Restaurar la configuración de páginas sucias al valor predeterminado

set global innodb_max_dirty_pages_pct = 75;

Ejecute lvdisplay nuevamente para asegurarse de que la instantánea esté allí y sea visible

lvdisplay

Salida:

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

Monta la instantánea

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

Si tiene un esclavo MySQL en ejecución, debe detenerlo

service mysql stop

A continuación, debe borrar la carpeta de datos MySQL

cd /var/lib/mysql
rm -fr *

De vuelta al maestro. Ahora sincronice la instantánea con el esclavo MySQL

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

Una vez que rsync se haya completado, puede desmontar y eliminar la instantánea

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

Cree un usuario de replicación en el maestro si el antiguo usuario de replicación no existe o la contraseña es desconocida

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

Verifique que los archivos de datos / var / lib / mysql son propiedad del usuario mysql, de ser así, puede omitir el siguiente comando:

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

Luego registre la posición del binlog

ls -laF | grep mysql-bin

Verás 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

Aquí el archivo de registro maestro es el número de archivo más alto en secuencia y la posición del registro de bin es el tamaño del archivo. Registre estos valores:

master_log_file=mysql-bin.000020
master_log_post=65657162

A continuación, inicie el esclavo MySQL

service mysql start

Ejecute el comando cambiar maestro en el esclavo ejecutando lo siguiente:

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 comienza el esclavo

SLAVE START;

Verifique el estado del esclavo:

SHOW SLAVE STATUS;

Asegúrese de que Slave IO se esté ejecutando y que no haya errores de conexión. ¡Buena suerte!

BR, Juha Vehnia

Recientemente escribí esto en mi blog que se encuentra aquí ... Hay pocos detalles más allí, pero la historia es la misma.

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

Juha Vehnia
fuente
0

Creé un repositorio de GitHub con un script para resolver este problema rápidamente. Simplemente cambie un par de variables y ejecútelo (Primero, el script crea una copia de seguridad de su base de datos).

Espero que esto te ayude (y a otras personas también).

Cómo restablecer (volver a sincronizar) MySQL Master-Slave Replication

MCurbelo
fuente
Veo que el script siempre establece la posición del registro maestro en 1 y el nombre del archivo de registro maestro. No sé lo suficiente como para estar seguro de si debería preocuparme por esto o no. ¿Podrías explicar? Tengo una posición de más de 1,000,000 actualmente. ¿Significa esto que intentará reproducir consultas de 1mil antes de ponerse al día? ¿No hay posibilidades de corrupción al reproducir esas consultas con los datos existentes? Me pregunto por qué no en el script al hacer un volcado de mysql, use la opción --master-data = 2 y luego extraiga el archivo y pos fuera del volcado para configurarlos.
Josiah
0

Estamos utilizando la técnica de replicación maestro-maestro de MySQL y si un servidor MySQL dice que 1 se elimina de la red, se vuelve a conectar después de que se restablezca la conexión y se transfieran todos los registros que se confirmaron en el servidor 2 que estaba en la red al servidor 1 que ha perdido la conexión después de la restauración. El subproceso esclavo en MySQL vuelve a intentar conectarse a su maestro después de cada 60 segundos de forma predeterminada. Esta propiedad se puede cambiar ya que MySQL tiene un indicador "master_connect_retry = 5" donde 5 está en segundos. Esto significa que queremos volver a intentarlo cada 5 segundos.

Pero debe asegurarse de que el servidor que perdió la conexión muestre que no realiza ninguna confirmación en la base de datos cuando obtiene duplicado Error de clave Código de error: 1062

parag gupta
fuente
0

maestro :

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

scp master:/tmp/dump.sql.gz slave:/tmp/ Mover el archivo de volcado al servidor esclavo

Esclavo:

STOP SLAVE;

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

START SLAVE;
SHOW SLAVE STATUS;  

NOTA :
En el maestro, puede ejecutar SET GLOBAL expire_logs_days = 3para mantener binlogs durante 3 días en caso de problemas de esclavos.

M Rostami
fuente