Replikacja bazy danych w MySQL

Replikację możemy wykorzystać do zrobienia kopii zapasowej lub jako serwer zapasowy, do którego nasza aplikacja podłączy się, gdy serwer główny w wyniku awarii lub zbyt dużego obciążenia przestanie działać. Konfiguracja replikacji jest prostą operacją i wymaga zmiany zaledwie kilku ustawień w pliku konfiguracyjnym serwera głównego (master) oraz serwera zapasowego (slave).

Serwer główny (master)

Edytujemy plik z ustawieniami MySQL-a.

vim /etc/mysql/my.conf

Do sekcji mysqld dodajemy ID serwera, ścieżkę do pliku dziennika oraz nazwy baz, które chcemy replikować. Nazwy baz mogą zawierać przecinki, więc musza być wypisane w osobnych liniach, a nie w postaci listy rozdzielonej przecinkami.

[mysqld]
server-id = 1
log-bin = /var/log/mysql/mysql-bin.log
binlog-do-db = nazwa_bazy_1
binlog-do-db = nazwa_bazy_2

Restartujemy MySQL-a.

/etc/init.d/mysql restart

Tworzymy użytkownika, który będzie wykorzystywany do

CREATE USER 'użytkownik'@'%' IDENTIFIED BY 'hasło';
GRANT REPLICATION SLAVE ON *.* TO 'użytkownik'@'%' IDENTIFIED BY 'hasło';
FLUSH PRIVILEGES;

Sprawdzamy czy ustawienia replikacji są poprawne.

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

Zapytanie „SHOW MASTER STATUS” powinno wyświetlić nazwę pliku dziennika, pozycję oraz nazwy baz, które będą poddawane replikacji.

File Position Binlog_Do_DB Binlog_Ignore_DB
mysql-bin.000001 106 nazwa_bazy_1,nazwa_bazy_2  

Serwer zapasowy (slave)

Edytujemy plik z ustawieniami MySQL-a.

vim /etc/mysql/my.conf

Do sekcji mysqld dodajemy ID serwera (musi być inny niż ten, który ustawiliśmy na serwerze głównym), adres serwera głównego, login i hasło wcześniej utworzonego użytkownika oraz nazwy baz. Nazwy baz również wpisujemy w osobnych liniach.

[mysqld]
server-id = 2
master-host = adres_serwera
master-user = użytkownik
master-password = hasło
master-connect-retry = 60
replicate-do-db = nazwa_bazy_1
replicate-do-db = nazwa_bazy_2

Restartujemy MySQL-a.

/etc/init.d/mysql restart

Po restarcie replikacja zostanie automatycznie uruchomiona, więc musimy ją zatrzymać.

SLAVE STOP;

Teraz należy przenieść bazy, które chcemy replikować z serwera głównego na zapasowy. Możemy to zrobić przy pomocy programu mysqldump.

Po wykonaniu kopii zapasowej na serwerze zapasowym należy określić parametry. Wykonujemy zapytanie „CHANGE MASTER TO” podając adres serwera, dane do logowania oraz nazwę pliku dziennika i pozycję. Dwie ostatnie informacje uzyskujemy po wykonaniu polecenia „SHOW MASTER STATUS” na serwerze głównym.

CHANGE MASTER TO MASTER_HOST='adres_serwera', MASTER_USER='użytkownik', MASTER_PASSWORD='hasło', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=106;

Uruchamiamy replikację na serwerze zapasowym.

START SLAVE;

Weryfikacja

Sprawdzamy czy replikacja działa poprawnie.

SHOW SLAVE STATUS;

Wynikiem będzie tabela z informacjami o serwerze głównym, replikowanych bazach oraz pozycji w dzienniku. W kolumnie „SLAVE_IO_STATE” powinien znaleźć się komunikat „Waiting for master to send event” co oznacza, że serwer zapasowy oczekuje na dane z serwera głównego. „MASTER_LOG_FILE” to nazwa dziennika, a „READ_MASTER_LOG_POS” to pozycja w dzienniku. Pozycja powinna być taka sama jak wartość zwracane przez zapytanie „SHOW MASTER STATUS” wykonane na serwerze głównym.

Oprócz tego, możemy wyświetlić listę procesów na obu serwerach.

SHOW PROCESSLIST

Na serwerze głównym, na liście procesów pojawi się wpis z informacją o oczekiwaniu na aktualizację dziennika,

Has sent all binlog to slave; waiting for binlog to be updated

a na serwerze zapasowym informacja o oczekiwaniu na dane z serwera głównego.

Waiting for master to send event

Działanie replikacji można sprawdzić również wykonując poniższe zapytanie.

SHOW STATUS LIKE 'Slave%'

W wyniku otrzymamy m.in. wpis o nazwie „Slave_running” i wartości „ON”.

Uwagi

Opcja skip-networking nie może zostać włączona na serwerze głównym, gdyż serwer (lub serwery) zapasowe nie będą mogły nawiązać połączenia.

Podobnie jak skip-networking, opcja bind-address musi zostać wyłączona lub zawierać adres, do którego będą łączyły się serwery zapasowe.

Podczas przenoszenia bazy należy zwrócić uwagę na użytkownika, który został zdefiniowany jako twórca procedur czy triggerów. Jeżeli na serwerze slave użytkownik nie istnieje, to możemy otrzymać komunikat o błędzie. Poniższy komunikat został wygenerowany w momencie, gdy baza próbowała zreplikować zapytanie INSERT wykonane na tabeli, na której zdefiniowane były triggery.

Error 'The user specified as a definer ('użytkownik'@'%') does not exist' on query. Default database: 'nazwa_bazy_1'. Query: 'INSERT INTO ...'

Problem można rozwiązać poprzez dodanie użytkownika o takiej samej nazwie, a następnie nadaniu mu odpowiednich uprawnień do bazy na serwerze zapasowym.

Replikację można wznowić wykonując poniższe zapytania.

STOP SLAVE;
START SLAVE;

MySQL wznowi replikację począwszy od zapytania, które spowodowało problem.

Ten wpis został opublikowany w kategorii Linux, MySQL. Dodaj zakładkę do bezpośredniego odnośnika.