Podrzędne serwery MySQL mogą stać się niespójne. Możesz spróbować tego uniknąć, ale to naprawdę trudne. Ustawienie super_read_only i użycie replikacji opartej na wierszach może bardzo pomóc, ale bez względu na to, co zrobisz, nadal możliwe jest, że Twój niewolnik stanie się niespójny.
Co można zrobić, aby odbudować niespójne urządzenie podrzędne MySQL? W tym poście na blogu przyjrzymy się temu problemowi.
Najpierw omówmy, co musi się wydarzyć, aby odbudować niewolnika. Aby wprowadzić węzeł do replikacji MySQL, musi on zostać wyposażony w dane z jednego z węzłów w topologii replikacji. Dane te muszą być spójne w momencie ich zebrania. Nie można go pobrać na podstawie tabeli po tabeli lub schematu po schemacie, ponieważ spowoduje to, że udostępniony węzeł będzie niespójny wewnętrznie. Oznacza to, że niektóre dane byłyby starsze niż inna część zbioru danych.
Oprócz spójności danych powinno być również możliwe zbieranie informacji o relacji między danymi a stanem replikacji. Chcesz mieć pozycję dziennika binarnego, w którym zebrane dane są spójne, lub globalny identyfikator transakcji transakcji, która była ostatnią wykonaną w węźle będącym źródłem danych.
To prowadzi nas do następujących rozważań. Urządzenie podrzędne można odbudować za pomocą dowolnego narzędzia do tworzenia kopii zapasowych, o ile narzędzie to może generować spójną kopię zapasową i zawiera współrzędne replikacji dla punktu w czasie, w którym kopia zapasowa jest spójna. To pozwala nam wybrać jedną z kilku opcji.
Korzystanie z Mysqldump do odbudowania niespójnego serwera MySQL Slave
Mysqldump jest najbardziej podstawowym narzędziem, jakie mamy, aby to osiągnąć. Pozwala na tworzenie logicznego backupu m.in. w postaci instrukcji SQL. Co ważne, będąc podstawowym, pozwala jednak na wykonanie spójnej kopii zapasowej:może wykorzystać transakcję, aby zapewnić spójność danych na początku transakcji. Może również zapisać współrzędne replikacji dla tego punktu, nawet całą instrukcję CHANGE MASTER, co ułatwia rozpoczęcie replikacji przy użyciu kopii zapasowej.
Korzystanie z Mydumper do odbudowania niespójnego modułu MySQL Slave
Inną opcją jest użycie mydumper - to narzędzie, podobnie jak mysqldump, generuje logiczną kopię zapasową i, podobnie jak mysqldump, może służyć do tworzenia spójnej kopii zapasowej bazy danych. Główna różnica między mydumper i mysqldump polega na tym, że mydumper, w połączeniu z myloader, może równolegle zrzucać i przywracać dane, poprawiając zrzut, a zwłaszcza czas przywracania.
Korzystanie z migawki do odbudowania niespójnego modułu MySQL Slave
Dla tych, którzy korzystają z dostawców usług w chmurze, istnieje możliwość zrobienia migawki bazowej pamięci blokowej. Migawki generują widok danych z określonego punktu w czasie. Ten proces jest jednak dość skomplikowany, ponieważ spójność danych i możliwość ich przywrócenia zależy głównie od konfiguracji MySQL.
Należy upewnić się, że baza danych działa w trybie trwałym (jest skonfigurowana w taki sposób, że awaria MySQL nie spowoduje utraty danych). Dzieje się tak, ponieważ (z punktu widzenia MySQL) zrobienie migawki woluminu, a następnie uruchomienie innej instancji MySQL z przechowywanych w niej danych, jest w zasadzie tym samym procesem, jak w przypadku zabicia mysqld -9, a następnie ponownego uruchomienia go. Odzyskiwanie InnoDB musi nastąpić, powtórzyć transakcje, które zostały zapisane w dziennikach binarnych, transakcje wycofania, które nie zostały zakończone przed awarią i tak dalej.
Wadą procesu odbudowy opartego na migawkach jest to, że jest on silnie powiązany z obecnym dostawcą. Nie można łatwo skopiować danych migawki od jednego dostawcy chmury do innego. Możesz przenieść go między różnymi regionami, ale nadal będzie to ten sam dostawca.
Korzystanie z Xtrabackup lub Mariabackup do odbudowania niespójnego serwera MySQL Slave
Na koniec xtrabackup/mariabackup - jest to narzędzie napisane przez Perconę i rozwidlone przez MariaDB, które pozwala na wygenerowanie fizycznej kopii zapasowej. Jest o wiele szybszy niż tworzenie kopii logicznych – ogranicza go głównie wydajność sprzętu – dysk lub sieć są najbardziej prawdopodobnymi wąskimi gardłami. Większość obciążenia jest związana z kopiowaniem plików z katalogu danych MySQL do innej lokalizacji (na tym samym hoście lub przez sieć).
Chociaż nie jest tak szybki jak migawki blokowej pamięci masowej, xtrabackup jest znacznie bardziej elastyczny i może być używany w dowolnym środowisku. Tworzona kopia zapasowa składa się z plików, dlatego doskonale jest możliwe skopiowanie kopii zapasowej w dowolne miejsce. Inny dostawca chmury, lokalne centrum danych, nie ma znaczenia, o ile możesz przesyłać pliki z bieżącej lokalizacji.
Nie musi nawet mieć łączności sieciowej — równie dobrze możesz po prostu skopiować kopię zapasową na jakieś „przenośne” urządzenie, takie jak dysk SSD USB lub nawet pamięć USB, o ile może zawierać wszystkie dane i przechowuj je w kieszeni podczas przenoszenia z jednego centrum danych do drugiego.
Jak odbudować MySQL Slave przy użyciu Xtrabackup?
Zdecydowaliśmy się skupić na xtrabackup, biorąc pod uwagę jego elastyczność i możliwość pracy w większości środowisk, w których może istnieć MySQL. Jak odbudować niewolnika za pomocą xtrabackup? Rzućmy okiem.
Na początku mamy urządzenie nadrzędne i podrzędne, które miały pewne problemy z replikacją:
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)
Jak widać, jest problem z jednym ze schematów. Załóżmy, że musimy przebudować ten węzeł, aby przywrócić go do replikacji. Oto kroki, które musimy wykonać.
Najpierw musimy upewnić się, że xtrabackup jest zainstalowany. W naszym przypadku używamy MySQL 8.0, dlatego musimy użyć xtrabackup w wersji 8, aby zapewnić kompatybilność:
[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 jest dostarczany przez repozytorium Percona, a przewodnik po jego instalacji można znaleźć tutaj:
https://www.percona.com/doc/percona-xtrabackup/8.0/installation/apt_repo.html
Narzędzie musi być zainstalowane zarówno na urządzeniu głównym, jak i podrzędnym, które chcemy odbudować.
W następnym kroku usuniemy wszystkie dane z „zepsutego” urządzenia podrzędnego:
[email protected]:~# service mysql stop
[email protected]:~# rm -rf /var/lib/mysql/*
Następnie pobierzemy kopię zapasową z urządzenia głównego i prześlemy strumieniowo do urządzenia podrzędnego. Należy pamiętać, że ta konkretna jednowierszowa wymaga bezhasłowej łączności root SSH od urządzenia nadrzędnego do urządzenia podrzędnego:
[email protected]:~# xtrabackup --backup --compress --stream=xbstream --target-dir=./ | ssh [email protected] "xbstream -x --decompress -C /var/lib/mysql/"
Na końcu powinieneś zobaczyć ważny wiersz:
200306 12:10:40 completed OK!
To jest wskaźnik, że kopia zapasowa została ukończona poprawnie. Kilka rzeczy może się nie udać, ale przynajmniej udało nam się uzyskać prawidłowe dane. Następnie na urządzeniu podrzędnym musimy przygotować kopię zapasową.
[email protected]:~# xtrabackup --prepare --target-dir=/var/lib/mysql/
.
.
.
200306 12:16:07 completed OK!
Powinieneś ponownie zobaczyć, że proces zakończył się poprawnie. Możesz teraz skopiować dane z powrotem do katalogu danych MySQL. Nie musimy tego robić, ponieważ zapisywaliśmy strumieniową kopię zapasową bezpośrednio w /var/lib/mysql. Chcemy jednak zapewnić prawidłowe prawo własności do plików:
[email protected]:~# chown -R mysql.mysql /var/lib/mysql
Teraz sprawdźmy współrzędne GTID kopii zapasowej. Użyjemy ich później podczas konfigurowania replikacji.
[email protected]:~# cat /var/lib/mysql/xtrabackup_binlog_info
binlog.000007 195 53d96192-53f7-11ea-9c3c-080027c5bc64:1-9
Ok, wszystko wydaje się być w porządku, uruchommy MySQL i przejdźmy do konfiguracji replikacji:
[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>
Teraz musimy ustawić gtid_purged na zestaw GTID, który znaleźliśmy w kopii zapasowej. To są GTID, które zostały „przykryte” przez naszą kopię zapasową. Tylko nowy identyfikator GTID powinien być replikowany z wzorca.
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)
Jak widać, nasz niewolnik replikuje się ze swojego pana.
Jak odbudować MySQL Slave za pomocą ClusterControl?
Jeśli jesteś użytkownikiem ClusterControl, zamiast przechodzić przez ten proces, możesz odbudować urządzenie podrzędne za pomocą zaledwie kilku kliknięć. Początkowo mamy wyraźny problem z replikacją:
Nasz slave nie replikuje się prawidłowo z powodu błędu.
Wszystko, co musimy zrobić, to uruchomić zadanie „Odbuduj moduł podrzędny replikacji” .
Zostanie wyświetlone okno dialogowe, w którym należy wybrać węzeł główny dla niewolnika, którego chcesz odbudować. Następnie kliknij Kontynuuj i gotowe. ClusterControl odbuduje urządzenie podrzędne i skonfiguruje replikację za Ciebie.
Krótko, w oparciu o rozmiar zestawu danych, powinieneś zobaczyć działające urządzenie podrzędne:
Jak widać, za pomocą zaledwie kilku kliknięć ClusterControl wykonał zadanie odbudowania niespójnego niewolnika replikacji.