Mysql
 sql >> база данни >  >> RDS >> Mysql

Как да възстановим непоследователен MySQL Slave?

Подчинените на MySQL могат да станат непоследователни. Можете да се опитате да го избегнете, но наистина е трудно. Задаването на super_read_only и използването на репликация, базирана на редове, може да помогне много, но каквото и да правите, все още е възможно вашият подчинен да стане непоследователен.

Какво може да се направи, за да се изгради отново непоследователен MySQL slave? В тази публикация в блога ще разгледаме този проблем.

Първо, нека обсъдим какво трябва да се случи, за да възстановим роб. За да внесете възел в MySQL репликация, той трябва да бъде снабден с данни от един от възлите в топологията на репликация. Тези данни трябва да са последователни към момента, в който са били събрани. Не можете да го вземете на база таблица по таблица или схема по схема, защото това ще направи предоставения възел несъвместим вътрешно. Това означава, че някои данни биха били по-стари от друга част от набора от данни.

В допълнение към последователността на данните, трябва да е възможно да се събира и информация за връзката между данните и състоянието на репликация. Искате да имате или позиция в двоичен регистър, при която събраните данни са последователни, или глобален идентификатор на транзакция на транзакцията, която е била последната, изпълнена на възела, който е източник на данните.

Това ни води до следните съображения. Можете да възстановите подчинен с помощта на всеки инструмент за архивиране, стига този инструмент да може да генерира последователно архивиране и да включва координати на репликация за момента във времето, в който архивирането е последователно. Това ни позволява да избираме от няколко опции.

Използване на Mysqldump за повторно изграждане на непоследователен MySQL Slave

Mysqldump е най-основният инструмент, с който разполагаме, за да постигнем това. Позволява ни да създадем логическо архивиране, наред с другото, под формата на SQL изрази. Важното е, че макар и основно, той все пак ни позволява да правим последователно архивиране:може да използва транзакцията, за да гарантира, че данните са последователни в началото на транзакцията. Може също така да запише координати на репликация за тази точка, дори и цял оператор CHANGE MASTER, което улеснява стартирането на репликацията с помощта на резервното копие.

Използване на Mydumper за повторно изграждане на непоследователен MySQL Slave

Друга опция е да използвате mydumper – този инструмент, точно като mysqldump, генерира логическо архивиране и, точно като mysqldump, може да се използва за създаване на последователно архивиране на базата данни. Основната разлика между mydumper и mysqldump е, че mydumper, когато е сдвоен с myloader, може да изхвърля и възстановява данни паралелно, подобрявайки изхвърлянето и особено времето за възстановяване.

Използване на моментна снимка за повторно изграждане на непоследователен MySQL Slave

За тези, които използват облачни доставчици, възможността е да направят моментна снимка на основното хранилище на блокове. Моментните снимки генерират изглед на данните в даден момент. Този процес обаче е доста труден, тъй като последователността на данните и възможността за възстановяването им зависят най-вече от конфигурацията на MySQL.

Трябва да се уверите, че базата данни работи в издръжлив режим (тя е конфигурирана по начин, че сривът на MySQL няма да доведе до загуба на данни). Това е така, защото (от гледна точка на MySQL) правенето на моментна снимка на тома и след това стартирането на друг екземпляр на MySQL от съхраняваните в него данни е по същество същият процес, както ако убиете -9 mysqld и след това го стартирате отново. Възстановяването на InnoDB трябва да се случи, да се възпроизведат транзакции, които са били съхранени в двоични регистрационни файлове, транзакции за връщане назад, които не са завършени преди срива и така нататък.

Недостатъкът на процеса на възстановяване, базиран на моментни снимки, е, че той е силно обвързан с текущия доставчик. Не можете лесно да копирате данните за моментни снимки от един доставчик на облак към друг. Може да успеете да го премествате между различни региони, но той пак ще бъде един и същ доставчик.

Използване на Xtrabackup или Mariabackup за възстановяване на непоследователно MySQL Slave

Накрая, xtrabackup/mariabackup - това е инструмент, написан от Percona и разклонен от MariaDB, който позволява да се генерира физическо архивиране. Той е много по-бърз от логическите архиви - ограничен е най-вече от хардуерната производителност - дискът или мрежата са най-вероятните тесни места. По-голямата част от натоварването е свързано с копиране на файлове от MySQL директория с данни на друго място (на същия хост или през мрежата).

Макар че не е толкова бърз, колкото моментните снимки на блоково хранилище, xtrabackup е много по-гъвкав и може да се използва във всяка среда. Архивът, който създава, се състои от файлове, така че е напълно възможно да копирате архива на всяко място, което желаете. Друг доставчик на облак, вашият локален център за данни, няма значение, стига да можете да прехвърляте файлове от текущото си местоположение.

Дори не е нужно да има мрежова свързаност - можете също така просто да копирате архива на някое „прехвърляемо“ устройство като USB SSD или дори USB флаш, стига да може да съдържа всички данни и ги съхранявайте в джоба си, докато се премествате от един център за данни в друг.

Как да възстановим MySQL Slave с помощта на Xtrabackup?

Решихме да се съсредоточим върху xtrabackup, предвид неговата гъвкавост и способност да работи в повечето среди, където MySQL може да съществува. Как да възстановите своя подчинен с помощта на xtrabackup? Нека да разгледаме.

Първоначално имаме главен и подчинен, които страдаха от някои проблеми с репликацията:

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)

Както виждате, има проблем с една от схемите. Да приемем, че трябва да възстановим този възел, за да го върнем обратно в репликацията. Ето стъпките, които трябва да изпълним.

Първо, трябва да се уверим, че xtrabackup е инсталиран. В нашия случай използваме MySQL 8.0, затова трябва да използваме xtrabackup във версия 8, за да гарантираме съвместимост:

[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 се предоставя от хранилището на Percona и ръководството за инсталирането му може да бъде намерено тук:

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

Инструментът трябва да бъде инсталиран както на главния, така и на подчинения, който искаме да изградим отново.

Като следваща стъпка ще премахнем всички данни от „счупения“ подчинен:

[email protected]:~# service mysql stop

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

След това ще вземем резервното копие на главния и ще го прехвърлим към подчинения. Моля, имайте предвид, че този конкретен едноред изисква SSH root връзка без парола от главния към подчинения:

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

В края трябва да видите важен ред:

200306 12:10:40 completed OK!

Това е индикатор, че архивирането е завършено ОК. Няколко неща все още може да се объркат, но поне имаме правилните данни. След това, на подчинения, трябва да подготвим резервното копие.

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

.

.

.

200306 12:16:07 completed OK!

Трябва да видите отново, че процесът е завършен ОК. Може да искате сега да копирате данните обратно в директорията с данни на MySQL. Не е нужно да правим това, тъй като съхранихме поточното архивиране директно в /var/lib/mysql. Това, което искаме да направим обаче, е да гарантираме правилното притежание на файловете:

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

Сега нека проверим GTID координатите на резервното копие. Ще ги използваме по-късно при настройката на репликацията.

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

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

Добре, всичко изглежда е наред, нека стартираме MySQL и да продължим с конфигурирането на репликацията:

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

Сега трябва да настроим gtid_purged на набора GTID, който намерихме в архива. Това са GTID, които са „покрити“ от нашето архивиране. Само нов GTID трябва да се репликира от главния.

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)

Както можете да видите, нашият подчинен се копира от своя главен.

Как да възстановим MySQL Slave с помощта на ClusterControl?

Ако сте потребител на ClusterControl, вместо да преминавате през този процес, можете да възстановите подчинения само с няколко щраквания. Първоначално имаме ясен проблем с репликацията:

Нашето подчинено устройство не се репликира правилно поради грешка.

Всичко, което трябва да направим, е да стартираме заданието „Rebuild Replication Slave“ .

Ще ви бъде представен диалогов прозорец, в който трябва да изберете главен възел за робът, който искате да възстановите. След това щракнете върху Напред и сте готови. ClusterControl ще изгради отново подчинения и ще настрои репликацията вместо вас.

Накратко, въз основа на размера на набора от данни, трябва да видите работещ подчинен:

Както можете да видите, само с няколко щраквания ClusterControl изпълни задачата за възстановяване на непоследователния роб на репликация.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL Подреждане по номер, нула последни

  2. MySQL заявка ГРУПА ПО ден/месец/година

  3. Изпълнение на множество SQL заявки в един израз с PHP

  4. PHP MySQL Google Chart JSON - пълен пример

  5. При игнориране на дублиран ключ?