Ostatnio w moim życiu pojawiła się konieczność postawienia systemu High Availability dla MySQL.
Od zawsze bałem się tego tematu, bo to replikacja, bo to heartbeat (w tym wypadku), jednak jak się okazało po przeczytaniu setki manuali nie jest to takie trudne ;-)
Na początku cytując „nie odpowiadam za to, co ten artykuł zrobi z Waszymi bazami danych; remember kids, always do backups” – shasta.
Dokumentacja:
http://www.netexpertise.eu/en/linux/heartbeat-2-howto.html
http://wiki.openvz.org/HA_cluster_with_DRBD_and_Heartbeat
http://www.howtoforge.com/mysql_master_master_replication
http://dev.mysql.com/doc/refman/5.0/en/replication-options-master.html#sysvar_auto_increment_offset
http://dev.mysql.com/doc/refman/5.0/en/replication-options-master.html#sysvar_auto_increment_increment
Przyjmijmy następującą konfiguracje:
Będzie to replikacja MySQL Master-Master dla jednej bazy danych (testha) automatycznie powracającej (w razie awarii master01=>rozwiązania problemu) do pozycji mastera (master01) replikacji (opcja auto_failback w /etc/ha.d/ha.cf) + HA zapewniany przez Heartbeat, konfiguracja będzie oparta o system CentOS.
Nazwa replikowanej bazy danych: testha
Adresy:
masterha – 192.168.20.1 – masterha.domain – wirtualne IP heartbeata,
master01 – 192.168.20.2 – master01.domain – MySQL primary master,
master02 – 192.168.20.3 – master02.domain – MySQL secondary master,
gateway – 192.168.20.253,
lokalny komputer – 192.168.20.123.
Replikacja będzie zaczynała od wartości auto_increment 1 dla master01, 2 dla master02 (opcja auto_increment_offset w /etc/mysql/my.cnf) oraz przeskakiwała co 5 kolejnych wpisów na obu serwerach (opcja auto_increment_increment w /etc/mysql/my.cnf) aby zapobiec kolizji wpisów do tabeli.
Najpierw stworzymy samą replikacje:
master01/master02:
Dopisujemy do pliku /etc/mysql/my.cnf:
server-id = 1/2 # 1 dla master01, 2 dla master02
log-bin = mysql_bin.log
binlog-do-db = testha
auto_increment_increment = 5
auto_increment_offset = 1/2 # 1 dla master01, 2 dla master02
Na obu maszynach restartujemy MySQL:
# /etc/init.d/mysql restart
W konsoli MySQL na master01/master02 nadajemy uprawnienia replikacji:
master01:
mysql> grant replication slave on *.* to 'slave’@’master02.domain’ identified by 'very-complicated-password’;
master02:
mysql> grant replication slave on *.* to 'slave’@’master01.domain’ identified by 'very-complicated-password’;
W konsoli MySQL na master01/master02 sprawdzamy pozycje binloga + nazwę pliku:
master01:
mysql> show master status;
+———————–+——————————–+——————————————+—————————————————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+———————–+——————————–+——————————————+—————————————————-+
| mysql-bin.003 | 73 | testha | |
+———————–+——————————–+——————————————+—————————————————-+
master02:
mysql> show master status;
+———————–+———————————-+——————————————+—————————————————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+———————–+———————————-+——————————————+—————————————————-+
| mysql-bin.005 | 117 | testha | |
+———————–+———————————-+——————————————+—————————————————-+
W konsoli MySQL na master01/master02 ustawiamy mastera replikacji:
master01:
mysql> slave stop;
mysql> CHANGE MASTER TO MASTER_HOST=”master02.domain”, MASTER_USER=”slave”, MASTER_PASSWORD=”very-complicated-password”, MASTER_LOG_FILE=”mysql-bin.005″, MASTER_LOG_POS=117;
mysql> slave start;
master02:
mysql> slave stop;
mysql> CHANGE MASTER TO MASTER_HOST=”master01.domain”, MASTER_USER=”slave”, MASTER_PASSWORD=”very-complicated-password”, MASTER_LOG_FILE=”mysql-bin.003″, MASTER_LOG_POS=73;
mysql> slave start;
Powinniśmy mieć w tym momencie działającą replikacje master<=>master, sprawdźmy to:
master01:
show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master02.domain
Master_User: slave
Master_Port: 3306
Connect_Retry: 3
Master_Log_File: mysql-bin.005
Read_Master_Log_Pos: 117
Relay_Log_File: mysqld-relay-bin.005
Relay_Log_Pos: 117
Relay_Master_Log_File: mysql-bin.005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
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: 117
Relay_Log_Space: 552
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
master02:
show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: master01.domain
Master_User: slave
Master_Port: 3306
Connect_Retry: 3
Master_Log_File: mysql-bin.003
Read_Master_Log_Pos: 73
Relay_Log_File: mysqld-relay-bin.003
Relay_Log_Pos: 73
Relay_Master_Log_File: mysql-bin.003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
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: 73
Relay_Log_Space: 552
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
Sprawdzamy, czy wszystko dobrze działa:
master01:
mysql> use testha;
mysql> create table test (id int (10));
mysql> show tables;
+——————+
| test |
+——————+
1 row in set (0.00 sec)
master02:
mysql> use testha;
mysql> show tables;
+——————+
| test |
+——————+
1 row in set (0.00 sec)
mysql> drop table test;
master01:
mysql> show tables;
Empty set (0.00 sec)
Jeśli o niczym nie zapomnieliśmy (lub ja nie zapomniałem ;-)) replikacja powinna działać już bezproblemowo w obie strony.
Bierzemy się za heartbeata.
Heartbeat będzie sprawdzał czy połączenie sieciowe działa pingując gateway (opcja ping w /etc/ha.d/ha.cf).
Instalacja heartbeat:
# yum install heartbeat
Na obu serwerach wszystkie pliki konfiguracyjne powinny wyglądać tak samo!
Edytujemy /etc/ha.d/authkeys:
auth 1
1 crc
Ustawiamy uprawnienia:
# chmod 600 /etc/ha.d/authkeys
Edytujemy /etc/ha.d/haresources:
master01 IPaddr::192.168.20.1/32
Edytujemy /etc/ha.d/ha.cf:
logfile /var/log/ha-log
keepalive 200ms
deadtime 15
deadping 15
initdead 80
ucast eth0 192.168.20.2
ucast eth0 192.168.20.3
udpport 694
node master01
node master02
auto_failback on
ping 192.168.20.253
respawn hacluster /usr/lib64/heartbeat/ipfail # w zależności od architektury.
autojoin none
Po wszystkim startujemy heartbeata na master01 oraz master02:
# /etc/init.d/heartbeat restart
Możemy teraz przetestować od siebie z lokalnej maszyny czy HA działa poprawnie:
Mój ulubiony sposób – a zarazem (według mnie) najłatwiejszy – to stworzenie bazy testowej na jednym serwerze a potem bawienie się w halty, shutdowny, killowanie heartbeata, czy co tam innego lubicie ;-)
Na obu serwerach nadajemy uprawnienia naszej maszynie do połączenia z mysql:
mysql> grant usage on *.* to 'nicon’@’192.168.20.123′;
Na serwerze master01 tworzymy bazę danych „hatest„:
mysql> create database hatest;
Logujemy się na masterha:
$ mysql -u nicon -h masterha.domain
mysql> show databases;
+————————————————————+
| Database |
+————————————————————+
| hatest |
| information_schema |
| mysql |
| testha |
+————————————————————+
4 rows in set (0.00 sec)
Jak widać powyżej jesteśmy w rzeczywistości na master01.
Nie będziemy się bawić w restartowanie mastera, szkoda czasu, tak więc wyłączamy heartbeat na master01:
# /etc/init.d/heartbeat stop
Odczekujemy chwilę, możemy w tym czasie podglądać logi z master02:
# tail -f /var/log/ha-log
W momencie gdy pojawi nam się dużo ładnie wyglądających nowych linijek ( ;-) ) logujemy się ponownie na masterha:
$ mysql -u nicon -h masterha
mysql> show databases;
+————————————————————+
| Database |
+————————————————————+
| information_schema |
| mysql |
| testha |
+————————————————————+
3 rows in set (0.00 sec)
Jeśli wszystko poszło dobrze powinniśmy zalogować się w rzeczywistości na master02 – czyli nie zobaczyć naszej bazy ’hatest’.
Po ponownym uruchomieniu heartbeat:
# /etc/init.d/heartbeat start
Powinniśmy po zalogowaniu na masterha ponownie zobaczyć naszą bazę ’hatest’.
Mam nadzieję, że to howto trochę położy tę skałke, jaką jest temat replikacji z HA.
Enjoy!
2 odpowiedzi na Replikacja MySQL + HA