Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie erstelle ich einen inkonsistenten MySQL-Slave neu?

MySQL-Slaves können inkonsistent werden. Sie können versuchen, es zu vermeiden, aber es ist wirklich schwierig. Das Festlegen von super_read_only und die Verwendung der zeilenbasierten Replikation können sehr hilfreich sein, aber egal, was Sie tun, es ist immer noch möglich, dass Ihr Slave inkonsistent wird.

Was kann getan werden, um einen inkonsistenten MySQL-Slave wieder aufzubauen? In diesem Blogbeitrag werden wir uns dieses Problem ansehen.

Lassen Sie uns zunächst besprechen, was passieren muss, um einen Sklaven wieder aufzubauen. Um einen Knoten in die MySQL-Replikation zu bringen, muss er mit Daten von einem der Knoten in der Replikationstopologie versorgt werden. Diese Daten müssen zum Zeitpunkt ihrer Erhebung konsistent sein. Sie können es nicht auf einer Tabelle-für-Tabelle- oder Schema-für-Schema-Basis nehmen, da dies den bereitgestellten Knoten intern inkonsistent machen würde. Das heißt, einige Daten wären älter als ein anderer Teil des Datensatzes.

Neben der Datenkonsistenz sollte es auch möglich sein, Informationen über die Beziehung zwischen den Daten und dem Stand der Replikation zu sammeln. Sie möchten entweder die Binärlog-Position haben, an der die gesammelten Daten konsistent sind, oder die globale Transaktions-ID der Transaktion, die zuletzt auf dem Knoten ausgeführt wurde, der die Quelle der Daten ist.

Das führt uns zu folgenden Überlegungen. Sie können einen Slave mit einem beliebigen Backup-Tool neu erstellen, solange dieses Tool konsistente Backups erstellen kann und Replikationskoordinaten für den Zeitpunkt enthält, zu dem das Backup konsistent ist. Dadurch können wir aus mehreren Optionen auswählen.

Mysqldump verwenden, um einen inkonsistenten MySQL-Slave neu aufzubauen

Mysqldump ist das grundlegendste Werkzeug, das wir haben, um dies zu erreichen. Es ermöglicht uns, eine logische Sicherung unter anderem in Form von SQL-Anweisungen zu erstellen. Was wichtig ist, obwohl es einfach ist, ermöglicht es uns dennoch, ein konsistentes Backup zu erstellen:Es kann Transaktionen verwenden, um sicherzustellen, dass die Daten zu Beginn der Transaktion konsistent sind. Es kann auch die Replikationskoordinaten für diesen Punkt aufschreiben, sogar eine ganze CHANGE MASTER-Anweisung, was es einfach macht, die Replikation unter Verwendung der Sicherung zu starten.

Mit Mydumper einen inkonsistenten MySQL-Slave neu erstellen

Eine weitere Möglichkeit ist die Verwendung von mydumper - dieses Tool erstellt, genau wie mysqldump, ein logisches Backup und kann, genau wie mysqldump, verwendet werden, um ein konsistentes Backup der Datenbank zu erstellen. Der Hauptunterschied zwischen mydumper und mysqldump besteht darin, dass mydumper, wenn es mit myloader gekoppelt ist, Daten parallel ausgeben und wiederherstellen kann, wodurch der Auszug und insbesondere die Wiederherstellungszeit verbessert werden.

Einen Snapshot verwenden, um einen inkonsistenten MySQL-Slave neu aufzubauen

Für diejenigen, die Cloud-Anbieter verwenden, besteht die Möglichkeit, einen Snapshot des zugrunde liegenden Blockspeichers zu erstellen. Snapshots erzeugen eine Point-in-Time-Ansicht der Daten. Dieser Prozess ist jedoch ziemlich knifflig, da die Konsistenz der Daten und die Fähigkeit, sie wiederherzustellen, hauptsächlich von der MySQL-Konfiguration abhängt.

Sie sollten sicherstellen, dass die Datenbank in einem dauerhaften Modus arbeitet (sie ist so konfiguriert, dass ein Absturz von MySQL nicht zu Datenverlust führt). Dies liegt daran, dass (aus MySQL-Sicht) das Erstellen eines Datei-Überblicks und das anschließende Starten einer weiteren MySQL-Instanz mit den darin gespeicherten Daten im Grunde der gleiche Vorgang ist, als ob Sie mysqld mit -9 beenden und dann erneut starten würden. Die InnoDB-Wiederherstellung muss stattfinden, Transaktionen wiedergeben, die in Binärprotokollen gespeichert wurden, Transaktionen zurücksetzen, die vor dem Absturz nicht abgeschlossen wurden, und so weiter.

Der Nachteil des Snapshot-basierten Wiederherstellungsprozesses ist, dass er stark an den aktuellen Anbieter gebunden ist. Sie können die Snapshot-Daten nicht einfach von einem Cloud-Anbieter zu einem anderen kopieren. Sie können es möglicherweise zwischen verschiedenen Regionen verschieben, aber es wird immer noch derselbe Anbieter sein.

Ein Xtrabackup oder Mariabackup verwenden, um einen inkonsistenten MySQL-Slave neu aufzubauen

Schließlich xtrabackup/mariabackup - dies ist ein von Percona geschriebenes und von MariaDB geforktes Tool, das es ermöglicht, ein physisches Backup zu erstellen. Es ist viel schneller als logische Backups – es wird hauptsächlich durch die Hardwareleistung begrenzt – Festplatte oder Netzwerk sind die wahrscheinlichsten Engpässe. Der größte Teil der Arbeitslast bezieht sich auf das Kopieren von Dateien aus dem MySQL-Datenverzeichnis an einen anderen Speicherort (auf demselben Host oder über das Netzwerk).

Obwohl nicht annähernd so schnell wie Blockspeicher-Snapshots, ist xtrabackup viel flexibler und kann in jeder Umgebung verwendet werden. Das erstellte Backup besteht aus Dateien, daher ist es durchaus möglich, das Backup an einen beliebigen Ort zu kopieren. Ein anderer Cloud-Anbieter, Ihr lokales Rechenzentrum, spielt keine Rolle, solange Sie Dateien von Ihrem aktuellen Standort übertragen können.

Es muss nicht einmal eine Netzwerkverbindung vorhanden sein - Sie können das Backup auch einfach auf ein "übertragbares" Gerät wie eine USB-SSD oder sogar einen USB-Stick kopieren, solange es alle Daten enthalten kann Daten und speichern Sie sie in Ihrer Tasche, während Sie von einem Rechenzentrum in ein anderes umziehen.

Wie erstellt man einen MySQL-Slave mit Xtrabackup neu?

Wir haben uns entschieden, uns auf xtrabackup zu konzentrieren, aufgrund seiner Flexibilität und Fähigkeit, in den meisten Umgebungen zu funktionieren, in denen MySQL existieren kann. Wie baut man seinen Slave mit xtrabackup wieder auf? Schauen wir uns das mal an.

Anfangs haben wir einen Master und einen Slave, die unter einigen Replikationsproblemen litten:

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 10.0.0.141

                  Master_User: rpl_user

                  Master_Port: 3306

                Connect_Retry: 10

              Master_Log_File: binlog.000004

          Read_Master_Log_Pos: 386

               Relay_Log_File: relay-bin.000008

                Relay_Log_Pos: 363

        Relay_Master_Log_File: binlog.000004

             Slave_IO_Running: Yes

            Slave_SQL_Running: No

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 1007

                   Last_Error: Error 'Can't create database 'mytest'; database exists' on query. Default database: 'mytest'. Query: 'create database mytest'

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 195

              Relay_Log_Space: 756

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: NULL

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 1007

               Last_SQL_Error: Error 'Can't create database 'mytest'; database exists' on query. Default database: 'mytest'. Query: 'create database mytest'

  Replicate_Ignore_Server_Ids:

             Master_Server_Id: 1001

                  Master_UUID: 53d96192-53f7-11ea-9c3c-080027c5bc64

             Master_Info_File: mysql.slave_master_info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State:

           Master_Retry_Count: 86400

                  Master_Bind:

      Last_IO_Error_Timestamp:

     Last_SQL_Error_Timestamp: 200306 11:47:42

               Master_SSL_Crl:

           Master_SSL_Crlpath:

           Retrieved_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:9

            Executed_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:1-8,

ce7d0c38-53f7-11ea-9f16-080027c5bc64:1-3

                Auto_Position: 1

         Replicate_Rewrite_DB:

                 Channel_Name:

           Master_TLS_Version:

       Master_public_key_path:

        Get_master_public_key: 0

            Network_Namespace:

1 row in set (0.00 sec)

Wie Sie sehen können, gibt es ein Problem mit einem der Schemas. Nehmen wir an, wir müssen diesen Knoten neu erstellen, um ihn wieder in die Replikation zu bringen. Hier sind die Schritte, die wir ausführen müssen.

Zuerst müssen wir sicherstellen, dass xtrabackup installiert ist. In unserem Fall verwenden wir MySQL 8.0, daher müssen wir xtrabackup in Version 8 verwenden, um die Kompatibilität zu gewährleisten:

[email protected]:~# apt install percona-xtrabackup-80

Reading package lists... Done

Building dependency tree

Reading state information... Done

percona-xtrabackup-80 is already the newest version (8.0.9-1.bionic).

0 upgraded, 0 newly installed, 0 to remove and 143 not upgraded.

Xtrabackup wird vom Percona-Repository bereitgestellt und die Anleitung zur Installation finden Sie hier:

https://www.percona.com/doc/percona-xtrabackup/8.0/installation/apt_repo.html

Das Tool muss sowohl auf dem Master als auch auf dem Slave installiert sein, den wir umbauen wollen.

Als nächsten Schritt entfernen wir alle Daten vom „kaputten“ Slave:

[email protected]:~# service mysql stop

[email protected]:~# rm -rf /var/lib/mysql/*

Als nächstes nehmen wir das Backup auf den Master und streamen es zum Slave. Bitte denken Sie daran, dass dieser spezielle Einzeiler eine passwortlose SSH-Root-Konnektivität vom Master zum Slave erfordert:

[email protected]:~# xtrabackup --backup --compress --stream=xbstream --target-dir=./ | ssh [email protected] "xbstream -x --decompress -C /var/lib/mysql/"

Am Ende sollten Sie eine wichtige Zeile sehen:

200306 12:10:40 completed OK!

Dies ist ein Indikator dafür, dass die Sicherung erfolgreich abgeschlossen wurde. Ein paar Dinge können immer noch schief gehen, aber zumindest haben wir die richtigen Daten. Als nächstes müssen wir auf dem Slave das Backup vorbereiten.

[email protected]:~# xtrabackup --prepare --target-dir=/var/lib/mysql/

.

.

.

200306 12:16:07 completed OK!

Sie sollten wieder sehen, dass der Vorgang erfolgreich abgeschlossen wurde. Möglicherweise möchten Sie die Daten jetzt zurück in das MySQL-Datenverzeichnis kopieren. Das müssen wir nicht tun, da wir das Streaming-Backup direkt in /var/lib/mysql gespeichert haben. Was wir jedoch tun möchten, ist sicherzustellen, dass die Dateien korrekt sind:

[email protected]:~# chown -R mysql.mysql /var/lib/mysql

Lassen Sie uns nun die GTID-Koordinaten des Backups überprüfen. Wir werden sie später beim Einrichten der Replikation verwenden.

[email protected]:~# cat /var/lib/mysql/xtrabackup_binlog_info

binlog.000007 195 53d96192-53f7-11ea-9c3c-080027c5bc64:1-9

Ok, alles scheint gut zu sein, lass uns MySQL starten und mit der Konfiguration der Replikation fortfahren:

[email protected]:~# service mysql start

[email protected]:~# mysql -ppass

mysql: [Warning] Using a password on the command line interface can be insecure.

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 8

Server version: 8.0.18-9 Percona Server (GPL), Release '9', Revision '53e606f'



Copyright (c) 2009-2019 Percona LLC and/or its affiliates

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.



Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.



Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.



mysql>

Jetzt müssen wir die gtid_purged auf den GTID-Satz setzen, den wir im Backup gefunden haben. Das sind GTIDs, die von unserem Backup „überdeckt“ wurden. Nur die neue GTID sollte vom Master repliziert werden.

mysql> SET GLOBAL gtid_purged='53d96192-53f7-11ea-9c3c-080027c5bc64:1-9';

Query OK, 0 rows affected (0.00 sec)

Now we can start the replication:

mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.141', MASTER_USER='rpl_user', MASTER_PASSWORD='yIPpgNE4KE', MASTER_AUTO_POSITION=1;

Query OK, 0 rows affected, 2 warnings (0.02 sec)



mysql> START SLAVE;

Query OK, 0 rows affected (0.00 sec)

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 10.0.0.141

                  Master_User: rpl_user

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: binlog.000007

          Read_Master_Log_Pos: 380

               Relay_Log_File: relay-bin.000002

                Relay_Log_Pos: 548

        Relay_Master_Log_File: binlog.000007

             Slave_IO_Running: Yes

            Slave_SQL_Running: Yes

              Replicate_Do_DB:

          Replicate_Ignore_DB:

           Replicate_Do_Table:

       Replicate_Ignore_Table:

      Replicate_Wild_Do_Table:

  Replicate_Wild_Ignore_Table:

                   Last_Errno: 0

                   Last_Error:

                 Skip_Counter: 0

          Exec_Master_Log_Pos: 380

              Relay_Log_Space: 750

              Until_Condition: None

               Until_Log_File:

                Until_Log_Pos: 0

           Master_SSL_Allowed: No

           Master_SSL_CA_File:

           Master_SSL_CA_Path:

              Master_SSL_Cert:

            Master_SSL_Cipher:

               Master_SSL_Key:

        Seconds_Behind_Master: 0

Master_SSL_Verify_Server_Cert: No

                Last_IO_Errno: 0

                Last_IO_Error:

               Last_SQL_Errno: 0

               Last_SQL_Error:

  Replicate_Ignore_Server_Ids:

             Master_Server_Id: 1001

                  Master_UUID: 53d96192-53f7-11ea-9c3c-080027c5bc64

             Master_Info_File: mysql.slave_master_info

                    SQL_Delay: 0

          SQL_Remaining_Delay: NULL

      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates

           Master_Retry_Count: 86400

                  Master_Bind:

      Last_IO_Error_Timestamp:

     Last_SQL_Error_Timestamp:

               Master_SSL_Crl:

           Master_SSL_Crlpath:

           Retrieved_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:10

            Executed_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:1-10

                Auto_Position: 1

         Replicate_Rewrite_DB:

                 Channel_Name:

           Master_TLS_Version:

       Master_public_key_path:

        Get_master_public_key: 0

            Network_Namespace:

1 row in set (0.00 sec)

Wie Sie sehen können, repliziert unser Slave von seinem Master.

Wie erstellt man einen MySQL-Slave mit ClusterControl neu?

Wenn Sie ein ClusterControl-Benutzer sind, können Sie, anstatt diesen Prozess zu durchlaufen, den Slave mit nur wenigen Klicks neu erstellen. Zunächst haben wir ein klares Problem mit der Replikation:

Unser Slave repliziert aufgrund eines Fehlers nicht richtig.

Alles, was wir tun müssen, ist, den Job „Rebuild Replication Slave“ auszuführen .

Es wird Ihnen ein Dialogfeld angezeigt, in dem Sie einen Master-Knoten auswählen sollten der Sklave, den Sie umbauen möchten. Klicken Sie dann auf Fortfahren und schon sind Sie fertig. ClusterControl baut den Slave neu und richtet die Replikation für Sie ein.

In Kürze, basierend auf der Größe des Datensatzes, sollten Sie Working Slave:

sehen

Wie Sie sehen können, hat ClusterControl mit nur wenigen Klicks die Aufgabe erledigt, den inkonsistenten Replikations-Slave neu aufzubauen.