В предыдущей статье шла речь о базовой установке и настройке Percona mysql под управлением операционной системы Ubuntu 12.04. В связи с чем переходим к настройке репликации созданной БД.
3 Настройка репликации
В mysql существует два типа репликации данных:
- Master-Slave
- Master-Master
Master-Slave репликация. На Master сервере данные добавляются, удаляются и изменяются. Slave сервер стягивает эти обновления себе и постепенно выполняет все полученные запросы. Если на Slave сервере будет добавлена новая таблица или БД, то данные не попадут на Master.
При Master-Master репликации данные попавшие на оба сервера будут среплицированы между собой.
3.1 Master-Master репликация
Сначала настроим Мастер-Мастер репликацию (рис. 2).
Рисунок 2 — Схема Master-Master репликации
В предыдущей статье было установлено percona mysql, создано тестовую БД и добавлено юзера для репликации. Теперь переходим к настройке репликации.
Для этого нам нужно добавить конфигурационный файл /etc/mysql/my.cnf для каждого mysql-сервера, который входит в репликацию. Здесь нужно прописать уникальный идентификатор сервера и БД, которые нужно и не нужно реплицировать. Также здесь прописывается множество дополнительных настроек mysql сервера, о которых можно узнать на официальном сайте. Я же наведу самую нужную малость.
3.1.1 Настройка m-serv1 мастера
Сначала настроим первый мастер-сервер.
root@m-serv1:~# cat /etc/mysql/my.cnf [mysqld] #Уникальный идентификатор сервера server-id = 1 #Логи ошибок log_error = /var/log/mysql/mysql.err #Путь к bin-логам сервера(бинлог, который ведет мастер) log-bin = /var/lib/mysql/server-mysql-bin log-bin-index = /var/lib/mysql/server-mysql-bin.index #Путь к relay-логам слейва (бинлог, скачанный с мастера) relay-log = /var/lib/mysql/slave-mysql-relay-bin relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index #БД, которые нужно/не нужно реплицировать replicate-do-db = testdb replicate-ignore-db=information_schema replicate-ignore-db=mysql replicate-ignore-db=performance_schema #Не вести журнал бин-лога для БД binlog-ignore-db = information_schema binlog-ignore-db = mysql binlog-ignore-db = performance_schema #Чтобы не было конфликтов автоинкремента, говорим серверу, #чтобы id генерировались начиная с 3-го прибавляя по 10, # например 13, 23, 33, 43... auto_increment_increment = 10 auto_increment_offset = 3 #Сохранять логи с мастера в своий бин-лог, чтобы передать слейву log-slave-updates
Как видим, здесь мы добавили для репликации только testdb БД. Теперь рестартуем mysql.
root@m-serv1:~# /etc/init.d/mysql restart * Stopping MySQL (Percona Server) mysqld [ OK ] * Starting MySQL (Percona Server) database server mysqld [ OK ] * Checking for corrupt, not cleanly closed and upgrade needing tables.
3.1.2 Настройка m-serv2 мастера
Настройка второго мастера аналогична первому, только меняется id и offset
root@m-serv2:~# cat /etc/mysql/my.cnf [mysqld] #Уникальный идентификатор сервера server-id = 2 #Логи ошибок log_error = /var/log/mysql/mysql.err #Путь к bin-логам сервера(бинлог, который ведет мастер) log-bin = /var/lib/mysql/server-mysql-bin log-bin-index = /var/lib/mysql/server-mysql-bin.index #Путь к relay-логам слейва (бинлог, скачанный с мастера) relay-log = /var/lib/mysql/slave-mysql-relay-bin relay-log-index = /var/lib/mysql/slave-mysql-relay-bin.index #БД, которые нужно/не нужно реплицировать replicate-do-db = testdb replicate-ignore-db=information_schema replicate-ignore-db=mysql replicate-ignore-db=performance_schema #Не вести журнал бин-лога для БД binlog-ignore-db = information_schema binlog-ignore-db = mysql binlog-ignore-db = performance_schema #Чтобы не было конфликтов автоинкремента, говорим серверу, #чтобы id генерировались начиная с 4-го прибавляя по 10, # например 14, 24, 34, 44... auto_increment_increment = 10 auto_increment_offset = 4 #Сохранять логи с мастера в своий бин-лог, чтобы передать слейву log-slave-updates
Рестартуем mysql.
root@m-serv2:~# /etc/init.d/mysql restart * Stopping MySQL (Percona Server) mysqld [ OK ] * Starting MySQL (Percona Server) database server mysqld [ OK ] * Checking for corrupt, not cleanly closed and upgrade needing tables.
3.1.3 Запуск репликации
Сначала запустим репликацию на первом мастере m-serv1. Для этого нам нужно знать MASTER_LOG_FILE и MASTER_LOG_POS m-serv2 сервера, т.е. нашего второго мастера. Логинимся на m-serv2 и смотрим master status.
root@m-serv2:~# mysql -u root -p -e 'show master status;' +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | server-mysql-bin.000001 | 120 | | information_schema,mysql,performance_schema | | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+
Следовательно MASTER_LOG_FILE = server-mysql-bin.000001, а MASTER_LOG_POS = 120. Теперь переходим на m-serv1 и настраиваем репликацию.
root@m-serv1:~# mysql -u root -p -e "CHANGE MASTER TO MASTER_HOST = '192.168.1.202', MASTER_USER = 'replica', MASTER_PASSWORD = '%repl2015', MASTER_LOG_FILE = 'server-mysql-bin.000001', MASTER_LOG_POS = 120;"
Все интуитивно понятно. Теперь стартуем слейв и смотрим статус.
root@m-serv1:~# mysql -u root -p -e 'start slave;' root@m-serv1:~# mysql -u root -p -e 'show slave status \G;' *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.202 Master_User: replica Master_Port: 3306 Connect_Retry: 60 Master_Log_File: server-mysql-bin.000001 Read_Master_Log_Pos: 120 Relay_Log_File: slave-mysql-relay-bin.000002 Relay_Log_Pos: 290 Relay_Master_Log_File: server-mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: testdb Replicate_Ignore_DB: information_schema,mysql,performance_schema 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: 120 Relay_Log_Space: 469 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 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2 Master_UUID: 25f9f3ac-fd3b-11e4-bb77-080027ead940 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0
Со всего этого вывода нас интересуют Seconds_Behind_Master (время отставания реплики от мастера), Slave_IO_State (должно писать, что ждет новостей от мастера), Slave_IO_Running (Yes) и Slave_SQL_Running (Yes). Если репликация идет нормально, реплика будет следовать за мастером (номер лога в Master_Log_File и позиция Exec_Master_Log_Pos будут расти). Отставания реплики от мастера (Seconds_Behind_Master), должно быть нулевым, но может расти. Если же значение Slave_IO_State пусто, а Seconds_Behind_Master равно NULL, репликация не началась.
У нас все гуд. Поэтому узнаем master статус на m-serv1 и беремся за m-serv2.
root@m-serv1:~# mysql -u root -p -e 'show master status;' +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+ | server-mysql-bin.000005 | 120 | | information_schema,mysql,performance_schema | | +-------------------------+----------+--------------+--------------------------------------------------+-------------------+
Логинимся на m-serv2 и стартуем репликация.
root@m-serv2:~# mysql -u root -p -e "CHANGE MASTER TO MASTER_HOST = '192.168.1.201', MASTER_USER = 'replica', MASTER_PASSWORD = '%repl2015', MASTER_LOG_FILE = 'server-mysql-bin.000005', MASTER_LOG_POS = 120;" root@m-serv2:~# mysql -u root -p -e 'start slave;' root@m-serv2:~# mysql -u root -p -e 'show slave status \G;' *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.1.201 Master_User: replica Master_Port: 3306 Connect_Retry: 60 Master_Log_File: server-mysql-bin.000005 Read_Master_Log_Pos: 120 Relay_Log_File: slave-mysql-relay-bin.000002 Relay_Log_Pos: 290 Relay_Master_Log_File: server-mysql-bin.000005 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: testdb Replicate_Ignore_DB: information_schema,mysql,performance_schema 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: 120 Relay_Log_Space: 469 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 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1 Master_UUID: f208be92-fa66-11e4-a905-08002742f2f0 Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0
Все прошло успешно. О парочке возможных ошибок и их исправлении будет написано в следующей статье.
3.1.4 Тестируем репликацию
Теперь можно немножко и протестировать. Перейдем на m-serv1 и добавим в testdb.users новую строку.
root@m-serv1:~# mysql -u root -p -e 'USE testdb; INSERT INTO users(name) VALUES ("Vova");' root@m-serv1:~# mysql -u root -p -e 'USE testdb; SELECT * FROM users;' +----+------+ | id | name | +----+------+ | 1 | Alex | | 3 | Vova | +----+------+
Теперь проверим среплицировалась ли запись на второй сервер.
root@m-serv2:~# mysql -u root -p -e 'USE testdb;SELECT * FROM users;' +----+------+ | id | name | +----+------+ | 1 | Alex | | 3 | Vova | +----+------+
Все в порядке, запись попала на второй сервер. Теперь добавим запись на втором сервере и посмотрим попадет ли она на первый мастер.
root@m-serv2:~# mysql -u root -p -e 'USE testdb; INSERT INTO users(name) VALUES ("Pasha");' root@m-serv2:~# mysql -u root -p -e 'USE testdb; SELECT * FROM users;' +----+-------+ | id | name | +----+-------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | +----+-------+
Смотрим на первом мастере.
root@m-serv1:~# mysql -u root -p -e 'USE testdb; SELECT * FROM users;' +----+-------+ | id | name | +----+-------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | +----+-------+
Как видим, все ок. Добавим еще по одной записи.
root@m-serv1:~# mysql -u root -p -e 'USE testdb;INSERT INTO users(name) VALUES ("Frodo");' root@m-serv1:~# mysql -u root -p -e 'USE testdb; SELECT * FROM users;' +----+-------+ | id | name | +----+-------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | +----+-------+ root@m-serv2:~# mysql -u root -p -e 'USE testdb; INSERT INTO users(name) VALUES ("Misha");' root@m-serv2:~# mysql -u root -p -e 'USE testdb; SELECT * FROM users;' +----+-------+ | id | name | +----+-------+ | 1 | Alex | | 3 | Vova | | 4 | Pasha | | 13 | Frodo | | 14 | Misha | +----+-------+
Как видим, если запись добавлена с сервера m-serv1, то поле auto_increment(id) имеет значения 3, 13, а при добавлении записей с m-serv2, эти значения равны 4, 14. Это нужно чтобы избежать ошибок типа Duplicate entry.
В следующей статье пойдет речь о настройке Master-Slave репликации.