Как настроить репликацию (Master-Master) на MariaDB

Как настроить репликацию (Master-Master) на MariaDB

Roman Bogachev VMware Specialist | Drone Pilot | Traveler

Настройка репликации данных MASTER-MASTER на MariaDB сервере.

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

В другом случае можно настроить Master-Master репликацию в обоих направлениях. Данный вид репликации может создать небольшие потенциальные проблемы, так как изменения данных происходит на двух серверах одновременно. Проблема может возникнуть в случае, если таблицы используют AUTO_INCREMENT поля. Чтобы решить данную проблему необходимо в настройках MySQL-сервера указать параметры auto_increment_increment и auto_increment_offset.

MASTER-MASTER REPLICATION

Шаг 1. Установка MariaDB

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

Шаг 2. Настройка MASTER-1

Редактируем файл /etc/my.cnf.d/server.cnf

1
2
3
4
5
6
7
8
# bind-address          = 127.0.0.1
server-id = 1
report_host = master1
log_bin = /var/lib/mysql/mariadb-bin
log_bin_index = /var/lib/mysql/mariadb-bin.index
relay_log = /var/lib/mysql/relay-bin
relay_log_index = /var/lib/mysql/relay-bin.index
# replicate-do-db = testdb

# bind-address = 127.0.0.1
По умолчанию MySQL разрешает соединения локально. Мы закомментируем данную строчку, чтобы разрешить подключения с других узлов. Это очень важно для того, чтобы репликация работала.

server-id = 1
report_host = master1
Указываем ID сервера и хостнейм.

log_bin = /var/lib/mysql/mariadb-bin
Указываем местоположение двоичного журнала обновлений, в котором будут вестись записи.

log_bin_index = /var/lib/mysql/mariadb-bin.index
Так как пользователь может выполнять команду FLUSH LOG, нужно знать, какой журнал является активным в настоящее время, а также какие журналы использовались ранее и в какой последовательности они сменялись.

relay_log = /var/lib/mysql/relay-bin
relay_log_index = /var/lib/mysql/relay-bin.index
Включение relay_log. События, которые читают bin_log с Master и записывают в relay.

replicate-do-db = testdb
Данный параметр сообщает MariaDB какую базу реплицировать. Этот парметр опциональный, если не указывать, то будут реплицироваться все существующие базы.

binlog-ignore-db = information_schema
binlog-ignore-db = mysql
Исключаем из репликации базы information_schema и mysql

expire_logs_days = 15
Очищение старых bin_log файлов

auto_increment_offset
Определяет начальное значение для столбцов с атрибутом AUTO_INCREMENT и для каждого сервера должно быть уникальным и меньшим значения auto_increment_increment

auto_increment_increment
Значение auto_increment_increment определяет интервал между значениями auto_increment на отдельном сервере. Для предотвращения конфликтов установите ему значение, как минимум равное числу серверов в цикле.

slave-skip-errors = 1062
Параметр сообщает потоку подчиненного сервера, что он должен продолжать репликацию, если запрос возвращает ошибку, указанную в списке.

replicate-rewrite-db=from_name->to_name
Обновления производятся не в подлинную базу данных, а в базу данных с именем, указанным в опции.
Пример: replicate-rewrite-db=master_db_name->slave_db_name

replicate-ignore-table
Сообщаем подчиненному серверу, что указанная база данных реплицироваться не должна. Чтобы указать более одной базы данных, директиву следует использовать несколько раз, по одному разу для каждой базы данных.
Пример: replicate-ignore-db=some_db

replicate-do-table=db_name.table_name
Сообщает подчиненному серверу, что он должен реплицировать только указанную таблицу. Для указания более чем одной таблицы директиву следует использовать несколько раз, по одному разу для каждой таблицы.

slave_net_timeout=#
Время ожидания (в секундах) дополнительных данных от головного сервера, после чего чтение будет прервано.

max_binlog_size=#
Максимальный размер, минимум 4096 байт, по умолчанию 1073741824 байт (1 гигабайт):

После сохранения настроек не забываем перезагрузить сервис MySQL

1
service mysql restart

Шаг 3. Создание пользователя на MASTER-1

Для репликации используется отдельный пользователь.

1
2
MariaDB [(none)]> create user 'replication_user'@'%' identified by 'replication_user';
MariaDB [(none)]> grant replication slave on *.* to 'replication_user'@'%';

Проверим состояние бинарного лога для того, чтобы запустить репликацию на другом сервере

1
2
3
4
5
6
7
MariaDB [(none)]> show master status;
+--------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+--------------------+----------+--------------+------------------+
| mariadb-bin.000001 | 314 | | |
+--------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Шаг 4. Настройка MASTER-2

Редактируем файл /etc/my.cnf.d/server.cnf

1
2
3
4
5
6
7
8
# bind-address          = 127.0.0.1
server-id = 2
report_host = master2
log_bin = /var/lib/mysql/mariadb-bin
log_bin_index = /var/lib/mysql/mariadb-bin.index
relay_log = /var/lib/mysql/relay-bin
relay_log_index = /var/lib/mysql/relay-bin.index
# replicate-do-db = testdb

После сохранения настроек не забываем перезагрузить сервис MySQL

1
service mysql restart

Шаг 5. Создание пользователя на MASTER-2

На втором сервере также создаем пользователя под репликацию

1
2
MariaDB [(none)]> create user 'replication_user'@'%' identified by 'replication_user';
MariaDB [(none)]> grant replication slave on *.* to 'replication_user'@'%';

Шаг 6. Запуск репликации на MASTER-2

Останавливаем репликацию

1
MariaDB [(none)]> STOP SLAVE;

Указываем хостнейм, пользователя, пароль, bin_log и его позицию:

1
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='master1', MASTER_USER='replication_user', MASTER_PASSWORD='replication_user_password', MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=314;

Запускаем слейв сервер

1
MariaDB [(none)]> START SLAVE;

для MASTER_LOG_FILE и MASTER_LOG_POS я использую информацию из show master status с первого сервера.

Проверяем статус слейва

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State : Waiting for master to send event
Master_Host : master2
Master_User : replication
Master_Port : 3306
Connect_Retry : 60
Master_Log_File : mariadb-bin.000001
Read_Master_Log_Pos : 84581249
Relay_Log_File : slave-relay-bin.000002
Relay_Log_Pos : 78751023
Relay_Master_Log_File : mariadb-bin.000001
Slave_IO_Running : Yes
Slave_SQL_Running : Yes
Replicate_Do_DB :
Replicate_Ignore_DB : mysql,information_schema
Replicate_Do_Table :
Replicate_Ignore_Table : forum.sessions, site.temp_user, gallery.thumb
Replicate_Wild_Do_Table :
Replicate_Wild_Ignore_Table :
Last_Errno : 0
Last_Error :
Skip_Counter : 0
Exec_Master_Log_Pos : 84581249
Relay_Log_Space : 78751178
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 rows in set (0.08 sec)

Обратите внимание на Read_Master_Log_Pos и Exec_Master_Log_Pos, что они имеют хороший показатель, который означает, что базы синхронизированы.

Теперь узнаем позицию bin_log на MASTER-2

1
2
3
4
5
6
7
mysql> show master status;
+------------------+----------+--------------+--------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+--------------------------+
| mariadb-bin.000002 | 81969933 | | information_schema,mysql |
+------------------+----------+--------------+--------------------------+
1 rows in set (0.01 sec)

Шаг 7. Запуск репликации на MASTER-1

Останавливаем репликацию

1
MariaDB [(none)]> STOP SLAVE;

Указываем хостнейм, пользователя, пароль, bin_log и его позицию:

1
MariaDB [(none)]> CHANGE MASTER TO MASTER_HOST='master2', MASTER_USER='replication_user', MASTER_PASSWORD='replication_user_password', MASTER_LOG_FILE='mariadb-bin.000002', MASTER_LOG_POS=81969933;

Запускаем слейв сервер

1
MariaDB [(none)]> START SLAVE;

Проверяем статус слейва

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State : Waiting for master to send event
Master_Host : master1
Master_User : replication
Master_Port : 3306
Connect_Retry : 60
Master_Log_File : mariadb-bin.000002
Read_Master_Log_Pos : 84581249
Relay_Log_File : slave-relay-bin.000003
Relay_Log_Pos : 78751023
Relay_Master_Log_File : mariadb-bin.000002
Slave_IO_Running : Yes
Slave_SQL_Running : Yes
Replicate_Do_DB :
Replicate_Ignore_DB : mysql,information_schema
Replicate_Do_Table :
Replicate_Ignore_Table : forum.sessions, site.temp_user, gallery.thumb
Replicate_Wild_Do_Table :
Replicate_Wild_Ignore_Table :
Last_Errno : 0
Last_Error :
Skip_Counter : 0
Exec_Master_Log_Pos : 84581249
Relay_Log_Space : 78751178
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 rows in set (0.08 sec)

Все отлично. Теперь создадим тестовую базу для проверки на MASTER-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
MariaDB [(none)]> create database testdb;

MariaDB [(none)]> use testdb;
Database changed

MariaDB [testdb]> CREATE TABLE users (id INT AUTO_INCREMENT,
-> name VARCHAR(30),
-> datum TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-> PRIMARY KEY(id));
Query OK, 0 rows affected (0.50 sec)

MariaDB [testdb]> INSERT INTO users(name) VALUES ('User1');
Query OK, 1 row affected (0.06 sec)

MariaDB [testdb]> select * from users;
+----+-------+---------------------+
| id | name | datum |
+----+-------+---------------------+
| 1 | User1 | 2015-05-28 17:41:41 |
+----+-------+---------------------+
1 row in set (0.00 sec)

Проверяем данные на MASTER-2

1
2
3
4
5
6
7
8
9
10
MariaDB [testdb]> use testdb
Database changed

MariaDB [testdb]> select * from users;
+----+-------+---------------------+
| id | name | datum |
+----+-------+---------------------+
| 1 | User1 | 2015-05-28 17:41:41 |
+----+-------+---------------------+
1 row in set (0.00 sec)

Вносим изменения на сервере MASTER-2

1
2
3
4
5
6
7
8
9
10
11
MariaDB [testdb]> INSERT INTO users(name) VALUES('User2');
Query OK, 1 row affected (0.39 sec)

MariaDB [testdb]> select * from users;
+----+-------+---------------------+
| id | name | datum |
+----+-------+---------------------+
| 1 | User1 | 2015-05-28 17:41:41 |
| 2 | User2 | 2015-05-28 17:44:17 |
+----+-------+---------------------+
2 rows in set (0.00 sec)

Проверяем данные на MASTER-1

1
2
3
4
5
6
7
8
MariaDB [testdb]> select * from users;
+----+-------+---------------------+
| id | name | datum |
+----+-------+---------------------+
| 1 | User1 | 2015-05-28 17:41:41 |
| 2 | User2 | 2015-05-28 17:44:17 |
+----+-------+---------------------+
2 rows in set (0.00 sec)

Как видно, то данные реплицировались.

Примечание

При восстановлении репликации создадим файл резервной копии с позицией бин-лога.

1
mysqldump --skip-lock-tables --single-transaction --flush-logs --hex-blob --master-data=2 -A  > ~/dump.sql

Это будет влиять на производительность сервера баз данных, но не будет блокировать таблицы.