Jak ponownie zsynchronizować bazę danych MySQL, jeśli Master i Slave mają inną bazę danych w przypadku replikacji MySQL?

139

MySQL Server1działa jako MASTER .
MySQL Server2działa jako SLAVE .

Teraz replikacja bazy danych odbywa się od MASTER do SLAVE .

Server2zostanie usunięty z sieci i podłącz go ponownie po 1 dniu. Następnie występuje niezgodność w bazie danych w trybie master i slave.

Jak ponownie zsynchronizować DB, ponieważ po przywróceniu DB pobranego z Master do Slave również nie rozwiązuje problemu?

Indu Sharma
źródło

Odpowiedzi:

287

Oto pełna procedura krok po kroku, aby ponownie zsynchronizować replikację typu master-slave od zera:

U mistrza:

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

I skopiuj gdzieś wartości wyniku ostatniego polecenia.

Bez zamykania połączenia z klientem (ponieważ zwolniłoby to blokadę odczytu) wydaj polecenie uzyskania zrzutu mastera:

mysqldump -u root -p --all-databases > /a/path/mysqldump.sql

Teraz możesz zwolnić blokadę, nawet jeśli zrzut jeszcze się nie skończył. Aby to zrobić, wykonaj następujące polecenie w kliencie MySQL:

UNLOCK TABLES;

Teraz skopiuj plik zrzutu do slave'a za pomocą scp lub preferowanego narzędzia.

U niewolnika:

Otwórz połączenie z mysql i wpisz:

STOP SLAVE;

Załaduj zrzut danych mastera za pomocą tego polecenia konsoli:

mysql -uroot -p < mysqldump.sql

Synchronizuj dzienniki slave i master:

RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98;

Gdzie wartości powyższych pól są tymi, które skopiowałeś wcześniej.

Na koniec wpisz:

START SLAVE;

Aby sprawdzić, czy wszystko działa, po wpisaniu:

SHOW SLAVE STATUS;

powinieneś zobaczyć:

Slave_IO_Running: Yes
Slave_SQL_Running: Yes

Otóż ​​to!

David Espart
źródło
8
Ze zdefiniowanym dabatazem wpisanym w INNODB i innymi złożonymi typami kolumn, takimi jak BLOB i DATE, polecam użycie następujących przełączników:--opt --single-transaction --comments --hex-blob --dump-date --no-autocommit --all-databases
Ken Pega
4
Jest RESET_SLAVEkonieczne? Zauważ, że te instrukcje resetują użytkownika i hasło replikacji, więc będziesz musiał ponownie wprowadzić te zCHANGE MASTER TO...
Mike S.
25
Jeśli użyjesz flagi --master-data podczas wywoływania mysqldump na serwerze głównym, polecenie CHANGE MASTER TO jest zapisywane w pliku zrzutu, a tym samym zapisuje krok jego wykonania po zaimportowaniu pliku zrzutu do urządzenia podrzędnego.
udog
3
Brak blokowania mastera (nie wymaga Percona ) plusbryan.com/mysql-replication-without-downtime Inną korzyścią jest to, że zrzut SQL zawiera również niezbędną linię "CHANGE MASTER" (zakomentowana)
mahemoff
2
Czy istnieje sposób na zautomatyzowanie tego?
Metafaniel,
26

Dokumentacja na ten temat w witrynie MySQL jest żałośnie nieaktualna i pełna pistoletów do noszenia (takich jak Interactive_timeout). Wydawanie FLUSH TABLES WITH READ LOCK jako części eksportu mastera ma sens tylko wtedy, gdy jest skoordynowane z migawką pamięci / systemu plików, taką jak LVM lub zfs.

Jeśli zamierzasz używać mysqldump, powinieneś zamiast tego polegać na opcji --master-data, aby ustrzec się przed błędami ludzkimi i jak najszybciej zwolnić blokady na serwerze głównym.

Załóżmy, że master to 192.168.100.50, a slave to 192.168.100.51, każdy serwer ma skonfigurowany odrębny identyfikator serwera, master ma logowanie binarne, a slave ma tylko do odczytu = 1 w my.cnf

Aby przygotować slave'a do rozpoczęcia replikacji zaraz po zaimportowaniu zrzutu, wydaj polecenie CHANGE MASTER, ale pomiń nazwę i pozycję pliku dziennika:

slaveserver> CHANGE MASTER TO MASTER_HOST='192.168.100.50', MASTER_USER='replica', MASTER_PASSWORD='asdmk3qwdq1';

Wydaj GRANT na master, aby slave użył:

masterserver> GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.100.51' IDENTIFIED BY 'asdmk3qwdq1';

Wyeksportuj wzorzec (na ekranie) przy użyciu kompresji i automatycznie przechwytuj poprawne współrzędne dziennika binarnego:

mysqldump --master-data --all-databases --flush-privileges | gzip -1 > replication.sql.gz

Skopiuj plik replication.sql.gz na slave, a następnie zaimportuj go za pomocą zcat do instancji MySQL działającej na slave:

zcat replication.sql.gz | mysql

Rozpocznij replikację, wydając komendę do slave'a:

slaveserver> START SLAVE;

Opcjonalnie zaktualizuj /root/.my.cnf na urządzeniu podrzędnym, aby przechowywać to samo hasło roota, co hasło główne.

Jeśli korzystasz z 5.1+, najlepiej najpierw ustawić binlog_format mastera na MIXED lub ROW. Należy pamiętać, że zdarzenia rejestrowane w wierszach są powolne w przypadku tabel, które nie mają klucza podstawowego. Jest to zwykle lepsze niż alternatywna (i domyślna) konfiguracja instrukcji binlog_format = (na urządzeniu głównym), ponieważ jest mniej prawdopodobne, że wygeneruje błędne dane na urządzeniu podrzędnym.

Jeśli musisz (ale prawdopodobnie nie powinieneś) filtrować replikację, zrób to z opcjami slave replicate-wild-do-table = dbname.% Lub replicate-wild-ignore-table = badDB.% I użyj tylko binlog_format = row

Ten proces utrzyma globalną blokadę na serwerze głównym na czas działania polecenia mysqldump, ale w inny sposób nie wpłynie na niego.

Jeśli kusi Cię użycie mysqldump --master-data --all-databases --single-transaction (ponieważ używasz tylko tabel InnoDB), być może lepiej będzie, gdy skorzystasz z MySQL Enterprise Backup lub implementacji open source o nazwie xtrabackup (dzięki uprzejmości Percona)

Przestarzały
źródło
3
Jeśli chcesz po prostu odbudować istniejącego slave'a, możesz wykonać powyższy proces, pomijając kilka kroków: Polecenie GRANT i ręczne CHANGE MASTER
nieaktualne
Pytanie 1: W oknach, co byłoby odpowiednikiem zcat. Pytanie 2: Jak to wygląda w mysqldumpprzypadku dużych baz danych pod względem wydajności? Dowolny sposób wykorzystać SELECT INTO OUTFILEi LOAD DATAsprawnie w sugerowanej procesie? (Ponieważ generalnie grają szybciej)
Ifedi Okonkwo
Nie musisz STOP SLAVEgdzieś w tym procesie?
David V.
16

O ile nie piszesz bezpośrednio do serwera podrzędnego (Serwer2), jedynym problemem powinno być to, że serwerowi2 brakuje jakichkolwiek aktualizacji, które miały miejsce od momentu odłączenia. Po prostu zrestartuj slave'a za pomocą „START SLAVE”; powinien przywrócić wszystko do działania.

malonso
źródło
2
Możesz sprawdzić dzienniki kosza i zobaczyć, czy obejmują one okres braku synchronizacji systemu. Jeśli brakuje Ci dni, może to być większy problem i wymagać wykonania pełnego zrzutu w celu przywrócenia brakujących danych.
nelaaro
7

Myślę, że narzędzia Maatkit pomagają ci! Możesz użyć mk-table-sync. Zobacz ten link: http://www.maatkit.org/doc/mk-table-sync.html

Mniejszy
źródło
Myślę, że będzie musiał chwilowo przerwać pisanie podczas uruchamiania skryptu.
Ztyx
To nadal działa świetnie. Nazwy narzędzi zostały jednak zmienione i teraz nazywa się to pt-table-sync. W rzeczywistości jednak odkryłem, że ich narzędzie do restartu pt-slave działa jak magia.
mlerley
7

Jestem bardzo spóźniony na to pytanie, jednak napotkałem ten problem i po długich poszukiwaniach znalazłem te informacje od Bryana Kennedy'ego: http://plusbryan.com/mysql-replication-without-downtime

Na Master wykonaj kopię zapasową w następujący sposób:
mysqldump --skip-lock-table --single-transaction --flush-logs --hex-blob --master-data = 2 -A> ~ / dump.sql

Teraz przyjrzyj się nagłówkowi pliku i zanotuj wartości MASTER_LOG_FILE i MASTER_LOG_POS. Będziesz ich potrzebować później: head dump.sql -n80 | grep „MASTER_LOG”

Skopiuj plik „dump.sql” do Slave i przywróć go: mysql -u mysql-user -p <~ / dump.sql

Połącz się z Slave mysql i uruchom takie polecenie: CHANGE MASTER TO MASTER_HOST = 'master-server-ip', MASTER_USER = 'replication-user', MASTER_PASSWORD = 'slave-server-password', MASTER_LOG_FILE = 'value from above', MASTER_LOG_POS = wartość z góry; START SLAVE;

Aby sprawdzić postęp Slave: POKAŻ STATUS PODRZĘDNEGO;

Jeśli wszystko jest w porządku, Last_Error będzie puste, a Slave_IO_State zgłosi „Oczekiwanie na zdarzenie mastera”. Poszukaj Seconds_Behind_Master, który wskazuje, jak daleko jest za nim. YMMV. :)

Jeffery7
źródło
3
To działa, a jeśli slave jest już skonfigurowany i stracił synchronizację, nie musisz uruchamiać CHANGE MASTER; po prostu określ --master-data=1(lub po prostu --master-data).
LSerni
5

Oto, co zwykle robię, gdy slave mysql traci synchronizację. Patrzyłem na mk-table-sync, ale pomyślałem, że sekcja Ryzyka wyglądała przerażająco.

Na Master:

SHOW MASTER STATUS

Wyprowadzone kolumny (Plik, Pozycja) za chwilę przydadzą nam się.

Na slave:

STOP SLAVE

Następnie zrzuć główną bazę danych i zaimportuj ją do podrzędnej bazy danych.

Następnie wykonaj następujące czynności:

CHANGE MASTER TO
  MASTER_LOG_FILE='[File]',
  MASTER_LOG_POS=[Position];
START SLAVE;

Gdzie [File] i [Position] to wartości wyprowadzone z powyższego „SHOW MASTER STATUS”.

Mam nadzieję że to pomoże!

Bryson
źródło
5
Wydaje się to zepsute, ponieważ najwyraźniej nie robisz tego FLUSH TABLES WITH READ LOCK;przed sobą SHOW MASTER STATUSi nie zrzucasz głównej bazy danych. Myślę, że może to skutkować np. Zduplikowanymi błędami klucza w slave, ponieważ skutecznie ustawiłeś status mastera na punkt w czasie przed wykonaniem zrzutu, więc odtworzysz historię, która jest już zawarta w zrzucie. (Jeśli robisz rzeczy w opisanej kolejności.)
KajMagnus
5

Kontynuując odpowiedź Davida ...

Użycie SHOW SLAVE STATUS\Gda wyjście czytelne dla człowieka.

Greg Ackerson
źródło
Jakiś sposób na stronicowanie wyników?
Josiah
„pager więcej”, myślę, że to zrobię
Ian
3

czasami trzeba po prostu kopnąć niewolnika

próbować

stop slave;    
reset slave;    
start slave;    
show slave status;

dość często niewolnicy, po prostu utknęli chłopaki :)

Zamaskowany koder gówna
źródło
... i monitoruj Positionmaster używając show master status;przeciwko Exec_Master_Log_Pos:na Slave używając show slave status \G. Niewolnik powinien dogonić pana. Pracowałem dla mnie używając mysql 5.6 właśnie teraz po krótkiej przerwie w działaniu sieci.
Mike S
10
To jest mylące, kiedy zresetujesz niewolnika, maść całkowicie straciła wiedzę o tym, gdzie jest pan.
Qian Chen
2

Oto pełna odpowiedź, która, miejmy nadzieję, pomoże innym ...


Chcę skonfigurować replikację mysql za pomocą master i slave, a ponieważ jedyne, co wiedziałem, to to, że używa plików dziennika do synchronizacji, jeśli slave przejdzie w tryb offline i utraci synchronizację, teoretycznie powinno tylko połączyć się z powrotem do swojego mastera i kontynuuj czytanie pliku dziennika od miejsca, w którym przerwał, jak wspomniał użytkownik Malonso.

Oto wynik testu po skonfigurowaniu master i slave, jak wspomniano w: http://dev.mysql.com/doc/refman/5.0/en/replication-howto.html ...

Pod warunkiem, że używasz zalecanej konfiguracji master / slave i nie piszesz do slave'a, on i ja tam gdzie ma rację (jeśli chodzi o mysql-server 5.x). Nie musiałem nawet używać „START SLAVE”, po prostu dogonił swojego pana. Ale jest domyślna 88000 ponownych prób co 60 sekund, więc myślę, że jeśli wyczerpiesz, być może będziesz musiał uruchomić lub ponownie uruchomić slave. W każdym razie, dla takich jak ja, którzy chcieli wiedzieć, czy wyłączenie niewolnika i ponowne utworzenie kopii zapasowej wymaga ręcznej interwencji… nie, nie.

Może oryginalny plakat zawierał błędy w plikach dziennika? Ale najprawdopodobniej nie tylko serwer, który przechodzi w tryb offline na jeden dzień.


ściągnięte z /usr/share/doc/mysql-server-5.1/README.Debian.gz, co prawdopodobnie ma sens również dla serwerów innych niż Debian:

* DALSZE UWAGI DOTYCZĄCE REPLIKACJI
===============================
Jeśli serwer MySQL działa jako slave replikacji, nie powinieneś
ustaw --tmpdir, aby wskazywało na katalog w systemie plików opartym na pamięci lub na
katalog, który jest czyszczony po ponownym uruchomieniu hosta serwera. Replikacja
slave potrzebuje niektórych swoich plików tymczasowych, aby przetrwać restart komputera, więc
że może replikować tabele tymczasowe lub operacje LOAD DATA INFILE. Jeśli
pliki w katalogu plików tymczasowych są tracone po ponownym uruchomieniu serwera,
replikacja nie powiedzie się.

możesz użyć czegoś takiego jak sql: pokaż zmienne, takie jak 'tmpdir'; dowiedzieć się.

bksunday
źródło
Czy obie bazy danych będą synchronizowane automatycznie między sobą? Np. Napiszę do Mastera, czy Slave zostanie zaktualizowany automatycznie?
TransformBinary,
2

Dodając do popularnej odpowiedzi, aby uwzględnić ten błąd:

"ERROR 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO",

Replikacja ze slave'a w jednym ujęciu:

W jednym oknie terminala:

mysql -h <Master_IP_Address> -uroot -p

Po podłączeniu

RESET MASTER;
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;

Stan wygląda jak poniżej: Zwróć uwagę, że numer pozycji jest różny!

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 |      98  | your_DB      |                  |
+------------------+----------+--------------+------------------+

Wyeksportuj zrzut w podobny sposób, jak opisał „ używając innego terminala ”!

Wyjdź i połącz się z własną bazą danych (która jest slave'em):

mysql -u root -p

Wpisz poniższe polecenia:

STOP SLAVE;

Zaimportuj zrzut, jak wspomniano (oczywiście w innym terminalu!) I wpisz poniższe polecenia:

RESET SLAVE;
CHANGE MASTER TO 
  MASTER_HOST = 'Master_IP_Address', 
  MASTER_USER = 'your_Master_user', // usually the "root" user
  MASTER_PASSWORD = 'Your_MasterDB_Password', 
  MASTER_PORT = 3306, 
  MASTER_LOG_FILE = 'mysql-bin.000001', 
  MASTER_LOG_POS = 98; // In this case

Po zalogowaniu ustaw parametr server_id (zwykle w przypadku nowych / niereplikowanych baz danych nie jest to ustawienie domyślne),

set global server_id=4000;

Teraz zacznij niewolnika.

START SLAVE;
SHOW SLAVE STATUS\G;

Wynik powinien być taki sam, jak opisał.

  Slave_IO_Running: Yes
  Slave_SQL_Running: Yes

Uwaga: po replikacji master i slave mają to samo hasło!

curlyreggie
źródło
Czy obie bazy danych będą synchronizowane automatycznie między sobą? Np. Napiszę do Mastera, czy Slave zostanie zaktualizowany automatycznie?
TransformBinary,
1

Odbudowa slave'a za pomocą LVM

Oto metoda, której używamy do przebudowy slave'ów MySQL przy użyciu Linux LVM. Gwarantuje to spójną migawkę, wymagając bardzo minimalnego czasu przestoju na serwerze głównym.

Ustaw innodb max brudnych stron procent na zero na głównym serwerze MySQL. Zmusi to MySQL do zapisania wszystkich stron na dysku, co znacznie przyspieszy ponowne uruchomienie.

set global innodb_max_dirty_pages_pct = 0;

Aby monitorować liczbę brudnych stron, uruchom polecenie

mysqladmin ext -i10 | grep dirty

Gdy liczba przestanie spadać, osiągniesz punkt, aby kontynuować. Następnie zresetuj urządzenie główne, aby wyczyścić stare dzienniki bin / dzienniki przekaźników:

RESET MASTER;

Uruchom lvdisplay, aby uzyskać ścieżkę LV

lvdisplay

Wynik będzie wyglądał następująco

--- Logical volume ---
LV Path                /dev/vg_mysql/lv_data
LV Name                lv_data
VG Name                vg_mysql

Zamknij główną bazę danych za pomocą polecenia

service mysql stop

Następnie zrób migawkę, mysql_snapshot będzie nową nazwą woluminu logicznego. Jeśli na dysku systemu operacyjnego znajdują się dzienniki binarne, również należy je wykonać jako migawki.

lvcreate --size 10G --snapshot --name mysql_snapshot /dev/vg_mysql/lv_data

Uruchom ponownie mastera za pomocą polecenia

service mysql start

Przywróć domyślne ustawienie brudnych stron

set global innodb_max_dirty_pages_pct = 75;

Uruchom ponownie lvdisplay, aby upewnić się, że migawka istnieje i jest widoczna

lvdisplay

Wynik:

--- Logical volume ---
LV Path                /dev/vg_mysql/mysql_snapshot
LV Name                mysql_snapshot
VG Name                vg_mysql

Zamontuj migawkę

mkdir /mnt/mysql_snapshot
mount /dev/vg_mysql/mysql_snapshot /mnt/mysql_snapshot

Jeśli masz działające urządzenie podrzędne MySQL, musisz je zatrzymać

service mysql stop

Następnie musisz wyczyścić folder danych MySQL

cd /var/lib/mysql
rm -fr *

Powrót do mistrza. Teraz zsynchronizuj migawkę ze slave'em MySQL

rsync --progress -harz /mnt/mysql_snapshot/ targethostname:/var/lib/mysql/

Po zakończeniu rsync możesz odmontować i usunąć migawkę

umount /mnt/mysql_snapshot
lvremove -f /dev/vg_mysql/mysql_snapshot

Utwórz użytkownika replikacji na serwerze głównym, jeśli stary użytkownik replikacji nie istnieje lub hasło jest nieznane

GRANT REPLICATION SLAVE on *.* to 'replication'@'[SLAVE IP]' identified by 'YourPass';

Sprawdź, czy pliki danych / var / lib / mysql należą do użytkownika mysql, jeśli tak, możesz pominąć następujące polecenie:

chown -R mysql:mysql /var/lib/mysql

Następnie zapisz pozycję binlog

ls -laF | grep mysql-bin

Zobaczysz coś takiego

..
-rw-rw----     1 mysql mysql  1073750329 Aug 28 03:33 mysql-bin.000017
-rw-rw----     1 mysql mysql  1073741932 Aug 28 08:32 mysql-bin.000018
-rw-rw----     1 mysql mysql   963333441 Aug 28 15:37 mysql-bin.000019
-rw-rw----     1 mysql mysql    65657162 Aug 28 16:44 mysql-bin.000020

W tym przypadku główny plik dziennika to najwyższy numer pliku w kolejności, a pozycja bin log to rozmiar pliku. Zapisz te wartości:

master_log_file=mysql-bin.000020
master_log_post=65657162

Następnie uruchom slave MySQL

service mysql start

Wykonaj polecenie change master na urządzeniu slave, wykonując następujące czynności:

CHANGE MASTER TO 
master_host="10.0.0.12", 
master_user="replication", 
master_password="YourPass", 
master_log_file="mysql-bin.000020", 
master_log_pos=65657162; 

Wreszcie zacznij niewolnika

SLAVE START;

Sprawdź status slave:

SHOW SLAVE STATUS;

Upewnij się, że Slave IO działa i nie ma błędów połączenia. Powodzenia!

BR, Juha Vehnia

Niedawno napisałem to na moim blogu, który znajduje się tutaj ... Jest tam kilka szczegółów, ale historia jest taka sama.

http://www.juhavehnia.com/2015/05/rebuilding-mysql-slave-using-linux-lvm.html

Juha Vehnia
źródło
0

Utworzyłem repozytorium GitHub ze skryptem, aby szybko rozwiązać ten problem. Wystarczy zmienić kilka zmiennych i uruchomić go (najpierw skrypt tworzy kopię zapasową bazy danych).

Mam nadzieję, że to pomoże tobie (a także innym ludziom).

Jak zresetować (ponownie zsynchronizować) replikację MySQL Master-Slave

MCurbelo
źródło
Widzę, że skrypt zawsze ustawia pozycję dziennika głównego na 1 i nazwę głównego pliku dziennika. Nie wiem wystarczająco, aby być pewnym, czy powinienem się tym martwić, czy nie. Czy możesz wytłumaczyć? Obecnie mam ponad 1 000 000 pozycji. Czy to oznacza, że ​​spróbuje ponownie odtworzyć 1 milion zapytań, zanim zacznie działać? Czy nie ma szans na korupcję w odtwarzaniu tych zapytań z istniejącymi danymi? Zastanawiam się, dlaczego nie w skrypcie podczas wykonywania zrzutu mysql użyć opcji --master-data = 2, a następnie wyciągnąć plik i pos ze zrzutu, aby je ustawić?
Josiah
0

Używamy techniki replikacji typu master-master MySQL i jeśli jeden serwer MySQL powie 1 zostanie usunięty z sieci, połączy się on ponownie po przywróceniu połączenia i przeniesieniu wszystkich rekordów, które zostały zatwierdzone na serwerze 2, który był w sieci do serwera 1, który utracił połączenie po przywróceniu. Wątek podrzędny w MySQL próbuje domyślnie połączyć się ze swoim serwerem głównym co 60 sekund. Ta właściwość może zostać zmieniona, ponieważ MySQL ma flagę „master_connect_retry = 5”, gdzie 5 jest w sek. Oznacza to, że chcemy ponawiać próbę co 5 sekund.

Ale musisz się upewnić, że serwer, który utracił połączenie, nie wykonuje żadnego zatwierdzenia w bazie danych, gdy otrzymasz zduplikowany błąd klucza Kod błędu: 1062

parag gupta
źródło
0

Mistrz :

mysqldump -u root -p --all-databases --master-data | gzip > /tmp/dump.sql.gz  

scp master:/tmp/dump.sql.gz slave:/tmp/ Przenieś plik zrzutu na serwer podrzędny

Niewolnik:

STOP SLAVE;

zcat /tmp/dump.sql.gz | mysql -u root -p

START SLAVE;
SHOW SLAVE STATUS;  

UWAGA :
Na master możesz uruchomić SET GLOBAL expire_logs_days = 3binlog przez 3 dni w przypadku problemów ze slave.

M Rostami
źródło