W konfiguracji master-slave MySQL 5.7, która używa domyślnego ustawienia replikacji półsynchronicznej dla rpl_semi_sync_master_wait_point , awaria mastera i przełączenie awaryjne na slave jest uważane za bezstratne. Jednak, gdy uszkodzony master wróci, może się okazać, że zawiera transakcje, które nie są obecne w bieżącym master (który wcześniej był slave). To zachowanie może być zagadkowe, biorąc pod uwagę, że półsynchroniczna replikacja ma być bezstratna, ale w rzeczywistości jest to oczekiwane zachowanie w MySQL. Dlaczego dokładnie tak się dzieje, wyjaśniono szczegółowo w poście na blogu Jean-François Gagné (JF).
Zważywszy na taki scenariusz, dokumentacja MySQL zaleca, aby uszkodzony master został odrzucony i nie powinien być uruchamiany ponownie. Jednak odrzucenie takiego serwera jest kosztowne i nieefektywne. W tym poście na blogu wyjaśnimy podejście do wykrywania i naprawiania transakcji na uszkodzonym serwerze głównym MySQL w konfiguracji replikacji półsynchronicznej oraz jak ponownie włączyć je z powrotem do konfiguracji master-slave.
Dlaczego ważne jest wykrywanie dodatkowych transakcji na Odzyskanym wzorcu?
Dodatkowe transakcje na odzyskanym wzorcu mogą manifestować się na dwa sposoby:
1. Replikacja MySQL nie powiodła się, gdy odzyskany master jest ponownie podporządkowany
Zazwyczaj dzieje się tak, gdy masz klucz podstawowy z automatyczną inkrementacją. Kiedy nowy master MySQL wstawi wiersz do takiej tabeli, replikacja nie powiedzie się, ponieważ klucz już istnieje na urządzeniu podrzędnym.
Inny scenariusz to sytuacja, w której aplikacja ponawia transakcję, która nie powiodła się podczas awarii głównej. Na odzyskanym urządzeniu głównym MySQL (który jest teraz urządzeniem podrzędnym) ta transakcja faktycznie istniałaby i ponownie spowoduje błąd replikacji.
Zazwyczaj błąd replikacji MySQL wygląda tak:
[BŁĄD] Slave SQL dla kanału '':Worker 5 nie mógł wykonać transakcji 'fd1ba8f0-cbee-11e8- b27f-000d3a0df42d:5938858' w logu głównym mysql-bin.000030, end_log_pos 10262184; Błąd „Zduplikowany wpis „5018” dla klucza „PRIMARY” w zapytaniu. Domyślna baza danych:„test”. Zapytanie:„wstaw do wartości testowych (5018,2019,„item100”)”, Error_code:1062 |
2. Cicha niespójność danych między nowym masterem MySQL i slave (odzyskanym masterem)
W przypadkach, gdy aplikacja nie ponawia próby nieudanej transakcji i w przyszłości nie wystąpią kolizje kluczy podstawowych, błąd replikacji może nie wystąpić. W rezultacie niespójność danych może pozostać niewykryta.
W obu powyższych przypadkach ma to wpływ na wysoką dostępność lub integralność danych w konfiguracji MySQL, dlatego tak ważne jest, aby wykryć ten stan tak wcześnie, jak to możliwe.
Jak wykryć dodatkowe transakcje na Odzyskanym Mistrzu MySQL
Możemy wykryć dodatkowe transakcje na odzyskanym wzorcu za pomocą funkcji MySQL GTID (globalny identyfikator transakcji):
GTID_SUBSET(zestaw1 ,zestaw2 ):podano dwa zestawy globalnych identyfikatorów transakcji set1 i zestaw2 , zwraca prawdę, jeśli wszystkie identyfikatory GTID w zestawie1 są również w zestawie2 . W przeciwnym razie zwraca fałsz.
Posłużmy się przykładem, aby to zrozumieć.
- GTID ustawiony na odzyskanym wzorcu, którego UUID to:„54a63bc3-d01d-11e7-bf52-000d3af93e52 ’ to:
- '54a63bc3-d01d-11e7-bf52-000d3af93e52:1-970,57956099-d01d-11e7-80bc-000d3af97c09:1-810”
- Zestaw GTID nowego mastera, którego UUID to:„57956099-d01d-11e7-80bc-000d3af97c09 ’ to:
- '54a63bc3-d01d-11e7-bf52-000d3af93e52:1-9690,57956099-d01d-11e7-80bc-000d3af97c09:1-870'
Teraz, jeśli wywołamy funkcję GTID_SUBSET jako GTID_SUBSET(zestaw GTID odzyskanego wzorca, zestaw GTID nowego wzorca) , zwracana wartość będzie prawdziwa tylko wtedy, gdy odzyskany wzorzec nie zawiera żadnych dodatkowych transakcji. W naszym przykładzie powyżej, ponieważ odzyskany master ma dodatkowe transakcje od 9691 do 9700, wynik powyższego zapytania jest fałszywy.
Ponowne podporządkowanie uszkodzonego serwera #MySQL Master w konfiguracji replikacji półsynchronicznejKliknij, aby tweetowaćJak ponownie podporządkować odzyskanego MySQL Master, który zawiera dodatkowe transakcje
Na podstawie powyższego kroku można dowiedzieć się, czy odzyskany wzorzec ma dodatkowe transakcje i jakie te transakcje używają funkcji GTID:GTID_SUBTRACT(zestaw GTID odzyskany wzorzec, zestaw GTID nowego wzorca).
Możliwe jest również wyodrębnienie tych dodatkowych transakcji z dzienników binarnych i zapisanie ich. Może być przydatne dla zespołu biznesowego, aby później przejrzeć te transakcje, aby upewnić się, że nie tracimy przypadkowo żadnych ważnych informacji biznesowych, nawet jeśli były one niezaangażowane. Gdy to zrobimy, potrzebujemy sposobu na pozbycie się tych dodatkowych transakcji, aby odzyskany master mógł zostać ponownie zniewolony bez problemów.
Jednym z najprostszych sposobów, aby to zrobić, jest wykonanie migawki kopii zapasowej na bieżącym urządzeniu głównym i przywrócenie danych na bieżącym urządzeniu podrzędnym. Pamiętaj, że musisz zachować UUID tego serwera tak jak poprzednio. Po przywróceniu danych serwer może zostać ponownie podporządkowany i rozpocznie replikację od punktu przywróconej migawki. Wkrótce znów będziesz mieć zdrowego niewolnika!
Powyższe kroki są bardzo żmudne, jeśli musisz je wykonać ręcznie, ale w pełni zarządzana usługa hostingowa MySQL firmy ScaleGrid może zautomatyzować cały proces bez żadnej interwencji. Oto jak to działa:
W przypadku awarii aktualnego urządzenia głównego ScaleGrid automatyzuje proces przełączania awaryjnego i promuje odpowiedniego urządzenia podrzędnego jako nowego urządzenia głównego. Stary wzorzec jest następnie odzyskiwany i automatycznie wykrywamy, czy są na nim dodatkowe transakcje. Jeśli jakieś zostaną znalezione, wdrożenie MySQL przechodzi w stan zdegradowany, a my używamy automatycznych narzędzi do wyodrębniania i zapisywania dodatkowych transakcji do sprawdzenia. Nasz zespół pomocy technicznej może następnie przywrócić stary master do dobrego stanu i ponownie podłączyć go do konfiguracji master-slave, aby zapewnić prawidłowe wdrożenie!
Chcesz spróbować? Rozpocznij bezpłatny 30-dniowy okres próbny, aby poznać wszystkie możliwości zarządzania bazą danych MySQL w ScaleGrid.