Replikacja Mysql poszczególnych tabel. Konfigurowanie replikacji Master-Slave w MySQL

Mój raport jest przeznaczony dla tych osób, które znają słowo „replikacja”, wiedzą nawet, że MySQL je ma, a być może raz to skonfigurowały, spędziły 15 minut i o tym zapomniały. Nic więcej o niej nie wiedzą.

Raport nie będzie zawierał:


Wszystko to jest w Internecie, nie ma sensu rozumieć składni.

Przeanalizujemy trochę teorię, spróbujemy wyjaśnić, jak to wszystko działa od środka, a potem będziesz mógł sam zagłębić się w dokumentację z potrójną siłą.

Czym w zasadzie jest replikacja? To jest kopiowanie zmian. Mamy jedną kopię bazy danych, chcemy w jakimś celu inną kopię.

Replikacja występuje w różnych typach. Różne osie porównania:

  • stopień synchronizacji zmian (synchronizacja, asynchronia, półsync);
  • liczba serwerów rejestrujących (M/S, M/M);
  • zmienić format (oparty na instrukcjach (SBR), oparty na wierszach (RBR), mieszany);
  • teoretycznie model przekazywania zmian (push, pull).

Ciekawostka – jeśli się nad tym chwilę zastanowić, replikacja teoretycznie pomaga nam skalować tylko odczyt z podstawowych powodów. Oto nieco nieoczywisty wniosek. Dzieje się tak dlatego, że jeśli musimy wgrać pewną liczbę zmian do tej samej kopii danych, a ta konkretna kopia danych jest obsługiwana przez ten sam serwer, to serwer ten jest w stanie wytrzymać określoną liczbę aktualizacji na sekundę i nie więcej będzie tam przesłanych. Serwer jest w stanie aktualizować 1000 rekordów na sekundę, ale nie 2000. Co się zmieni, jeśli umieścisz replikę na tym serwerze, niezależnie od tego, czy jest to tryb master-slave czy master-master? Czy uda Ci się wrzucić drugi tysiąc aktualizacji na tę replikę? Prawidłowa odpowiedź brzmi: nie.

Można oczywiście dodawać dodatkowe aktualizacje do repliki w trybie master-master, ale inna sprawa, że ​​jak nie dotrą do pierwszego mastera i spróbują zrobić na nim drugi tysiąc aktualizacji, to pojemność już nie będzie wystarczająca . Musisz zrozumieć i nie mylić dwóch prawie oczywistych punktów, że replikacja to jedno, ale dane muszą zostać podzielone, a jeśli chcesz skalować nie czytanie, ale pisanie, będziesz musiał zrobić coś innego, i replikacja niewiele pomoże.

Te. replikacja polega bardziej na czytaniu.

O synchronizacji.

Synchronizacja to gwarancja dostępności i przystępności. Dostępność w tym sensie, że nasze zatwierdzenie minęło, transakcja została zatwierdzona, wszystko jest w porządku, dane te są widoczne dla jednego lub większej liczby węzłów w klastrze, mogą one uczestniczyć w kolejnych żądaniach. Dostępność oznacza, że ​​dane w zasadzie znajdują się na więcej niż jednym serwerze, ale być może transakcja nie została utracona i nie jest dostępna.

Nie ma żadnego komunikatu „Zatwierdzenie powiodło się, co to znaczy?” Powstrzymaj się tutaj. Zatwierdzenie synchroniczne oznacza, że ​​zakończyło się nasze lokalne i zdalne (przynajmniej na jednej replice), tj. popełniliśmy coś na maszynie, jeśli mamy tryb replikacji synchronicznej, to zmiany te zostały pomyślnie zatwierdzone, są widoczne dla kolejnych żądań na maszynie lokalnej, są też widoczne na maszynie zdalnej (przynajmniej jednej). Oznacza to, że w przypadku wystąpienia standardowej sytuacji awaryjnej, tj. łom wleciał w jeden z serwerów i przebił wszystko na wylot - od procesora po samą śrubę, po czym mimo to dane nie tylko są kopiowane na określony zdalny serwer, ale także w dodatku mogą natychmiast, bez żadnych dodatkowe opóźnienia, uczestniczyć w kolejnych transakcjach.

To wszystko jest ogólną terminologią i nie ma absolutnie nic wspólnego z MySQL. W każdym systemie rozproszonym będzie to zorganizowane w ten sposób.

Zatwierdzenie asynchroniczne - brak dodatkowych gwarancji, w zależności od szczęścia.

Zatwierdzenie półsynchroniczne jest fajnym rozwiązaniem pośrednim, wtedy właśnie minęło nasze lokalne zatwierdzenie, o zdalnym zatwierdzeniu nic nie wiadomo - może slave dogonił, a może nie, ale przynajmniej otrzymaliśmy potwierdzenie, że te dane są gdzieś potem odlecieli, zostali tam przyjęci i prawdopodobnie zapisali się.

O serwerach nagrywających. Jakie są rodzaje replikacji?

Klasyka master-slave, wszystkie zmiany przelewane są na jeden serwer, po czym kopiowane są na masę replik.

Mistrz-mistrz prawdziwy – kiedy zmiany napływają na grupę mistrzów jednocześnie i jakoś od jednego do drugiego, od drugiego do trzeciego i pomiędzy nimi wszystkimi, co rodzi zarówno szereg radości, jak i szereg automatycznych problemów. Jasne jest, że jeśli masz jedną „złotą kopię” i kilka z niej replik, które powinny (idealnie - natychmiast) powtórzyć tę „złotą kopię”, to wszystko jest stosunkowo proste z punktu widzenia sposobu przesyłania danych tam i z powrotem i co zrobić z każdą konkretną kopią. W przypadku master-master zaczyna się ciekawy „ból głowy” i to, podkreślam, nie konkretnie w przypadku MySQL, ale czysto teoretyczny. Co zrobić, jeśli na dwóch węzłach jednocześnie próbowano przeprowadzić tę samą transakcję, która zmienia te same dane i dla uproszczenia przykładu zmienia je na różne sposoby. Oczywiste jest, że nie możemy zastosować tych dwóch zmian jednocześnie. W momencie, gdy zaczynamy coś zmieniać w jednym węźle, w drugim węźle nie ma jeszcze nic. Konflikt. Jedna z transakcji będzie musiała zostać wycofana. Ponadto osobne „tańce” rozpoczynają się od sprawdzania zegarków itp.

Ciekawostka – nawet opcja, w której ostatecznie wszystkie zmiany ze wszystkich masterów powinny stopniowo rozprzestrzeniać się wszędzie, nadal nie pomoże w utrzymaniu tej samej przepustowości zapisu. Szkoda, ale tak właśnie jest.

Fajną opcją jest „Master-slave + żądania routingu”. To fajne, bo łatwo go zaprogramować w środku, masz jedną główną kopię, replikujesz ją na kilka maszyn. Jest to znacznie prostsze niż w środowisku master-master, gdzie wszyscy mają równe prawa itp., ale z punktu widzenia aplikacji nadal wygląda na to, że masz dużo punktów zapisu. Docierasz do dowolnego węzła, on wie, dokąd Cię skierować i skutecznie Cię wyznacza. Cóż, odczyty są skalowane – na tym polega radość replikacji. Zawsze możesz przeczytać wszystko ze wszystkich punktów.

Teraz bliżej baz danych, „magicznych” formatów opartych na instrukcjach, wierszach itp. O formacie zmian.

Co możesz zrobić? Możesz przesyłać same zapytania lub tylko zmodyfikowane wiersze. Podkreślam, że choć nie zagłębiliśmy się jeszcze w dżunglę MySQL, może to zrobić dowolny DBMS, który ma zapytania generujące dużą (lub niezbyt dużą) liczbę zmian, tj. aktualizowanie wielu danych. Powstaje pytanie – co dokładnie będziemy kopiować? Możesz wysyłać same żądania tam i z powrotem między węzłami lub możesz wysyłać tylko zmienione dane. To ciekawe, że oba sposoby są bardzo złe! Nadal możesz spróbować wymieszać.

Jeszcze jedna uwaga na temat rodzajów replikacji. O modelu dystrybucji. Prawdopodobnie gdzieś model oparty na Push nie wymarł jeszcze całkowicie, gdy węzeł, który dokonał zmian, ma obowiązek wysłać je do wszystkich pozostałych węzłów. Z punktu widzenia programowania i śledzenia stanów jest to nadal kłopotliwe, dlatego reguły typu pull-based.Pobieranie aktualizacji z tego czy innego węzła jest znacznie łatwiejsze do zaprogramowania niż monitorowanie chaotycznego skupiska swoich replik w jednym węźle.

Wprowadzono pewne ogólne terminy. Przejdźmy do tego jak zrobiliśmy to w MySQL.

MySQL sam w sobie jest rodzajem oszustwa. Istnieje warstwa logiczna zwana MySQL, która zajmuje się wszelkiego rodzaju ogólnymi sprawami odizolowanymi od przechowywania danych – siecią, optymalizatorem, pamięciami podręcznymi itp. Specyficzna warstwa fizyczna odpowiedzialna za przechowywanie danych znajduje się piętro niżej. Istnieje kilka wbudowanych, a niektóre instalowane za pomocą wtyczek. Ale nawet wbudowane MyISAM, InnoDB itp. żyć w warstwie fizycznej. Architektura wtyczek jest fajna, można wybrać nowy silnik, ale od razu pojawia się pewna nieoptymalność. W zasadzie transakcyjny dziennik zapisu z wyprzedzeniem i (WAL), który i tak zapisuje fizyczna warstwa pamięci, dobrze byłoby wykorzystać do replikacji i jeśli system wie, że istnieje pewna warstwa fizyczna lub jest z nią wystarczająco dobrze połączony warstwa fizyczna, wówczas byłoby możliwe nie pisanie osobnego dziennika na poziomie logicznym, ale użycie tego samego WAL... Ale w przypadku MySQL jest to koncepcyjnie niemożliwe lub jeśli zmienisz interfejs w PSE, aby stało się to koncepcyjnie możliwe , wtedy będzie dużo pracy.

Replikacja realizowana jest na poziomie samego MySQL. I jest w tym dobro - oprócz jednego logu w postaci głęboko wewnętrznych danych silnika składowania, istnieje log mniej lub bardziej logiczny, być może na poziomie wyciągów, który jest prowadzony oddzielnie od tego silnika. „dodatkowe” zabezpieczenia itp. ponadto, ponieważ nie ma wewnętrznych ograniczeń, możesz zrobić dowolną kreatywną rzecz, np. wymianę silnika w locie.

Pod tym względem MySQL 4.1 zaimplementował: master-slave, pull-based, ściśle asynchroniczny i ściśle SBR. Jeśli utknąłeś w starożytnej erze 4.x, prawdopodobnie jest z tobą źle. Wersje 5.x mają już prawie 10 lat – czas na aktualizację.

Zabawnie jest śledzić wersje, jak ludzie nadepnęli na wszelkiego rodzaju grabie, a gdy już nic nie dało się zrobić, przykręcali do tych grabi nowe grabie, żeby życie nie było tak bolesne. Tak więc w wersji 5.1 dodano RBR, aby zrekompensować nieuniknione problemy z SBR, i dodano tryb mieszany. W wersji 5.6 dodaliśmy jeszcze kilka fajnych rzeczy: półsynchronizację, opóźnione urządzenie podrzędne, GTID.

Jeszcze jedna rzecz. Skoro MySQL to z jednej strony swego rodzaju wspólna warstwa, a z drugiej cała masa silników wymiennych, w tym wbudowanych, to od pewnego momentu powstaje boski klaster NDB, o którym mówią fajne rzeczy. Istnieje całkowicie synchroniczna replikacja master-master, bardzo przystępna baza danych w pamięci... Jednak jest jedno zastrzeżenie - gdy tylko zaczniesz szukać osób, które korzystają z klastra NDB na produkcji, takich osób jest bardzo mało.

Co robi master, gdy zdecydujesz się włączyć replikację? W masterze odbywa się sporo dodatkowych ruchów. Jak zwykle odbieramy żądania przez sieć, analizujemy je, wysyłamy transakcje, rejestrujemy je itp. Oprócz tego na poziomie logicznym MySQL master zaczyna prowadzić dziennik binarny - plik, nie do końca tekstowy, do którego wlewane są wszystkie zmiany. Master może również wysyłać te logi przez sieć. Wszystko jest bardzo proste i wydaje się działać.

Co robi niewolnik? Lepiej nie wysyłać zmian do slave'a, bo można wplątać się w coś niezrozumiałego. Niewolnik ma trochę więcej pracy. Oprócz prowadzenia jednego dodatkowego dziennika i wysyłania go na żądanie, istnieje również wątek, który trafia do zdalnego mastera, być może nawet więcej niż jednego, i pobiera stamtąd dziennik binarny. Rozwiązanie jest takie: „przejdźmy do i z kilku Remote Masters „pobieranie różnych logów" jest niejednoznaczne. Z jednej strony nie jest źle, z drugiej jednak od razu widać rozbieżność. Nie da się tak po prostu fizycznie skopiować plików przez SCP, jeden log masz już na serwerze, zawiera twoje własne pozycje, lokalnie przeciągamy je po siatce, umieszczamy w osobnym logu, jest też uruchomiony osobny wątek i próbuje odtworzyć te lokalne logi.Najbardziej piekielne jest moim zdaniem to, że aż do wersji 5.6 identyfikacja konkretnej transakcji w logu następuje po nazwie pliku i pozycji na masterze.Ciekawe rozwiązanie.

Oto ścieżka zapisu, którą przyjmuje prosta wstawka bez replikacji:


Aplikacja połączyła się z serwerem, umieść ją w tabeli i wyjdź.

W przypadku replikacji istnieje kilka dodatkowych kroków:


Aplikacja pisząca trafia do mastera w ten sam sposób, ale dodatkowo dane te lądują w takiej czy innej formie w logu binarnym, następnie są pobierane przez sieć do logu przekaźnikowego, po czym z logu przekaźnikowego są stopniowo odtwarzane (jeśli mamy szczęście i niewolnik się nie laguje, od razu odtwarzamy go ponownie) w tabelkę na niewolnika, po czym wszystko jest dostępne w czytniku.

To, co dokładnie trafi do dziennika binarnego, zależy od ustawień SBR/RBR/mieszanych. Skąd to wszystko wyrasta? Wyobraźmy sobie siebie jako bazę danych. Otrzymaliśmy proste żądanie „zaktualizuj jeden konkretny rekord” – UPDATE users SET x=123 WHERE id=456

Co zapisać w logu binarnym? W zasadzie wszystko jest takie samo, naprawdę. Możemy spisać krótką prośbę lub (i zaktualizował jeden rekord) możemy jakoś zapisać zmianę w takim czy innym formacie.

Kolejna sytuacja. Wyobraźmy sobie, że otrzymaliśmy to samo żądanie, które samo w sobie jest niewielkie, ale zmienia dużo danych - UPDATE users SET bonus=bonus+100

Jest tylko jedna skuteczna opcja - napisać samo żądanie, ponieważ żądanie ma dokładnie 32 bajty i może zaktualizować dowolną liczbę rekordów - 1000, 100 000, 1 000 000, tyle, ile chcesz... Pisanie jest nieefektywne zmienił zapisy w dzienniku.

Co się stanie jeśli w logu umieścimy takie proste żądanie: „wyłączmy wszystkich użytkowników, którzy dawno się nie logowali” – UPDATE users SET wyłączona=1 WHERE last_login

Nagle nadchodzi horror. Problem w tym, że jeśli samo żądanie jest idealnie replikowane, to po pierwsze, czas pomiędzy obydwoma węzłami nigdy nie jest synchroniczny, w dodatku ze względu na to, że ścieżka zapisu jest tak długa, w momencie odtworzenia tego „TERAZ” będzie się różnić. Replika nagle odbiega od wzorca, a wszelkie późniejsze zmiany, formalnie rzecz biorąc, nie są już bezpieczne i mogą prowadzić do czegokolwiek.

Ogólnie rzecz biorąc, w przypadku takich zapytań, niezależnie od ilości zmienionych danych, idealnie byłoby, gdyby konieczne było skopiowanie samych linii. W tym konkretnym przypadku nie można skopiować samych linii, ale naprawić stałą i zapisać w dzienniku nie „TERAZ”, ale konkretny znacznik czasu, którego używał master w czasie replikacji.


Zabawne fakty, których przypadkowo dowiesz się, nurkując w dżungli replikacji. Co więcej, możesz nurkować płytko – od razu na nie wpadniesz. W losowej kolejności są to:

  • Master jest wielowątkowy, ale slave nie. Oczywiste jest, że jeśli mistrz przeleje obciążenie na cztery rdzenie, niewolnik nie ma czasu na przelanie tego obciążenia na jeden rdzeń. Wszystko jest dość złe;
  • Stan urządzenia podrzędnego jest określany na podstawie nazwy pozycji w pliku głównym. Pomyśl o tym – o stanie jednego węzła w klastrze decyduje nazwa pliku i pozycja w tym pliku na innym węźle w klastrze, z którym wszystko może się zdarzyć z dowolnego powodu!
  • „oszczędzanie” RBR. Okazuje się, że domyślnie zapisywane są tam pełne obrazy wierszy przed/po, tj. zmieniliśmy jedną kolumnę w ciągu pięciu kilobajtów, ups! – 10 KB ruchu i 20-40 bajtów narzutu dla tej linii, a potem ups! – tam jest taka odważna linijka z poprzedniej wersji, oops! – po nim pojawia się wersja z nowymi wartościami. Administratorzy wyją zgodnie! Jest to jednak po prostu niesamowite z punktu widzenia niektórych wypaczonych aplikacji, np. zewnętrznych czytników, które próbują się podłączyć do serwera MySQL, pobrać z niego dane i coś z nimi zrobić, np. wkleić je w całości indeks tekstowy. Choć jest to złe z punktu widzenia administrowania bazą danych, w której jedna zmiana na trzy bajty generuje 10 KB ruchu na śrubie, a następnie 10 KB ruchu sieciowego na każdego urządzenia podrzędnego, jest równie dobre dla wszelkich systemów takich jak jako wyszukiwanie pełnotekstowe, jak Sphinx, w którym nie ma lokalnej kopii danych i nie ma potrzeby implementowania MySQL od zera. W MySQL 5.6 zdali sobie z tego sprawę i stworzyli binlog_row_image (ale domyślnie pełny, a nie minimalny lub noblob).

Krótko mówiąc, nie wszystko jest sprytnie ułożone – kij, lina, jedna kłoda, druga kłoda. I nawet w tym dzienniku choroby „dziecięce” są dość zabawne:


Dla osoby, która od dwóch dni korzysta z replikacji, to wszystko jest przerażające i trudne. Ale wiedząc, jakie to proste, w zasadzie jasne jest, jak z tym żyć:

  • Po pierwsze, nie wierzymy w opóźnienia;
  • Uważnie przyglądamy się ustawieniom, zastanawiamy się, czego chcemy - SBR, RBR itp.

I lepiej ustawić to od razu, żeby później nie musieć porządkować dziwnego mielonego mięsa.

W sytuacji „log jest uszkodzony, pozycje się rozeszły, nie wiadomo, co się dzieje” istnieje pewien zestaw narzędzi - patrzymy na zdarzenia, staramy się zrozumieć, która transakcja już przeszła, a która nie, czy to całość można zapisać lub przywrócić itp. Jeśli GTID „Jeśli udało ci się to włączyć wcześniej, życie staje się łatwiejsze.

Kolejny punkt obserwacji replikacji. Ciekawie jest zobaczyć, jak wewnętrzna, krzywa konstrukcja prowokuje nie tylko konkurencję, ale także tworzenie dodatkowych produktów. Mówi się, że „magiczny” replikator wolframu dobrze rozwiązuje problem „jednonitkowy slave jest zły” i gdyby nie nieodłączne trudności, nie byłoby dodatkowego produktu, który pozwalałby na wykorzystanie tego mechanizmu, przesyłanie danych do z jednej strony innych systemów, a z drugiej strony rozwiązuje szereg problemów wbudowanych w istniejący system.

Jak zwykle nie da się nic doradzić. Niektórym to pomaga, inni dużo plują. Mówią jednak, że są sytuacje, w których Tungsten dobrze radzi sobie z nieuniknionym jednowątkowym opóźnieniem. Jestem pewien, że istnieją inne interesujące sztuczki, ale wewnętrzny jednowątkowy niewolnik jest trudny.

Co zrobić jeśli z jakiegoś powodu użyłeś replik jako kopii zapasowej? Myślę, że trzeba bić głową w mur, bo replika i kopia zapasowa to dwie różne rzeczy. Jeśli jednak jesteś kreatywny i używasz całkiem nowej wersji, opóźniona replikacja z jednej strony Cię uratuje, ale z drugiej strony, jeśli nie wykonasz pełnych kopii zapasowych, i tak nic Cię nie uratuje.

Następny jest kolejny element kreatywności. Nietrudno sobie wyobrazić sytuację, w której master zapełnił logami cały dysk w chmurze 10 PB lub zapełnił całą sieć wysyłając te logi, a my 90% tych aktualizacji nie potrzebujemy, bo interesuje nas replikacja, na przykład jedna tabela na widoku lub jedna baza danych na widoku i domyślnie wszystko jest wlewane do dziennika binarnego - wszystkie zmiany we wszystkich bazach danych, we wszystkich tabelach, we wszystkim. Rozwiązanie ponownie zadziwia swoją kreatywnością. Z jednej strony dostępne są cztery ustawienia - (binlog|replicate)_(do|ignore)_db, które pozwalają filtrować po masterze, co będzie zapisywane w logu, a co będzie ignorowane. Odpowiednio na niewolniku pozwala ci zrobić to samo. Te. na urządzeniu głównym możemy filtrować to, co trafia do dziennika binarnego - do tego lejka, który następnie łączy się z siecią, a na urządzeniu podrzędnym odpowiednio możemy umieścić filtr przychodzący na tym, co przychodzi z sieci. Lub zapisz tylko część danych na dysku, a następnie odtwórz ponownie tylko część danych na urządzeniu podrzędnym. Nagle nawet w tej prostej historii wkrada się horror, bo kombinacja - korzystamy z jednej bazy danych i aktualizujemy tabelę w innej bazie za pomocą ciekawej składni - jakoś się to zachowuje... A jak dokładnie się zachowa, nie wiadomo, bo różne filtry są uruchamiane w różnym czasie.

Nie ma wbudowanych miłych rzeczy zwanych „ponownym wyborem mistrza, jeśli nagle umrze”, trzeba to podnieść rękami. Brak narzędzi do zarządzania klastrami – to moim zdaniem dobrze – rodzi konkurencję, powoduje powstawanie dodatkowych produktów. W rzeczywistości, jeśli bardzo fajna replikacja master-master działała idealnie w zwykłym MySQL lub przynajmniej automatyczne odzyskiwanie po awariach, to po co cały klaster Galera, Percona/MariaDB itp. miałby być potrzebny?

Jeszcze kilka trików. Ciekawą implementacją jest replikacja, która z jednej strony jest prosta jak kij i lina, bez żadnych kontroli z jednej strony, a z drugiej bez żadnych narzędzi ułatwiających zarządzanie klastrem replikującego się niewolnika. To jest złe. Ale można z tego ręcznie wyrzeźbić tak ciekawe konfiguracje, że wszyscy, którzy później przyjdą i rozbiorą to za Ciebie, wzdrygną się.

Konfiguracja nr 1. Master-master „na kolanach” w stylu MySQL odbywa się w następujący sposób:


Przerażające jest to, ilu idiotów jest na świecie! Google „replikacja MySQL master-master” – co drugi link jest taki. Piekło i Holokaust.

Focus nr 2 – niewolnik typu catch-all – jest przyjemniejszy. Nie ma zbędnych kontroli – co od kogo leci, kto to dostaje i co z tym zrobić. Dzięki temu można zrobić śmieszne rzeczy, np. slave, na który precyzyjnie scalona zostanie albo część danych z grupy serwerów, albo precyzyjnie scalone wszystkie dane ze wszystkich serwerów - serwer ze wszystkimi kopiami zapasowymi. Ale powtarzam, istnieje replikacja, tj. Istnieje pewne podstawowe narzędzie, które kopiuje tabelę A zamiast B i to wszystko.

I na koniec trik nr 3 – wymieniamy wszystko. Pamiętajmy, że replikacja żyje na poziomie logicznym, który nie jest w żaden sposób powiązany z poziomem fizycznego przechowywania. Dzięki temu możesz tworzyć niezwykle ciekawe, dziwne rzeczy. Możesz zmienić silnik „w locie” z niejasnych powodów - oto prawdziwa historia, która, jak mówią, replikacja z baz danych InnoDB do tabel MyISAM tylko po to, aby jakoś działało wyszukiwanie pełnotekstowe. Istnieje kreatywny trik zwany „modyfikację schematu poprzez replikację”. Nie rozumiem, co to jest tłuszcz, ale są takie sztuczki. Cóż, istnieje przejrzysty i interesujący tryb działania zwany „aktualizacją wersji paranoicznej poprzez replikację”.

Podczas raportu dowiedzieliśmy się:


Niemniej jednak możesz żyć z tym piekłem, jeśli przynajmniej z grubsza zrozumiesz, jak to działa.

Głównym przesłaniem jest to, że:


W 2015 roku na konferencji HighLoad++ Junior Andrey Aksenov przeczytał nową wersję swojego raportu na temat urządzenia replikacyjnego w MySQL. Rozszyfrowaliśmy to również na naszym blogu.

Termin replikacja odnosi się do mechanizmu synchronizacji wielu kopii danych, co zwiększa bezpieczeństwo informacji, odporność na awarie i wydajność systemu. Uderzającym przykładem jest replikacja bazy danych pomiędzy dwoma serwerami.

Replikacja MySQL typu Master-Slave

W terminologii Master-Slave, master jest głównym serwerem z bazą danych; zapisuje dane do bazy danych, ale odczyt jest rozdzielany pomiędzy master i slave w zależności od obciążenia systemu, co zwiększa odporność na awarie i wydajność. Dodatkowo dzięki takiemu podejściu kopia bazy danych jest zawsze pod ręką i można ją odtworzyć w przypadku awarii jednego z serwerów.

W jakich sytuacjach może być potrzebny serwer podrzędny? Przykładowo, gdy do bazy danych przychodzi duża ilość danych do zapisania, a serwer master po prostu nie ma czasu na ich odczytanie i klient musi czekać na koniec zapisu, czego można uniknąć dzięki serwerowi slave.

Możliwe są sytuacje, gdy nastąpi awaria serwera master; w tym przypadku serwer slave przejmuje wszystkie funkcje mastera i pracuje samodzielnie do czasu jego przywrócenia. Klient najprawdopodobniej niczego nie zauważy, a na pewno nie będzie czekał godzinę, dwie, trzy, aż technik go naprawi.

Konfiguracja replikacji nie jest wcale trudna, ponieważ mechanizm jest wbudowany w MySQL od samego początku.

Konfiguracja na serwerze głównym

Zacznijmy od edycji pliku konfiguracyjnego my.cnf, który najczęściej znajduje się w /etc/mysql/my.cnf. Musisz znaleźć i odkomentować (usunąć #) lub napisać takie linie.

Adres powiązania = 0.0.0.0 identyfikator serwera = 1 log_bin = /var/log/mysql/mysql-bin.log

Ważny! Jeżeli adres powiązania został już zarejestrowany, należy go zmienić, w przeciwnym razie nawiązanie połączenia między serwerami nie będzie możliwe.

Zaraz po tym zrestartujemy bazę danych na serwerze.

/etc/init.d/mysql uruchom ponownie

Teraz musimy utworzyć użytkownika z uprawnieniami do replikacji naszej bazy danych; można to zrobić z poziomu roota w konsoli MySQL za pomocą polecenia

PRZYZNAJ REPLIKACJĘ SLAVE NA *.* „slave_user”@”%” IDENTYFIKOWANĄ PRZEZ „slave_password”; PRZYWILEJE FLUSH;

Gdzie zamiast „slave_user” i „slave_password” musisz wpisać login i hasło dla slave.

Spójrzmy teraz na dane podstawowe

POKAŻ STATUS GŁÓWNY;

Wartości kolumn Plik I Pozycja musisz pamiętać, zostaną one użyte podczas konfigurowania urządzenia podrzędnego i do tego teraz przechodzimy.

Konfiguracja na serwerze Slave

Pierwszym krokiem jest utworzenie bazy danych o tej samej nazwie, co ta, którą będziemy replikować. Jest to ważny krok i nie należy go zaniedbywać. Następnie przejdź do znanego nam już pliku konfiguracyjnego mój.cnf i napisz ustawienia.

Identyfikator serwera = 2 przekaźnik-log = /var/log/mysql/mysql-relay-bin.log bin-log = /var/log/mysql/mysql-bin.log

Ważny! W bin-log zapisana jest ścieżka do bin-log na serwerze Mester . Identyfikator serwera musi różnić się od identyfikatora głównego, wygodnie jest ustawić go na jeszcze 1.

ZMIEŃ MASTER NA MASTER_HOST="1.1.1.1", MASTER_USER="slave_user", MASTER_PASSWORD="slave_password", MASTER_LOG_FILE = "mysql-bin.000001", MASTER_LOG_POS = 107; URUCHOM PODRZĘDNY;

Gdzie host to adres IP mastera, login i hasło odpowiadają tym, które utworzyliśmy na masterze, master_log_file i master_log_pos są wypełnione informacjami z ostatni element konfiguracji serwera głównego .

Od tego momentu wszystkie zmiany w bazie danych zostaną przeniesione z urządzenia master na urządzenie slave.

Sprawdzanie statusu replikacji

Oprócz polecenia SHOW MASTER STATUS; Podobny istnieje dla slave'a SHOW SLAVE STATUS\G, który wyświetli tabelę z informacjami. Głównym sygnałem, że serwery się połączyły i działają poprawnie, jest obecność takich linii

Nie tak dawno temu poproszono mnie o rozmowę replikacja w MySQL. Postanowiłem, że ten temat może być przydatny dla wielu, dlatego w tym artykule omówię czym jest replikacja w MySQL, kiedy jest potrzebna i jak ją skonfigurować.

Głównym zadaniem replikacji jest połączyć moc kilku serwerów. Załóżmy, że Twoja witryna internetowa ma serwer dedykowany, ale z biegiem czasu jest ona coraz częściej odwiedzana i nie jest już w stanie wytrzymać obciążenia. W rezultacie serwer zaczyna zwalniać i regularnie ulegać awariom. Najłatwiej jest kupić mocniejszy serwer i większość ludzi tak robi. Ale prędzej czy później przychodzi taki moment, że koszt podniesienia ceny serwera nie odpowiada wzrostowi jego wydajności, więc bardziej opłaca się kupić 2 różne serwery za mniejsze pieniądze.

W rezultacie Twoja baza danych będzie znajdować się na dwóch serwerach jednocześnie. Kiedy jeden serwer główny (inaczej serwer główny) nie daje sobie już rady, przełącza się na serwer zapasowy.

Wszystko żądania aktualizacji bazy danych zawsze trafiają do serwera głównego. Po zaktualizowaniu serwera głównego umieszcza informację na ten temat w osobnym pliku, skąd serwery podrzędne pobierają wszystkie informacje. Jednak operacje próbkowania, które zwykle stanowią większość i są najwolniejsze, można już przenieść na serwery podrzędne, ponieważ dane są w obu przypadkach takie same.

Teraz rozwiążmy to jak skonfigurować replikację w MySQL:

  1. Zainstaluj najwięcej najnowsze wersje MySQL do wszystkich serwerów.
  2. Utwórz użytkownika z uprawnieniami na serwerze głównym ZAMIANA NIEWOLNIKA. Jako adres, z którego może się połączyć, podaj „ Wszystko".
  3. Zatrzymaj wszystkie serwery.
  4. W ustawieniach MySQL'a(w pliku mój.cnf) W rozdziale dodaj następujące linie: log-bin
    id_serwera=1 Proszę o tym pamiętać identyfikator serwera musi być inny na wszystkich serwerach. W rzeczywistości to właśnie odróżnia jeden serwer od drugiego.
  5. Na serwerach podrzędnych dodaj do ustawień MySQL'a następujące linie: master-host=master_host_name
    master-user=login utworzonego_użytkownika
    master-password=hasło utworzonego_użytkownika
    master-port=port_do_łączenia_z_serwerem_głównym
    id-serwera=id_tego_serwera_podrzędnego
  6. Przesuń wszystkie bazy z serwera głównego do urządzeń podrzędnych.
  7. Uruchomić serwer główny, a następnie wszyscy niewolnicy.

Replikacja to mechanizm synchronizacji zawartości wielu kopii obiektu. Proces ten polega na kopiowaniu danych z jednego źródła do wielu innych i odwrotnie.

Oznaczenia:

  • master - główny serwer, którego dane wymagają zduplikowania;
  • replika - naprawiony serwer przechowujący kopię danych podstawowych

Aby skonfigurować replikację w MySQL należy postępować zgodnie z sekwencją czynności opisaną poniżej, jednak nie jest to dogmat i parametry mogą się zmieniać w zależności od okoliczności.

Na głównym serwerze edytuj plik my.cnf i dodaj następujące wiersze do sekcji mysqld:

Identyfikator serwera = log-bin = mysql-bin log-bin-index = mysql-bin.index log-error = mysql-bin.err przekaźnik-log = przekaźnik-bin przekaźnik-log-info-plik = przekaźnik-bin. informacje o przekaźniku-log-index = przekaźnik-bin.index wygaśnięcie_logs_days=7 binlog-do-db =

  • - unikalny identyfikator serwera MySQL, liczba z zakresu 2 (0-31)
  • - nazwa bazy danych, o której informacja zostanie zapisana do logu binarnego; jeżeli jest kilka baz to każda wymaga osobnej linii z parametrem binlog_do_db

Na urządzeniu podrzędnym edytuj plik my.cnf i dodaj następujące wiersze do sekcji mysqld:

Identyfikator serwera = główny host = główny użytkownik główny = hasło główne replikacji = hasło port główny = 3306 przekaźnik-log = pojemnik przekaźnikowy przekaźnik-log-info-plik = przekaźnik-log.info przekaźnik-log-indeks = przekaźnik-log.index replikacja-do-db =

Na serwerze głównym dodaj użytkownika replikacji z uprawnieniami do replikacji danych:

UDZIEL REPLIKACJI SLAVE ON *.* DO „replikacji”@„repliki” IDENTYFIKOWANEJ PRZEZ „hasło”

Zablokujmy replikowanym bazom danych na głównym serwerze możliwość zmiany danych programowo lub przy użyciu funkcjonalności MySQL:

Mysql@master> OPUSZAJ TABELE Z BLOKADĄ ODCZYTU; mysql@master> USTAW GLOBALNY tylko do odczytu = WŁ.;

Aby odblokować użyj polecenia:

Mysql@master> USTAW GLOBALNY tylko do odczytu = WYŁ;

Zróbmy kopie zapasowe wszystkich baz danych na serwerze głównym (lub tych, których potrzebujemy):

Root@master# tar -czf mysqldir.tar.gz /var/lib/mysql/

lub używając narzędzia mysqldump:

Root@master# mysqldump -u root -p --lock-all-tables > dbdump.sql

Zatrzymajmy oba serwery (w niektórych przypadkach można się bez tego obejść):

Root@master# mysqlamdin -u root -p zamknięcie root@replica# mysqlamdin -u root -p zamknięcie

Przywróćmy zreplikowane bazy danych na serwerze podrzędnym, kopiując katalog. Przed rozpoczęciem replikacji bazy danych muszą być identyczne:

Root@replica# cd /var/lib/mysql root@replica# tar -xzf mysqldir.tar.gz

lub mysql, nie było potrzeby zatrzymywania mysql na serwerze podrzędnym:

Root@replika# mysql -u root -p< dbdump.sql

Uruchommy mysql na serwerze głównym (a następnie na serwerze podrzędnym, jeśli to konieczne):

Root@master# /etc/init.d/mysql start root@replica# /etc/init.d/mysql start

Sprawdźmy działanie serwerów master i slave:

Mysql@replica> uruchom urządzenie slave; mysql@replica> POKAŻ STATUS SLAVE\G mysql@master> POKAŻ STATUS MASTER\G

Na serwerze slave sprawdź logi w pliku master.info, powinien on zawierać żądania zmiany danych w bazie danych. Zatem ten plik binarny należy najpierw przekonwertować na format tekstowy:

Root@replica# mysqlbinlog master.info > master_info.sql

Jeśli wystąpią błędy, możesz użyć poleceń:

Mysql@replica> zatrzymaj niewolnika; mysql@replica> ZRESETUJ PODRZĘDNY; mysql@master> ZRESETUJ MASTER;

i powtórz wszystkie kroki zaczynając od zablokowania baz danych.

Aby dodać serwery replikacji na gorąco, możesz użyć następującej składni:

Mysql@replica> POKAŻ STATUS SLAVE\G mysql@master> POKAŻ STATUS MASTER\G mysql@replica-2> ZMIEŃ MASTER NA MASTER_HOST = "master", MASTER_USER ="replikacja", MASTER_PASSWORD = "hasło", MASTER_LOG_FILE ="mysql- bin.000004 ", MASTER_LOG_POS = 155; mysql@replica-2> URUCHOM SLAVE;

Informacje ze statusów pokażą położenie i nazwę bieżącego pliku logu.

W przypadku replikacji asynchronicznej aktualizacja z jednej repliki jest propagowana do innych po pewnym czasie, a nie w tej samej transakcji. Zatem replikacja asynchroniczna wprowadza opóźnienie, czyli czas oczekiwania, podczas którego poszczególne repliki mogą nie być faktycznie identyczne. Ale ten typ replikacji ma również pozytywne strony: serwer główny nie musi się martwić o synchronizację danych, można zablokować bazę danych (na przykład w celu utworzenia kopii zapasowej) na maszynie podrzędnej, bez problemów dla użytkowników.

Lista wykorzystanych źródeł

  1. Habrahabr.ru - Podstawy replikacji w MySQL (http://habrahabr.ru/blogs/mysql/56702/)
  2. Wikipedia (http://ru.wikipedia.org/wiki/Replication_(computing_technology))

Korzystając z jakichkolwiek materiałów z serwisu w całości lub w części, należy wyraźnie wskazać link jako źródło.

Replikacja danych mysql pozwala na posiadanie dokładnej kopii bazy danych z jednego serwera - serwera głównego (serwer wiodący) na jednym lub większej liczbie innych serwerów (serwer podrzędny). Domyślnie replikacja Mysql jest asynchroniczna.
Oznacza to, że serwer główny nie ma kontroli i nie wie, czy serwery podrzędne czytają plik dziennika i czy robią to poprawnie.
Istnieją również inne rodzaje synchronizacji, synchroniczna i półsynchroniczna, w których procesy te są kontrolowane.
W zależności od ustawień można replikować zarówno całe bazy danych, jak i pojedyncze tabele bazy danych.

Do czego możesz wykorzystać replikację:
1. Rozkład obciążenia pomiędzy hostami w celu poprawy wydajności.
W takim schemacie węzeł główny będzie wykonywał operacje odczytu i zapisu, węzły posiadające abonament na węzeł główny zapewnią bazę do odczytu, tym samym odciążymy serwer główny od operacji odczytu
2. Bezpieczeństwo danych i łatwość konserwacji, ponieważ węzeł podrzędny zawiera dane tylko do odczytu, zmiany danych abonenta będą ograniczone, łatwość konserwacji - możliwość uruchamiania procesów obsługujących bazę danych bez zakłócania działania aplikacji
3. Dystrybucja danych na duże odległości. Możesz utworzyć kopię danych na dowolnym hoście, niezależnie od jego lokalizacji
mysql obsługuje następujące metody replikacji:
Tradycyjna – metoda opiera się na replikacji zdarzeń z binarnego pliku dziennika głównego i wymaga plików dziennika. Pozycje pomiędzy serwerami głównymi i podrzędnymi muszą być zsynchronizowane.
Metoda wykorzystująca globalne identyfikatory transakcji GTID (metoda transakcyjna)
mysql obsługuje następujące typy synchronizacji:
asynchroniczny (synchronizacja jednokierunkowa)
półsynchroniczny (częściowa kontrola abonentów)
synchroniczny (pełna kontrola abonentów)

Konfigurowanie tradycyjnej metody replikacji bazy danych Mysql

Zasada działania
Serwer główny zawiera kosz pliki log, które rejestrują wszystkie zmiany zachodzące w bazie danych master, plik opisujący nazwy kosz plików, a także pozycję w logu, w której zapisano ostatnie dane podstawowe
Węzeł podrzędny otrzymuje od urządzenia nadrzędnego dane zawierające informacje o nazwach kosz plików i pozycji w pliku dziennika.

Konfiguracja kreatora
moje.ini musi zawierać unikalny identyfikator - liczbę od 1 do 2 do potęgi 32 - 1, identyfikator serwera.
Domyślnie identyfikator serwera=0, co oznacza, że ​​nie akceptujesz subskrypcji z serwerów podrzędnych

log-bin=mysql-bin
identyfikator serwera=1

Na początek wystarczą te dwie linie
Uwaga: jeśli jednak używany jest InnoDB, zaleca się dodatkowo dodanie
innodb_flush_log_at_trx_commit=1
sync_binlog=1

Musisz sprawdzić, czy możliwość pracy z siecią nie jest wyłączona i czy ustawiony jest parametr pomijania sieci
Serwer podrzędny łączy się z serwerem głównym za pomocą nazwy użytkownika i hasła, dlatego najpierw tworzymy użytkownika na serwerze głównym
UTWÓRZ UŻYTKOWNIKA repl@%.mydomain.com IDENTYFIKOWANY PRZEZ hasło slave;
PRZYZNAJ PODRZĘDNY REPLIKACJI NA *.* DO repl@%.mydomain.com;

Spójrzmy na warunek
POKAŻ STATUS MASTERA
Jeżeli procedura tworzenia logów binarnych została już uruchomiona, to dla tabel InnoDB należy najpierw zablokować tabele w jednej z sesji
STOLIKI PODTYNKOWE Z BLOKADĄ ODCZYTU;
Jeśli opuścisz sesję, blokada tabeli zostanie automatycznie zwolniona
W innej sesji otrzymujemy wartości nazw kosz log i pozycja
Obie wartości reprezentują współrzędne replikacji, od których serwer podrzędny musi rozpocząć odczyt z pliku w żądanej lokalizacji, aby rozpocząć replikację.
Następny krok zależy od tego, czy na serwerze slave znajdują się dane, dane z mastera
Jeśli istnieją, pozostawiamy tabele zamknięte i tworzymy wysypisko(jest to zalecany sposób podczas korzystania z InnoDB)
Typ bazy danych można sprawdzić za pomocą polecenia
mysqlshow -u użytkownik_mysql -p -i nazwa-bazy danych
Jeśli baza danych jest zapisana w plikach binarnych, to można je skopiować z serwera master na serwer slave
Zróbmy wysypisko
mysqldump --all-databases --master-data dbdump.db
aby wybrać bazy mysqldump --databases --master-data dbdump.db
parametr master-data, dodaje się automatycznie ZMIEŃ MASTERA NA w węźle podrzędnym, jeśli parametr nie zostanie dodany, wszystkie tabele w sesji muszą zostać zablokowane ręcznie
Odblokować
ODBLOKUJ STOŁY;

Konfiguracja węzła podrzędnego A
Dodać do moje.ini identyfikator serwera z osobistego z głównego i z innych węzłów

identyfikator serwera=2

Utwórz subskrypcję
ZMIEŃ MASTERA NA
MASTER_HOST=nazwa_głównego_hosta,
MASTER_USER=nazwa_użytkownika_replikacji,
MASTER_PASSWORD=hasło_replikacji,
MASTER_LOG_FILE=nazwa pliku_dziennika_zarejestrowanego,
MASTER_LOG_POS=zarejestrowana pozycja_loga;

Konfigurując replikację z użyciem istniejących danych, przed rozpoczęciem replikacji należy przesłać migawkę z urządzenia głównego do urządzenia podrzędnego
Używamy mysqldump
1. Uruchom węzeł podrzędny za pomocą --skip-slave-start parametr uniemożliwiający rozpoczęcie replikacji
2. Zaimportuj plik zrzutu
mysql fulldb.dump
3. Rozpocznij proces subskrypcji
URUCHOM PODRZĘDNY;
Sprawdzanie statusu replikacji
POKAŻ STATUS PODRZĘDU\G
Slave_IO_State: - aktualny stan urządzenia slave
Slave_IO_Running: - czy strumień danych jest odczytywany z mastera
Slave_SQL_Running: - czy działają zapytania SQL, powinno być tak

Przykład Skonfigurujmy serwer Master (master) – ip 11.11.11.10 V moje.ini
[
mysqld] log-bin=mysql-bin identyfikator serwera=1
Utwórz użytkownika mysql -u root -p PRZYZNAJ REPLIKACJĘ SLAVE ON *.* DO repliki@% IDENTYFIKOWANEJ PRZEZ hasło; PRZYWILEJE FLUSH;
Następnie blokujemy wszystkie tabele w bazie danych STOLIKI PODTYNKOWE Z BLOKADĄ ODCZYTU;
Patrzymy na stan POKAŻ STATUS GŁÓWNY; Zapamiętujemy nazwę i pozycję pliku, wykorzystamy je na serwerze Slave w celu subskrypcji

Na niewolniku B moje.ini
log-bin=mysql-bin identyfikator serwera=2

Utwórz subskrypcję ZMIEŃ MASTER NA MASTER_HOST=11.11.11.10, MASTER_PORT=3306,
MASTER_USER=replika, MASTER_PASSWORD=hasło,
MASTER_LOG_FILE=serwer-mysql-bin.000002,
MASTER_LOG_POS=1151664, MASTER_CONNECT_RETRY=10;
URUCHOM PODRZĘDNY;
Status replikacji POKAŻ STATUS SLAVE\G