Mysql (часть 2). Настройка Master-Master репликации

master-master2В предыдущей статье шла речь о базовой установке и настройке Percona mysql под управлением операционной системы Ubuntu 12.04. В связи с чем переходим к настройке репликации созданной БД.

3 Настройка репликации

В mysql существует два типа репликации данных:

Master-Slave репликация. На Master сервере данные добавляются, удаляются и изменяются. Slave сервер стягивает эти обновления себе и постепенно выполняет все полученные запросы. Если на Slave сервере будет добавлена новая таблица или БД, то данные не попадут на Master.
При Master-Master репликации данные попавшие на оба сервера будут среплицированы между собой.

3.1 Master-Master репликация

Сначала настроим Мастер-Мастер репликацию (рис. 2).

master-master
Рисунок 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 репликации.

Автор: admin, 2 июня 2015
Рубрики: Linux
Метки: ,

Написать комментарий

Последние статьи

Яндекс.Метрика
?>