El error de datos de una sola tabla del escenario de replicación maestro-esclavo de MySQL causa la terminación de la replicación cómo reparar rápidamente

Descripción de la escena:

Si los datos de la tabla t en la base de datos esclava no concuerdan con la base de datos maestra, lo que genera errores de replicación, toda la base de datos tiene una gran cantidad de datos y la rehacer la base de datos esclava es lenta. ¿Cómo recuperar los datos de esta tabla sola?
En general, se considera que es imposible reparar datos de una sola tabla, porque el estado de cada tabla es inconsistente.
A continuación, se enumeran los problemas y las soluciones que enfrentará la tabla única de respaldo cuando se restaure en la base de datos esclava.

1. Descripción del entorno de demostración:

Servidor físico Dell r620 Ambos
entornos de red son intranet
maestro: 192.168.1.220
esclavo: 192.168.1.217
Entorno del sistema operativo: centos7.8 X86_64 instalación mínima, cierre iptables, cierre selinux
versión del software de prueba: paquete binario mysql5.7.27 por
adelantado Configure la replicación maestro-esclavo de MySQL basada en Gtid para
crear datos de prueba simulados, simule escenarios de falla para
reparar la replicación maestro-esclavo de MySQL
pt-table-checksum, verifique si los datos de replicación maestro-esclavo de MySQL reparados son consistentes

Dos, configurar la replicación maestro-esclavo

El proceso de instalación de MySQL ya no se describe aquí, Baidu mismo

Para configurar la replicación maestro-esclavo
para configurar un nuevo esclavo para una máquina maestra, recuerde agregar el parámetro --set-gtid-purged = ON cuando mysqldump realiza una copia de seguridad de los datos.
Suplemento de conocimientos:
1. La copia de seguridad regular es agregar --set-gtid-purged = OFF resuelve la advertencia durante la copia de seguridad
[root @ localhost ~] # mysqldump -uroot -p'dXdjVF # (y3lt '--set-gtid-purged = OFF --single-transaction -A -B | gzip> 2020-09-17 .sql.gz
2. Para la copia de seguridad realizada al construir el maestro-esclavo, no es necesario agregar el parámetro --set-gtid-purged = OFF, sino que debe agregar --set-gtid-purged = ON
[root @ localhost ~] # mysqldump -uroot -p'dXdjVF # (y3lt '--set-gtid-purged = ON --single-transaction -A -B --master-data = 2 | gzip> 2020-09-17.sql.gz
indicador:
en Para crear una replicación maestro-esclavo, no la desactive. Durante la copia de seguridad diaria, puede desactivarla.
--Set-gtid-purged = AUTO, ON, OFF
1 .-- set-gtid-purged = OFF se puede usar en los parámetros de copia de seguridad diaria . 2
.-- = SET-GTID los parámetros purgados-oN necesarios para construir la copia maestra de la configuración del entorno

Los pasos específicos para configurar la replicación maestro-esclavo basada en Gtid son los siguientes:

biblioteca maestra:

 grant replication slave on *.* to rep@'192.168.1.217' identified by 'JuwoSdk21TbUser'; flush privileges;
 mysqldump -uroot -p'dXdjVF#(y3lt' --set-gtid-purged=ON --single-transaction -A -B --master-data=2 |gzip > 2020-09-20.sql.gz 

Operación de biblioteca esclava:

 [root@mysql02 ~]# mysql < 2020-09-17.sql 
 mysql>  change master to master_host='192.168.1.220',master_user='rep',master_password='JuwoSdk21TbUser',MASTER_AUTO_POSITION = 1;start slave;show slave status\G
ERROR 29 (HY000): File '/data1/mysql/3306/relaylog/relay-bin.index' not found (Errcode: 2 - No such file or directory)
ERROR 29 (HY000): File '/data1/mysql/3306/relaylog/relay-bin.index' not found (Errcode: 2 - No such file or directory)
Empty set (0.00 sec)

La razón es que la ruta de almacenamiento del registro de retransmisión está configurada en la configuración de la máquina esclava my.cnf, pero la ruta no existe en el servidor esclavo y se informa un error. Cree el directorio, autorice el permiso de mysql y luego cambie el maestro nuevamente

mkdir -p /data1/mysql/3306/relaylog/
cd /data1/mysql/3306/
chown -R mysql.mysql relaylog
mysql> change master to master_host='192.168.1.220',master_user='rep',master_password='JuwoSdk21TbUser',MASTER_AUTO_POSITION = 1;start slave;show slave status\G

La configuración de la replicación maestro-esclavo está completa.

3. Preparar datos de prueba y simular fallas

Cree una tabla de demostración de simulación en la biblioteca maestra, tenga temporizadores y procedimientos almacenados, y escriba datos en la tabla de prueba con regularidad para facilitar la creación de la tabla de prueba para la siguiente demostración de recuperación de fallas de replicación maestro-esclavo
:

 CREATE TABLE `test_event` (
`id` int(8) NOT NULL AUTO_INCREMENT, 
`username` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
`password` varchar(20) COLLATE utf8_unicode_ci NOT NULL, 
`create_time` varchar(20) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`) #主键ID
) ENGINE=innodb AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

Cree un temporizador y escriba un dato cada segundo después de 1 minuto desde la hora actual:

delimiter $$
create event event_2 
on schedule every 1 second STARTS   CURRENT_TIMESTAMP + INTERVAL 1 MINUTE
COMMENT 'xiaowu create'
do 
    BEGIN
           insert into test_event(username,password,create_time) values("李四","tomcat",now());
    END $$
delimiter ;

Cree una nueva tabla de prueba txt similar al método anterior, escriba datos regularmente

Fallo de simulación de biblioteca esclava:


 insert into test_event(username,password,create_time) values("李四","tomcat",now());
 insert into test_event(username,password,create_time) values("李四","tomcat",now());
 delete from txt where id=200;

Luego elimine el registro con id = 200 en la biblioteca
maestra Operación maestra: eliminar de txt donde id = 200;

En este momento, la biblioteca esclava verifica el estado de la replicación y ha detenido la replicación:

[root@mysql02 ~]#  mysql -e "show slave status\G"|grep -A 1 'Last_SQL_Errno'
               Last_SQL_Errno: 1062
               Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '8a9fb9a3-f579-11ea-830d-90b11c12779c:42083' at master log mysql-bin.000001, end_log_pos 18053730. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

Cuatro, recuperación de fallas

escena 1

Si se informa del error de replicación, la replicación maestro-esclavo no se ha reparado mediante métodos como omitir errores y filtrado de replicación. Los datos de la base de datos maestra se han actualizado y los datos de la base de datos esclava están bloqueados en un estado de error (asumiendo que el GTID es 8a9fb9a3-f579-11ea-830d-90b11c12779c: 1-42083).
Pasos de reparación:
tabla de respaldo test_event en la base de datos maestra (asumiendo que la instantánea de respaldo GTID es 8a9fb9a3-f579-11ea-830d-90b11c12779c: 1-42262);
restaurar a la base de datos esclava;
iniciar la replicación.
El problema aquí es que la posición de inicio de la replicación es 8a9fb9a3-f579-11ea-830d-90b11c12779c: 42084, y el estado de los datos de la tabla test_event de la biblioteca está por delante de otras tablas.
8a9fb9a3-f579-11ea-830d-90b11c12779c: 42084-42262 En estas transacciones, siempre que haya una transacción que modifique los datos de la tabla test_event, provocará errores de replicación, como conflictos de claves primarias y no existencia de registros (mientras que 8a9fb9a3-f579-11ea-8c12d779c11: 1-42084, la transacción que informó el error de replicación anterior debe ser la transacción que modificó la tabla t)
Solución: omita 8a9fb9a3-f579-11ea-830d-90b11c12779c: 42084-42262 en estas transacciones que modifican la tabla t al iniciar la replicación.

Los pasos correctos de reparación:

  1. Haga una copia de seguridad de la tabla test_event en la base de datos maestra (la instantánea de copia de seguridad GTID es 8a9fb9a3-f579-11ea-830d-90b11c12779c: 1-42262) y restáurela a la base de datos esclava;
  2. Establecer filtro de replicación, tabla de filtros t:
    CAMBIAR FILTRO DE REPLICACIÓN REPLICATE_WILD_IGNORE_TABLE = ('dbtest01.test_event');
  3. Comience a copiar y detenga la copia cuando la reproducción alcance 8a9fb9a3-f579-11ea-830d-90b11c12779c: 1-42262 (los datos de todas las tablas de la biblioteca esclava están en el mismo estado en este momento, lo que es coherente);
    START SLAVE HASTA SQL_AFTER_GTIDS = '8a9fb9a3-f579 -11ea-830d-90b11c12779c: 1-42262 ';
  4. Elimine el filtro de replicación e inicie la replicación normalmente.
    Nota: Use mysqldump --single-transaction --master-data = 2 aquí para registrar el GTID correspondiente a la instantánea de respaldo

Los pasos detallados son los siguientes:

A. Para volcar la tabla test_event que provocó que la replicación se detuviera en la biblioteca maestra:

mysqldump -uroot -p'dXdjVF#(y3lt'  --single-transaction dbtest01 test_event --master-data=2 |gzip >$(date +%F).test_event.sql.gz
[root@localhost ~]# mysqldump -uroot -p'dXdjVF#(y3lt'  --single-transaction dbtest01 test_event --master-data=2 |gzip >$(date +%F).test_event.sql.gz
mysqldump: [Warning] Using a password on the command line interface can be insecure.
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events. 

B. Obtenga el valor gtid de la instantánea de una tabla de respaldo separada:

8a9fb9a3-f579-11ea-830d-90b11c12779c: 1-42262

[root@mysql02 ~]# gzip -d 2020-09-17.test_event.sql.gz
[root@mysql02 ~]# grep -A6 'GLOBAL.GTID_PURGED' 2020-09-17.test_event.sql 
SET @@GLOBAL.GTID_PURGED='8a9fb9a3-f579-11ea-830d-90b11c12779c:1-42262';
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=18130552;

C. Restaure esta tabla a la biblioteca esclava. Debido a que GTID_EXECUTED no es un valor nulo, no puede importar la tabla test_event a la biblioteca esclava. El error específico es el siguiente:
Operación de la biblioteca esclava :

[root@mysql02 ~]#  mysql dbtest01 < 2020-09-17.test_event.sql 
ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.

 mysql> select  @@GLOBAL.GTID_EXECUTED;
+----------------------------------------------------------------------------------------+
| @@GLOBAL.GTID_EXECUTED                                                                 |
+----------------------------------------------------------------------------------------+
| 5ec577a4-f401-11ea-bf6d-14187756553d:1-2,
8a9fb9a3-f579-11ea-830d-90b11c12779c:1-42082 |
+----------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 368620
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 5ec577a4-f401-11ea-bf6d-14187756553d:1-2,
8a9fb9a3-f579-11ea-830d-90b11c12779c:1-42082
1 row in set (0.00 sec)

La solución es iniciar sesión en la biblioteca esclava:
mysql> reset master;
esta operación puede vaciar el valor GTID_EXECUTED de la biblioteca actual

[root@mysql02 ~]#  mysql dbtest01 < 2020-09-17.test_event.sql 

mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000001
         Position: 154
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 8a9fb9a3-f579-11ea-830d-90b11c12779c:1-42262
1 row in set (0.00 sec)

D. Abrir filtro de copia en línea:

mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ('db_name.test_event');
Query OK, 0 rows affected (0.00 sec)

[root@mysql02 ~]# mysql -e "show slave status\G"|egrep 'db_name.test_event'
  Replicate_Wild_Ignore_Table: db_name.test_event

E. Comience a copiar y deje de copiar cuando reproduzca a 8a9fb9a3-f579-11ea-830d-90b11c12779c: 42262 (En este momento, los datos de todas las tablas de la biblioteca secundaria están en el mismo estado y son coherentes)

mysql> START SLAVE UNTIL SQL_AFTER_GTIDS ='8a9fb9a3-f579-11ea-830d-90b11c12779c:42262';
Query OK, 0 rows affected, 1 warning (0.03 sec)

mysql> 

Aunque el hilo de SQL no es en este momento, la replicación ya no informa un error:

[root@mysql02 ~]# mysql -e "show slave status\G"|egrep 'Last_SQL_Error|Slave_IO|Slave_SQL'
               Slave_IO_State: Waiting for master to send event
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
               Last_SQL_Error: 

F. Desactive el filtrado de replicación en línea:

mysql> CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE = ();
Query OK, 0 rows affected (0.00 sec)

mysql> 
[root@mysql02 ~]# mysql -e "show slave status\G"|egrep 'db_name.test_event|IO_Running|SQL_Running'
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
      Slave_SQL_Running_State: 

G. Inicie el hilo SQL de replicación esclava:


mysql> start slave sql_thread;
Query OK, 0 rows affected (0.04 sec)

Recuperación de la replicación maestro-esclavo:

[root@mysql02 ~]# mysql -e "show slave status\G"|egrep 'IO_Running|SQL_Running'
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates

Nota: Use mysqldump --single-transaction --master-data = 2 aquí para registrar el GTID correspondiente a la instantánea de respaldo

Cinco, verificar la consistencia de los datos maestro-esclavo

Utilice la herramienta de verificación pt-table-checksum para verificar. Para obtener detalles sobre cómo instalar y usar, consulte la siguiente dirección de publicación de blog:
https://blog.51cto.com/wujianwei/2409523


[root@localhost bin]# time /usr/local/percona-toolkit/bin/pt-table-checksum h=192.168.1.220,u=ptsum,p='ptchecksums',P=3306 --ignore-databases sys,mysql  --truncate-replicate-table  --replicate=percona.ptchecksums --no-check-binlog-format --nocheck-replication-filters --recursion-method="processlist"   2>&1 | tee 2020-09-18-pt-checksum.log

Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
09-18T07:49:09      0      0     9739          0       4       0   0.747 dbtest01.hlz_ad
09-18T07:49:10      0      0    64143          0       4       0   0.968 dbtest01.hlz_ad_step
09-18T07:49:16      0      0   741424          0      10       0   6.014 dbtest01.hlz_bubble
09-18T07:49:18      0      0   499991          0       5       0   1.610 dbtest01.test01
09-18T07:49:25      0      0  3532986          0      13       0   7.802 dbtest01.test02
09-18T07:49:26      0      0   126863          0       1       0   0.976 dbtest01.test_event
09-18T07:49:27      0      1    30294          0       1       0   0.582 test01.txt

real    1m22.725s
user    0m0.387s
sys 0m0.078s

Se encuentra que la tabla test01.txt en la biblioteca principal es inconsistente con test01.txt en el esclavo.

La razón es: Justo ahora en la demostración de la simulación, la acción de
eliminar eliminar de txt donde id = 200 se ejecutó en la biblioteca esclava ; resultando en un registro menos en la tabla de la biblioteca esclava txt que en la tabla txt de la biblioteca maestra

Datos de reparación:

[root@localhost bin]# /usr/local/percona-toolkit/bin/pt-table-sync h=192.168.1.220,u=ptsum,p=ptchecksums,P=3306 --databases=test01 --tables=test01.txt  --replicate=percona.ptchecksums  --charset=utf8  --transaction --execute

Verifique nuevamente, los datos son consistentes


[root@localhost bin]# time /usr/local/percona-toolkit/bin/pt-table-checksum h=192.168.1.220,u=ptsum,p='ptchecksums',P=3306 --ignore-databases sys,mysql  --truncate-replicate-table  --replicate=percona.ptchecksums --no-check-binlog-format --nocheck-replication-filters --recursion-method="processlist"   2>&1 | tee 2020-09-18-pt-checksum.log
Checking if all tables can be checksummed ...
Starting checksum ...
            TS ERRORS  DIFFS     ROWS  DIFF_ROWS  CHUNKS SKIPPED    TIME TABLE
09-18T09:48:10      0      0     9739          0       4       0   0.784 dbtest01.hlz_ad
09-18T09:48:11      0      0    64143          0       4       0   0.995 dbtest01.hlz_ad_step
09-18T09:48:16      0      0   741424          0       9       0   4.224 dbtest01.hlz_bubble
09-18T09:48:17      0      0   499991          0       5       0   1.470 dbtest01.test01
09-18T09:48:24      0      0  3532986          0      13       0   6.403 dbtest01.test02
09-18T09:48:24      0      0   133999          0       1       0   0.894 dbtest01.test_event
09-18T09:48:25      0      0    37431          0       1       0   0.511 test01.txt

real    0m15.676s
user    0m0.359s
sys 0m0.055s

Seis, con un total de casos de prueba de internautas

Se adjunta el caso 2, que es básicamente igual que la escena 1. No entraré en detalles aquí y se lo dejo a los internautas interesados.
A continuación, se describen brevemente los escenarios y los métodos de recuperación:

Si se informa del error de replicación, la replicación maestro-esclavo se puede reparar utilizando métodos como omitir errores y filtrado de replicación. Los datos del maestro y del esclavo se actualizan constantemente.
Pasos para la reparación de errores:
tabla de respaldo t en la base de datos maestra (asumiendo que la instantánea de respaldo GTID es aaaa: 1-10000);
detener la copia de la base de datos, GTID es aaaa: 1-20000;
restaurar la tabla t en la base de datos esclava;
iniciar la replicación.

Análisis de la razón:
el problema aquí es que la posición de inicio de la replicación es aaaa: 20001, aaaa: 10000-20000. Estas transacciones no se reproducirán en la biblioteca esclava. Si hay una transacción que modifica los datos de la tabla t, la biblioteca esclava perderá esta transacción. parte de los datos

Solución: desde el inicio de la copia de seguridad hasta el inicio de la replicación, bloquee la tabla t para asegurarse de que no haya transacciones que modifiquen la tabla t en aaaa: 10000-20000.

Pasos correctos de reparación:

Agregue un bloqueo de lectura a
la tabla de la biblioteca principal t; tabla de respaldo t en la biblioteca principal;
deje de copiar de la biblioteca y restaure la tabla t;
comience a copiar;
desbloquee la tabla t.

Solución sugerida: si no desea bloquear la tabla t, puede suspender directamente la copia de la biblioteca y luego usar el escenario uno para reanudar. Esto evita bloquear la mesa.

Supongo que te gusta

Origin blog.51cto.com/wujianwei/2535067
Recomendado
Clasificación