Kitek's Page Blog programisty / webdeveloper'a

MySQL replikacja

Replikacja w MySQL

Baza danych MySQL oferuje asynchroniczną replikację między serwerem nadrzędnym a podrzędnym. Serwer nadrzędny prowadzi dziennik aktualizacji, a serwer podrzędny odczytuje dziennik i kolejno stosuje aktualizacje.

Dziennik aktualizacji (nazywany również dziennikiem binarnym) zawiera pewne informację przeznaczone dla serwera podrzędnego, które umożliwiają mu wykonanie aktualizacji dokładnie tak samo jak zrobił to serwer nadrzędny. Serwer podrzędny łączy się do serwera nadrzędnego w celu odczytania kolejnej porcji danych z dziennika, a następnie na podstawie tych danych wykonuje lokalnie aktualizację. Odbywa się to za pomocą dwóch wątków: wejścia-wyjścia i SQL. Pierwszy z nich odpowiada za pobranie danych i zapisanie ich lokalnie w plikach tymczasowych nazywanych dziennikami przekazywania (relay-log). Drugi wątek natomiast odczytuje dane z lokalnego dziennika przekazywania i wykonuje aktualizację danych.

Rodzaje replikacji

W MySQL replikacja może opierać się na trzech sposobach: na poziomie instrukcji, wierszy lub trybu mieszanego. Metoda oparta na instrukcjach polega na tym, że serwer nadrzędny rejestruje każdą instrukcję modyfikującą dane np. INSERT, DELETE, która następnie wykonywana jest przez serwer podrzędny. W metodzie opartej na wierszach rejestrowana jest każda zmiana wiersza tabeli. W trybie mieszanym wykorzystywane są obie metody – serwer nadrzędny decyduje który tryb zastosować dla każdego zapytania.

Początkowo stosowano replikację opartą na wierszach lecz od wersji 5.0 wyparto ją dużo wydajniejszą replikacją na poziomie instrukcji. Zalety replikacji opartej na instrukcjach:

  • wymaga przesłania mniejszej ilości danych
  • ogranicza rozmiar dziennika aktualizacji
  • nie musi uwzględniać formatu wiersza

Konfiguracja replikacji

Proces konfiguracji replikacji w MySQL jest względnie nieskomplikowany. Zaczniemy od przygotowania serwera pełniącego rolę nadrzędną (MASTER). W pliku my.cnf (domyślnie znajdującym się w /etc/mysql/) ustawiamy następujące opcje:

[mysqld]
log-bin = mysql-bin
server-id = 1
max_binlog_size = 20M
binlog-do-db = blog

#bind-address = 127.0.0.1
#skip-networking

Poniżej przedstawiam opis powyższych ustawień:

  • log-bin – powoduje włączenie logowania wszystkich zmian i zapisywanie ich do pliku dziennika replikacji o podanej nazwie np. mysql-bin
  • server-id – określa unikatowy numer naszego serwera – w naszym przykładzie przyjmiemy, że serwer nadrzędny będzie posiadał server-id = 1, a natomiast serwer podrzędny 2
  • max_binlog_size - określa maksymalny rozmiar dziennika replikacji
  • binlog-do-db – wskazuje którą bazę danych chcemy replikować, jeżeli nie ustawimy tej opcji będziemy replikować wszystkie bazy znajdujące się na naszym serwerze
  • bind-address, skip-networking – opcje, które musimy wyłączyć by możliwe były połączenia do naszego serwera z zewnątrz

Po zapisaniu zmian w naszym my.cnf restartujemy serwer MySQL i wykonujemy następujące polecenia:

mysql -u root -p
SHOW MASTER STATUS\G

Pierwsze polecenie służy do zalogowania nas na naszym serwerze jako użytkownik root (wymagane będzie podanie hasła), drugie natomiast wyświetli nam dane podobne do poniższych:

mysql> SHOW MASTER STATUS\G
*************************** 1. row ***************************
File: mysql-bin.000012
Position: 463666
Binlog_Do_DB: blog
Binlog_Ignore_DB:
  • File – wskazuje plik gdzie aktualnie zapisywane są dane dziennika replikacji
  • Position – to pozycja w powyższym pliku
  • Binlog_Do_DB - replikowana baza danych
  • Binlog_Ignore_DB – nazwa bazy której replikować nie chcemy

Dane które nas najbardziej interesują to File i Position: są to współrzędne replikacji, które pozwolą serwerowi podrzędnemu replikować dane właśnie od tego momentu – zapisujemy je sobie ponieważ przydadzą się nam przy konfigurowaniu serwera podrzędnego.

Ostatnim elementem konfiguracji serwera nadrzędnego będzie nadanie uprawnień dla konta użytkownika replikacji:

GRANT REPLICATION SLAVE ON *.*
TO 'uzytkownik-replikacji'@'ip-serwera-nadzędnego'
IDENTIFIED BY 'haslo-uzytkownika-replikacji';

Konfiguracja serwera podrzędnego (SLAVE):

W pliku my.cnf ustawiamy:

[mysqld]
server-id = 2
replicate-do-db = blog

i wykonujemy następujące polecenia:

CHANGE MASTER TO
MASTER_HOST='ip-serwera-nadrzędnego',
MASTER_USER='użytkownik-replikacji',
MASTER_PASSWORD='haslo-uzytkownika-replikacji',
MASTER_LOG_FILE='nazwa-pliku-odczytana-z-File',
MASTER_LOG_POS='pozycja-odczytana-z-Position';

Kopiujemy pliki naszej bazy z serwera nadrzędnego na serwer podrzędny. Domyślnie w Gentoo znajdują się one w: /var/lib/mysql/{nazwa_naszej_bazy}.

Uruchamiamy replikację na serwerze podrzędnym, a następnie sprawdzamy czy wszystko poszło po naszej myśli:

START SLAVE;
SHOW SLAVE STATUS\G

wyniki tych operacji powinny być podobne do poniższych:

*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: ip-serwera-nadrzędnego
                Master_User: uzytkownik-replikacji
                Master_Port: 3306
              Connect_Retry: 20
            Master_Log_File: mysql-bin.000012
        Read_Master_Log_Pos: 664823
             Relay_Log_File: benq-relay-bin.000002
              Relay_Log_Pos: 664960
      Relay_Master_Log_File: mysql-bin.000012
           Slave_IO_Running: Yes
          Slave_SQL_Running: Yes
            Replicate_Do_DB: blog
        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: 664823
            Relay_Log_Space: 664960
            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

Opis wybranych parametrów:

  • Slave_OI_State – opis słowny operacji wykonywanych przez serwer podrzędny
  • Master_User – nazwa użytkownika replikacji
  • Master_Port – port na którym łączymy się z serwerem nadrzędnym
  • Connect_Retry – czas wyrażony w sekundach po którym serwer podrzędny spróbuje nawiązać połączenie z serwerem nadrzędnym w przypadku utraty komunikacji
  • Master_Log_File – nazwa pliku dziennika replikacji który jest aktualnie przetwarzany
  • Read_Master_Log_Pos – aktualna pozycja w dzienniku replikacji
  • Relay_Log_File – nazwa pliku dziennika przekazywania
  • Relay_Log_Pos – aktualna pozycja w dzienniku przekazywania
  • Slave_OI_Running – określa czy wątek wejścia-wyjścia działa
  • Slave_SQL_Running – określa czy wątek SQL działa
  • Relay_Log_Space – ilość zajętego miejsca przez dziennik przekazywania
  • Seconds_Behind_Master – opóźnienie serwera podrzędnego w stosunku do serwera nadrzędnego wyrażone w sekundach

W ten oto sposób skonfigurowaliśmy i uruchomiliśmy replikację – możemy sprawdzić czy wszystko działa zmieniając wpis w bazie danych na serwerze nadrzędnym i obserwować co dzieje się na serwerze podrzędnym.

Linki: