XtraBackup to bardzo przyjemne narzędzie do wykonania szybkiego i “gorącego” binarnego backupu dla InnoDB i MyISAM. Znakomicie nadaje się do przygotowania pełnej kopii całego serwera bazodanowego, w szczególności do kopii, którą chcemy następnie używać jako slave. Ten wpis to takie proste, krok po kroku, how-to.

Podstawową zaletą XtraBackup, jeśli chcemy sklonować serwer i uruchomić pierwszego slave, jest fakt, że dzięki temu narzędziu do minimum ograniczamy okres braku dostępności serwera źródłowego. Co tak na prawdę potrzebujemy, żeby uruchomić slave? Pełen zestaw danych + koordynaty binlogów, na moment backupu. Co ważne, nie może być tak, że backup zawiera zmiany danych w czasie. Przykładowo – notujemy stan binlogów, uruchamiamy proces backupu, robimy kopię pierwszej tabeli – w tym czasie zmodyfikowana została kolejna tabela. Jeśli teraz nasz backup będzie zawierał stan drugiej tabeli już po modyfikacjach, będzie stanowiło to dla nas problem.

Teoretycznie możemy wyłączyć sobie MySQL na masterze (Percona Server w logach zapisuje na jakiej pozycji w binlogu zakończył pracę, nie pamiętam jak to jest z “czystym” MySQL), przekopiować wszystkie dane na bok a następnie włączyć mastera ponownie. Problemem jest czas, w którym MySQL nie działa. Przekopiowanie dużej ilości danych może po prostu trwać.

Innym rozwiązaniem jest zastosowanie mysqldump, który posiada flagę –single-transaction którą można użyć w połączeniu z flagą –dump-slave – w przypadku czystego InnoDB to jest rozwiązanie najlepsze. Mysqldump jest wolny, pojedyncza, długa transakcja także jest odczuwalna dla serwera MySQL, ale nie musimy się martwić, że baza nie jest dostępna. Jeśli jednak posiadamy miks InnoDB z MyISAM, zastosowanie pojedynczej transakcji oczywiście nie jest możliwe. Oczywiście, głównie dlatego, że MyISAM transakcji nie obsługuje. Co prawda można użyć samej flagi –dump-slave, ale tym razem skończy się to nałożeniem globalnego read lock, przez co wszelkie DML będą czekać na zakończenie mysqldump. Biorąc pod uwagę, że mysqldump nie jest najszybszym sposobem na wykonanie kopii zapasowej dużych (kilkaset GB i więcej) baz danych, może to kończyć się timeoutami tych zapytań i w efekcie utratą danych.

Z powyższych więc względów, XtraBackup jest rozwiązaniem bardzo zalecanym do tego typu przypadków. Jak to w praktyce działa?

Zaczynamy na serwerze źródłowym, przyszłym serwerze master, od wykonania kopii danych:

root@source:~# innobackupex --slave-info --user=root /backup/

Dane w tym wypadku zrzucamy do katalogu /backup/.

Następnie, na serwerze docelowym (przyszły slave) tworzymy sobie strukturę katalogów, przechodzimy tam i włączamy netcata.

root@restore:~# mkdir /backup/restore
root@restore:~# cd /backup/restore/
root@restore:/backup/restore# nc -l 9999 | tar xvf -

Gdy innobackupex zakończył pracę, przegrywamy dane z serwera źródłowego na docelowy.

root@source:/backup# tar cfv - ./2012-10-29_07-13-06/ | nc -v 192.168.1.17 9999

Oczywiście, zamiast netcata można użyć cokolwiek innego – rsync, scp, dysk wymienny – wszystko co spowoduje, że pliki wylądują na serwerze docelowym. Następnie na serwerze docelowym nakładamy logi transakcji na pliki z backupem:

root@restore:~# innobackupex --apply-log /backup/restore/2012-10-29_06-32-25/

Dzięki temu, MySQL podczas startu nie będzie musiał przechodzić procesu recovery dla InnoDB.

Następnym krokiem będzie umieszczenie tak przygotowanego backupu w datadir MySQL. Jeśli coś wcześniej tam było, usuwamy całość. Jeśli MySQL nie ma zainstalowanego na serwerze, instalujemy a potem czyścimy katalog domowy. Jak już wszystko jest na miejscu, upewniamy się że pliki mają właściwego właściciela:

root@restore:~# chown -R mysql.mysql /var/lib/mysql/

Następnie sprawdzamy zawartość pliku:

root@restore:~# cat /var/lib/mysql/xtrabackup_binlog_info
mysql-bin.000014 5172686

Znajdziemy tu koordynaty binlogów, które wykorzystamy do rozpoczęcia replikacji. Serwery (zarówno master jak i slave) należy do replikacji odpowiednio skonfigurować – ustawić server-id, dodać użytkownika który będzie łączyć się z slave itd. Dokładne informacje jak to zrobić można znaleźć w dokumentacji: http://dev.mysql.com/doc/refman/5.5/en/replication-howto.html

Gdy już wszystko jest gotowe, na serwerze docelowym (slave) uruchamiamy replikację:

change master to master_host='192.168.1.16', master_user='repl', master_password='password', master_log_file='mysql-bin.000014', master_log_pos=5172686;

start slave;
show slave status\G

Jeśli wszystko wykonaliśmy poprawnie, powinniśmy widzieć jak nasz nowy serwer slave ładnie nadgania zaległości do serwera master.

W ten sposób, bezinwazyjnie, udało się nam uruchomić serwer slave. Jeśli nie mamy miejsca na serwerze źródłowym, XtraBackup umożliwia streamowanie danych na inny serwer – nie musimy tworzyć backupu na tej samej maszynie, z jakiej jest on wykonywany.

Jeśli posiadamy już parę master – slave i chcemy uruchomić następnego slave, XtraBackup posiada jeszcze jedną, dodatkową funkcję. Backup wykonywać będziemy z serwera slave. Jeśli wtedy dodamy flagę –slave-info:

root@source:~# innobackupex --slave-info --user=root /backup/

to utworzony zostanie plik xtrabackup_slave_info – korzystamy wtedy z niego, zamiast z pliku xtrabackup_binlog_info, jak w opisywanym wcześniej przypadku. Znajduje się tam polecenie CHANGE MASTER z gotowymi koordynatami.

Jeśli ktoś z czytelników administrujących MySQL nie miał okazji zapoznać się z XtraBackup, polecam przeznaczyć na to trochę czasu – warto.