sql >> Database teknologi >  >> RDS >> Mysql

Hvordan genopbygger man en inkonsekvent MySQL-slave?

MySQL-slaver kan blive inkonsekvente. Du kan prøve at undgå det, men det er virkelig svært. At indstille super_read_only og bruge rækkebaseret replikering kan hjælpe meget, men uanset hvad du gør, er det stadig muligt, at din slave bliver inkonsekvent.

Hvad kan man gøre for at genopbygge en inkonsekvent MySQL-slave? I dette blogindlæg tager vi et kig på dette problem.

Først og fremmest, lad os diskutere, hvad der skal ske for at genopbygge en slave. For at bringe en node ind i MySQL-replikering skal den forsynes med data fra en af ​​noderne i replikeringstopologien. Disse data skal være konsistente på det tidspunkt, hvor de blev indsamlet. Du kan ikke tage det på en tabel for tabel eller skema for skema, fordi dette vil gøre den klargjorte node inkonsekvent internt. Det betyder, at nogle data ville være ældre end en anden del af datasættet.

Ud over datakonsistens bør det også være muligt at indsamle information om forholdet mellem dataene og replikationstilstanden. Du vil have enten binær logposition, hvor de indsamlede data er konsistente, eller Global Transaction ID for transaktionen, som var den sidst udførte på den node, der er kilden til dataene.

Dette fører os til følgende overvejelser. Du kan genopbygge en slave ved hjælp af ethvert sikkerhedskopieringsværktøj, så længe dette værktøj kan generere konsekvent sikkerhedskopiering, og det inkluderer replikeringskoordinater for det tidspunkt, hvor sikkerhedskopieringen er konsistent. Dette giver os mulighed for at vælge mellem et par muligheder.

Brug af Mysqldump til at genopbygge en inkonsekvent MySQL-slave

Mysqldump er det mest grundlæggende værktøj, vi har for at opnå dette. Det giver os mulighed for at lave en logisk backup i blandt andet form af SQL-sætninger. Hvad der er vigtigt, mens det er grundlæggende, giver det os stadig mulighed for at tage en konsekvent backup:den kan bruge transaktionen til at sikre, at dataene er konsistente i begyndelsen af ​​transaktionen. Den kan også nedskrive replikeringskoordinater for det punkt, endda en hel CHANGE MASTER-sætning, hvilket gør det nemt at starte replikeringen ved hjælp af sikkerhedskopien.

Brug af Mydumper til at genopbygge en inkonsekvent MySQL-slave

En anden mulighed er at bruge mydumper - dette værktøj, ligesom mysqldump, genererer en logisk backup og kan, ligesom mysqldump, bruges til at lave en konsistent backup af databasen. Den største forskel mellem mydumper og mysqldump er, at mydumper, når den er parret med myloader, kan dumpe og gendanne data parallelt, hvilket forbedrer dumpen og især genskaber tiden.

Brug af et snapshot til at genopbygge en inkonsekvent MySQL-slave

For dem, der bruger cloud-udbydere, er en mulighed at tage et øjebliksbillede af den underliggende bloklagring. Snapshots genererer et punkt-i-tidsbillede af dataene. Denne proces er dog ret besværlig, da konsistensen af ​​dataene og evnen til at gendanne dem afhænger for det meste af MySQL-konfigurationen.

Du bør sikre dig, at databasen fungerer i en holdbar tilstand (den er konfigureret på en måde, så nedbrud af MySQL ikke vil resultere i tab af data). Dette skyldes (fra et MySQL-synspunkt) at tage et volumen-øjebliksbillede og derefter starte en anden MySQL-instans fra de data, der er gemt i den, dybest set er den samme proces, som hvis du ville dræbe -9 mysqld'en og derefter starte den igen. InnoDB-gendannelsen skal ske, genafspil transaktioner, der er blevet gemt i binære logfiler, rollback-transaktioner, der ikke er gennemført før nedbruddet og så videre.

Ulempen ved snapshot-baseret genopbygningsproces er, at den er stærkt knyttet til den nuværende leverandør. Du kan ikke nemt kopiere snapshot-dataene fra en cloud-udbyder til en anden. Du kan muligvis flytte det mellem forskellige regioner, men det vil stadig være den samme udbyder.

Brug af en Xtrabackup eller Mariabackup til at genopbygge en inkonsekvent MySQL-slave

Til sidst, xtrabackup/mariabackup - dette er et værktøj skrevet af Percona og forgrenet af MariaDB, der gør det muligt at generere en fysisk backup. Det er langt hurtigere end logiske sikkerhedskopier - det er for det meste begrænset af hardwareydelsen - disk eller netværk er de mest sandsynlige flaskehalse. Det meste af arbejdsbyrden er relateret til kopiering af filer fra MySQL-datamappe til en anden placering (på samme vært eller over netværket).

Selv om det ikke er nær så hurtigt som snapshots af bloklagring, er xtrabackup meget mere fleksibelt og kan bruges i ethvert miljø. Sikkerhedskopien den producerer består af filer, derfor er det perfekt muligt at kopiere sikkerhedskopien til et hvilket som helst sted, du ønsker. En anden cloud-udbyder, dit lokale datacenter, det er ligegyldigt, så længe du kan overføre filer fra din nuværende placering.

Det behøver ikke engang at have netværksforbindelse - du kan lige så godt bare kopiere sikkerhedskopien til en "overførbar" enhed som USB SSD eller endda USB-stick, så længe den kan indeholde alle data og gem dem i lommen, mens du flytter fra et datacenter til et andet.

Hvordan genopbygger man en MySQL-slave ved hjælp af Xtrabackup?

Vi besluttede at fokusere på xtrabackup på grund af dets fleksibilitet og evne til at arbejde i de fleste af de miljøer, hvor MySQL kan eksistere. Hvordan genopbygger du din slave ved hjælp af xtrabackup? Lad os tage et kig.

I første omgang har vi en master og en slave, som led af nogle replikeringsproblemer:

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)

Som du kan se, er der et problem med et af skemaerne. Lad os antage, at vi skal genopbygge denne node for at bringe den tilbage i replikationen. Her er de trin, vi skal udføre.

Først skal vi sørge for, at xtrabackup er installeret. I vores tilfælde bruger vi MySQL 8.0, derfor er vi nødt til at bruge xtrabackup i version 8 for at sikre kompatibilitet:

[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 leveres af Percona repository, og vejledningen til at installere det kan findes her:

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

Værktøjet skal installeres på både master og slave, som vi ønsker at genopbygge.

Som et næste trin vil vi fjerne alle data fra den "brudte" slave:

[email protected]:~# service mysql stop

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

Derefter tager vi backup'en på masteren og streamer den til slaven. Husk at denne særlige one-liner kræver adgangskodefri SSH-rodforbindelse fra masteren til slaven:

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

I slutningen skulle du se en vigtig linje:

200306 12:10:40 completed OK!

Dette er en indikator for, at sikkerhedskopieringen er fuldført OK. Et par ting kan stadig gå galt, men i det mindste fik vi dataene rigtige. Dernæst skal vi på slaven forberede sikkerhedskopien.

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

.

.

.

200306 12:16:07 completed OK!

Du skulle igen kunne se, at processen fuldførte OK. Du vil måske nu kopiere dataene tilbage til MySQL-databiblioteket. Vi behøver ikke at gøre det, da vi gemte streaming backup direkte i /var/lib/mysql. Hvad vi dog ønsker at gøre, er at sikre korrekt ejerskab af filerne:

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

Lad os nu tjekke GTID-koordinaterne for sikkerhedskopieringen. Vi vil bruge dem senere, når vi opsætter replikeringen.

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

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

Ok, alt ser ud til at være i orden, lad os starte MySQL og fortsætte med at konfigurere replikeringen:

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

Nu skal vi indstille gtid_purged til det GTID-sæt, som vi fandt i sikkerhedskopien. Det er GTID, der er blevet "dækket" af vores backup. Kun nyt GTID bør replikeres fra masteren.

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)

Som du kan se, replikerer vores slave fra sin herre.

Hvordan genopbygger man en MySQL-slave ved hjælp af ClusterControl?

Hvis du er en ClusterControl-bruger, kan du i stedet for at gennemgå denne proces genopbygge slaven med blot et par klik. I første omgang har vi et klart problem med replikeringen:

Vores slave replikerer ikke korrekt på grund af en fejl.

Alt vi skal gøre er at køre "Rebuild Replication Slave"-jobbet .

Du vil blive præsenteret for en dialogboks, hvor du skal vælge en masterknude til slaven, som du vil genopbygge. Klik derefter på Fortsæt, og du er klar. ClusterControl vil genopbygge slaven og konfigurere replikeringen for dig.

I kort tid, baseret på datasættets størrelse, skulle du se en fungerende slave:

Som du kan se, udførte ClusterControl med blot et par klik opgaven med at genopbygge den inkonsekvente replikeringsslave.


  1. Sikkerhedskopier/gendan en dockeriseret PostgreSQL-database

  2. Forbind med i Oracle SQL

  3. Vil du ændre startnummer for automatisk stigning?

  4. Sådan laver du en inventardatabase om adgang