Настройка репликации Master-Master на MySQL

Настройка репликации Master-Master на MySQL

Репликация в виде Master-Master  в MySQL используется распределения нагрузки на БД между нодами. С помощью репликации, 2 (и больше) отдельных MySQL серверов выступают в качестве кластера. Кластеризация базы данных особенно полезна для обеспечения высокой производительности. Используйте два и более выделенных серверов (нод) для настройки репликации базы данных ( но для этого нужно выделенные IPv4 адреса).

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

  1. Master-Slave
  2. Master-Master

При использовании репликации Master-Slave, на Master ноде данные поступают ( с ними можно выполнять любые операции (добавлять/удалять/изменять) и все изменения Slave нода будет забирать себе, но если на Slave ноде  вы выполните любой из запросов ( удаление, добавление или изменение), то данные не попадут на Master.

При репликации в виде Master-Master данные попавшие на ноды, будут синхронизироваться между собой.

 Имеется: 

  • (Мастер 1) — Сервер с ОС Debian 8 — 192.168.13.147
  • (Мастер 2) — Сервер с ОС CentOS 7 -192.168.13.151

Взял специально 2 сервера с разными ОС для того чтобы показать что оно может работать корректно ( можно использовать не ограниченное количество нод, хоть 100 шт).

Репликация master-master в MYSQL

Данный процесс настройки master-master репликации поделен на 2 шага:

  • На 1-м шаге, организую master-slave репликацию, где главным будет master_1, а подчиненным будет master_2;
  • На 2-м шаге я организую обратную master-slave репликацию, и сервера начинают собирать информацию из логов друг друга.

Установка MYSQL в Unix/Linux

У меня имеется ряд статей по установке mysql на различные Unix/Linux ОС, по этому если кто-то не знает как установить, может воспользоваться следующими статьями:

Установка MySQL на Debian/Ubuntu/Linux Mint

Установка MySQL 5.5 на RHEL / CentOS и Fedora

Установка MySQL из портов во FreeBSD

Установка MariaDB 10 на CentOS 7

Установка MariaDB на Debian

Установка MariaDB 5.5 на RHEL / CentOS / Fedora Linux

Установка MariaDB в Ubuntu 12.04/12.10/13.04/13.10/14.04

Настройка репликации Master-Master на MySQL

И так, mysql установлен на всех серверах (у меня их 2, но можно подключить и больше) и следующим шагом нужно отредактировать my.cnf файл на каждой из нод.

На 1-м сервере с ОС Debian 8 (192.168.13.147):

# vim /etc/mysql/my.cnf

Вставляем:

[mysqld]
#Уникальный идентификатор сервера
server-id = 1
 
#Логи ошибок
log_error = /var/log/mysql/mysql.err
 
#Путь к bin-логам сервера(бинлог, который ведет мастер)
log_bin = /var/log/mysql/mysql-bin.log
log_bin_index = /var/log/mysql/mysql-bin.log.index
 
#Путь к relay-логам слейва (бинлог, скачанный с мастера)
relay_log = /var/log/mysql/mysql-relay-bin
relay_log_index = /var/log/mysql/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 генерировались начиная с 1-го прибавляя по 2,
# например 13, 23, 33, 43...
auto_increment_increment = 2
auto_increment_offset = 1
 
#Сохранять логи с мастера в своий бин-лог, чтобы передать слейву
log-slave-updates
#log_slave_updates = 1

# Сколько дней хранить бин-логи
expire_logs_days = 7

# Максимальный размер бин-лога
max_binlog_size = 500M

# Адрес 1-го мастера
bind-address = 192.168.13.147

В моем конфиге будет реплицироваться все БД, но если хотите сделать репликацию только 1 базы данных — стоит раскомментировать «binlog_do_db» поле и указать в нем имя БД.

Создаем пользователя для репликации:

mysql> create user 'replica'@'%' identified by '%repl2017'; 
Query OK, 0 rows affected (0.00 sec)

mysql> grant replication slave on *.* to 'replica'@'%'; 
Query OK, 0 rows affected (0.00 sec)

mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)

mysql> exit
Bye
[root@localhost captain]#

PS: Для более крутой безопасности, можно указать конкретно IP:

# create user 'replica'@'192.168.13.147' identified by '%repl2017'; 
# GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.13.147' IDENTIFIED BY '%repl2017';

Перезапускаем MySQL сервер:

# service mysql restart

Собственно, первый MASTER готов!

Смотрим статус мастера (данная информация понадобится немного позже):

mysql> show master status; 
+------------------+----------+--------------+---------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            |
+------------------+----------+--------------+---------------------------------------------+
| mysql-bin.000002 |      107 |              | information_schema,mysql,performance_schema |
+------------------+----------+--------------+---------------------------------------------+
1 row in set (0.00 sec)

mysql> 

Вот.

На 2-м сервере с ОС CentOS 7 -192.168.13.151:

# vim /etc/my.cnf

Вставляем:

[mysqld]
#Уникальный идентификатор сервера
server-id = 2
 
#Логи ошибок
log_error = /var/log/mysql/mysql.err
 
#Путь к bin-логам сервера(бинлог, который ведет мастер)
log_bin = /var/log/mysql/mysql-bin.log
log_bin_index = /var/log/mysql/mysql-bin.log.index
 
#Путь к relay-логам слейва (бинлог, скачанный с мастера)
relay_log = /var/log/mysql/mysql-relay-bin
relay_log_index = /var/log/mysql/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 генерировались начиная с 2-го прибавляя по 2,
# например 13, 23, 33, 43...
auto_increment_increment = 2
auto_increment_offset = 2
 
#Сохранять логи с мастера в своий бин-лог, чтобы передать слейву
log-slave-updates
#log_slave_updates = 1

# Сколько дней хранить бин-логи
expire_logs_days = 7

# Максимальный размер бин-лога
max_binlog_size = 500M

# Адрес 2-го мастера
bind-address = 192.168.13.151

Создаем папку и файлы ( в них будут писаться логи):

# mkdir /var/log/mysql
# chown -R mysql. /var/log/mysql

Создаем пользователя для репликации:

mysql> create user 'replica'@'%' identified by '%repl2017'; grant replication slave on *.* to 'replica'@'%'; flush privileges; exit

PS: Для более крутой безопасности, можно указать конкретно IP:

# create user 'replica'@'192.168.13.147' identified by '%repl2017'; 
# GRANT REPLICATION SLAVE ON *.* TO 'replica'@'192.168.13.147' IDENTIFIED BY '%repl2017';

Перезапускаем MySQL сервер:

# service mysqld restart

Идем дальше.

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

Сейчас нужно настроить саму репликацию. Для начала, запускаем репликацию на 2-м мастере, но чтобы сделать это, необходимо узнать «MASTER_LOG_FILE» и «MASTER_LOG_POS»  на 1-м мастере.

Смотрим статус мастера ( я выводил его выше) на 1-й ноде:

# mysql -u root -p -e 'show master status;'

Или:

mysql> show master status;

Вывод:

+------------------+----------+--------------+---------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            |
+------------------+----------+--------------+---------------------------------------------+
| mysql-bin.000002 |      107 |              | information_schema,mysql,performance_schema |
+------------------+----------+--------------+---------------------------------------------+
1 row in set (0.00 sec)

Видим, что «MASTER_LOG_FILE = mysql-bin.000002, а «MASTER_LOG_POS» = 107.

На 2-й ноде выполняем:

mysql> slave stop; 
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.13.147', MASTER_USER = 'replica', MASTER_PASSWORD = '%repl2017', MASTER_LOG_FILE = 'mysql-bin.000002', MASTER_LOG_POS = 107; 
Query OK, 0 rows affected (0.02 sec)

mysql> slave start;
Query OK, 0 rows affected (0.00 sec)

mysql> 

Думаю что не стоит объяснять что и где нужно заменить — это интуитивно понятно.

Делаем репликацию на 1-м сервере, но для этого смотрим мастер статус на 2-м:

mysql> SHOW MASTER STATUS; 
+------------------+----------+--------------+---------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                            |
+------------------+----------+--------------+---------------------------------------------+
| mysql-bin.000002 |      106 |              | information_schema,mysql,performance_schema |
+------------------+----------+--------------+---------------------------------------------+
1 row in set (0.00 sec)

mysql> 

Видим, что «MASTER_LOG_FILE = mysql-bin.000002, а «MASTER_LOG_POS» = 106.

И на 1-м выполняем команду:

mysql> slave stop; 
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.13.151', MASTER_USER = 'replica', MASTER_PASSWORD = '%repl2017', MASTER_LOG_FILE = 'mysql-bin.000002', MASTER_LOG_POS = 106; 
Query OK, 0 rows affected (0.03 sec)

mysql> slave start;
Query OK, 0 rows affected (0.00 sec)

mysql> 

После чего, можно посмотреть статус слейва на всех мастерах.

МАСТЕР_1:

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.13.151
                  Master_User: replica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 106
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 252
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          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: 106
              Relay_Log_Space: 408
              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
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql>

МАСТЕР_2:

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.13.147
                  Master_User: replica
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 107
               Relay_Log_File: mysql-relay-bin.000002
                Relay_Log_Pos: 252
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          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: 107
              Relay_Log_Space: 407
              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: 
1 row in set (0.00 sec)

ERROR: 
No query specified

mysql> 

Если необходимо собрать кластер более чем 2 мастера, то необходимо соединять их постепенно и по цепочке. А сейчас, перейдем к тестированию созданного кластера.

Тестирования репликации master-master в mysql

Потестируем репликацию и убедимся что все хорошо работает.

На 1-м мастере я создам базу данных и таблицу:

mysql> create database master_1;
Query OK, 1 row affected (0.00 sec)

mysql> create table master_1.flowers (`id` varchar(10));
Query OK, 0 rows affected (0.01 sec)

mysql>

На мастере 2 смотрю что получилось:

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| master_1 |
| mysql |
| test |
+--------------------+
4 rows in set (0.00 sec)

mysql> show tables in master_1
 -> ;
+--------------------+
| Tables_in_master_1 |
+--------------------+
| flowers |
+--------------------+
1 row in set (0.00 sec)

mysql>

Видно что репликация работает и все данные реплицировало на 2-й мастер с 1-го. Переходим тестировать мастер 2, для этого, я создаю на нем же БД и таблицу:

mysql> create database master_2;
Query OK, 1 row affected (0.00 sec)

mysql> create table master_2.flowers (`id` varchar(10));
Query OK, 0 rows affected (0.00 sec)

mysql> 

И на 1-м выполняю команду:

mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| master_1 |
| master_2 |
| mysql |
| performance_schema |
+--------------------+
5 rows in set (0.01 sec)

mysql> show tables in master_2;
+--------------------+
| Tables_in_master_2 |
+--------------------+
| flowers |
+--------------------+
1 row in set (0.00 sec)

mysql>

Видим что все работает должным образом и настройка репликации Master-Master на MySQL завершена!

One thought on “Настройка репликации Master-Master на MySQL

  1. Приветствую!
    Спасибо за статью, у Вас во втором конфиге ошибка в комментарии к автоинкременту и отсутствует заголовок [mysqld].

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.