Создание группы репликации MySQL в Ubuntu 16.04

Репликация MySQL обеспечивает избыточность данных, отражая операции с одной БД в другую. В обычной репликации используется один ведущий сервер, который принимает все операции записи, и ведомые серверы, которые полностью отражают набор данных ведущего сервера.

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

Группы репликации – более гибкий и ошибкоустойчивый вариант. Эта технология подразумевает настройку пула серверов, которые обеспечивают правильное копирование данных. Если на ведущем сервере произошёл сбой, из пула будет выбран новый ведущий сервер. Таким образом, остальные ноды могут продолжать работу даже в случае критической ошибки. Взаимодействие серверов пула, обнаружение ошибок и доставка сообщений реализуются при помощи алгоритма Паксос.

Данное руководство поможет настроить группу репликации, состоящую из трех серверов Ubuntu 16.04.

Требования

  • Три сервера Ubuntu 16.04 (в руководстве они условно называются mysqlmember1, mysqlmember2 и mysqlmember3).
  • Пользователь sudo и настроенный брандмауэр на каждом сервере (руководство по настройке можно найти здесь).
  • Версия MySQL из репозитория Ubuntu не поддерживает групповую репликацию. Чтобы найти MySQL с поддержкой такого плагина, обратитесь к официальному репозиторию проекта MySQL. Все инструкции можно найти здесь.

Генерирование UUID для группы MySQL

Прежде чем приступить к настройке MySQL, нужно сгенерировать UUID для идентификации группы MySQL.

Для этого подключитесь к серверу mysqlmember1 и введите команду uuidgen:

uuidgen
959cf631-538c-415d-8164-ca00181be227

Скопируйте полученное значение, оно понадобится в дальнейшем.

Настройка MySQL для поддержки группы репликации

Примечание: Данный раздел нужно выполнить на всех серверах пула.

Теперь можно отредактировать конфигурационный файл MySQL.

Откройте его:

sudo nano /etc/mysql/my.cnf

По умолчанию этот файл используется только для объединения файлов из других подкаталогов. Потому все настройки нужно добавить после строк !includedir. это позволяет переопределить все необходимые настройки из дополнительных файлов.

Сначала добавьте раздел [mysqld], который будет содержать описание компонентов MySQL. В этот раздел вставьте настройки группы репликации. Префикс loose- позволяет MySQL без ошибок обрабатывать незнакомые опции.

. . .
!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/
[mysqld] # Базовые настройки репликации
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = OFF
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1
# Общие настройки группы репликации
loose-group_replication_group_name = ""
loose-group_replication_ip_whitelist = ""
loose-group_replication_group_seeds = ""
# Настройки режима Single-primary или Multi-primary. Раскомментируйте эти строки,
# чтобы включить multi-primary режим, который позволит обрабатывать операции записи всем серверам группы
#loose-group_replication_single_primary_mode = OFF
#loose-group_replication_enforce_update_everywhere_checks = ON
# Настройки хостов серверов группы
server_id =
bind-address = ""
report_host = ""
loose-group_replication_local_address = ""

Рассмотрим подробнее каждый из четырёх разделов параметров.

Базовые настройки репликации

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

. . .
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE
log_slave_updates = ON
log_bin = binlog
binlog_format = ROW
transaction_write_set_extraction = XXHASH64
loose-group_replication_bootstrap_group = OFF
loose-group_replication_start_on_boot = OFF
loose-group_replication_ssl_mode = REQUIRED
loose-group_replication_recovery_use_ssl = 1
. . .

Эти настройки включают поддержку глобальной транзакции, бинарное логирование и SSL. Также в этом блоке находятся настройки восстановления и запуска группы.

Общие настройки группы репликации

В этом разделе находятся параметры репликации, общие для всех серверов группы. Этот блок должен быть одинаковым на всех нодах. Его нужно отредактировать: указать уникальный UUID, белый список серверов–членов группы и инициирующих серверов, которые предоставляют исходные данные.

В loose-group_replication_group_name укажите UUID, который вы получили с помощью команды uuidgen.

В loose-group_replication_ip_whitelist укажите белый список IP-адресов всех серверов пула MySQL.

Параметр loose-group_replication_group_seeds должен содержать почти тот же белый список, а также порт, который будет использоваться для репликации на всех серверах группы (в руководстве для этого используется рекомендуемый порт 33061).

. . .
loose-group_replication_group_name = "959cf631-538c-415d-8164-ca00181be227"
loose-group_replication_ip_whitelist = "203.0.113.1,203.0.113.2,203.0.113.3"
loose-group_replication_group_seeds = ""203.0.113.1:33061,203.0.113.2:33061,203.0.113.3:33061"
. . .

Отредактируйте его на одном сервере, а затем просто скопируйте его в настройки других серверов группы.

Настройка режимов Single Primary или Multi-Primary

Затем нужно выбрать режим группы single-primary или multi-primary.

Согласно документации MySQL, в первом режиме используется один ведущий сервер, а во втором все серверы группы являются ведущими (т. е. могут обрабатывать операции записи).

Чтобы настроить группу в режиме multi-primary, раскомментируйте директивы loose-group_replication_single_primary_mode и loose-group_replication_enforce_update_everywhere_checks. Чтобы настроить группу в режиме single-primary, оставьте их закомментированными.

. . .
#loose-group_replication_single_primary_mode = OFF
#loose-group_replication_enforce_update_everywhere_checks = ON
. . .

Этот раздел должен быть одинаковым на всех серверах группы.

Чтобы изменить эти параметры, нужно остановить все серверы группы репликации MySQL, запустить каждый сервер с новыми параметрами, а затем перезапустить группу репликации. Эта процедура не повлияет на данные, но вызовет простой сервиса.

Настройки хостов серверов группы

Этот раздел должен быть уникальным на каждом сервере группы. Он содержит следующие данные:

  • ID сервера.
  • Адрес, к которому нужно подключиться.
  • Адрес, который нужно сообщить другим членам группы репликации.
  • Локальный адрес и прослушиваемый порт.

Директива server_id должна содержать уникальный номер на каждом сервере. К примеру, на первом сервере группы это будет 1, на втором – 2 и т. д. В bind-address укажите IP-адрес текущего сервера (чтобы экземпляр MySQL мог прослушивать внешние подключения). Директива report_host позволяет сообщить этот адрес другим серверам группы. В loose-group_replication_local_address нужно указать IP-адрес текущего сервера и порт группы репликации 33061.

. . .
server_id = 1
bind-address = "203.0.113.1"
report_host = "203.0.113.1"
loose-group_replication_local_address = "203.0.113.1:33061"

Повторите этот процесс на каждом сервере группы репликации.

Этот блок настроек должен быть уникальным на каждом сервере. Остальные настройки совпадают. Сохраните и закройте файл.

Перезапуск MySQL и настройка удалённого доступа

После перезагрузки MySQL будет поддерживать группу репликации. Чтобы перезапустить MySQL, введите на каждом сервере группы следующую команду:

sudo systemctl restart mysql

В конфигурационном файле MySQL для внешних соединений настроен порт 3306. Для целей репликации используется порт 33061.

Разблокируйте эти порты в брандмауэре:

sudo ufw allow 33061
sudo ufw allow 3306

Создание пользователя для репликации и включение плагина репликации

Примечание: Этот раздел необходимо выполнить на каждом сервере группы.

Подключитесь к серверу как root:

mysql -u root -p

Система запросит root-пароль MySQL, после чего вы получите доступ к сессии MySQL.

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

Такой пользователь необходим на каждом сервере группы. На время создания пользователей нужно отключить бинарные логи, иначе группа серверов попытается скопировать этого пользователя с ведущего сервера на остальные серверы, что приведёт к конфликту.

Создайте пользователя с поддержкой SSL, передайте ему права на сервер, а затем сбросьте привилегии. После этого можно будет включить бинарное логирование, чтобы восстановить работу группы. Пароль пользователя должен быть сложным.

SET SQL_LOG_BIN=0;
CREATE USER 'repl'@'%' IDENTIFIED BY 'password' REQUIRE SSL;
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;

Затем настройте group_replication_recovery, чтобы использовать новую учётную запись. Это позволить всем серверам группы пройти аутентификацию.

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery';

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

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

Убедитесь, что плагин включен:

SHOW PLUGINS;
+----------------------------+----------+--------------------+----------------------+---------+
| Name                       | Status   | Type               | Library              | License |
+----------------------------+----------+--------------------+----------------------+---------+
|                            |          |                    |                      |         |
| . . .                      | . . .    | . . .              | . . .                | . . .   |
|                            |          |                    |                      |         |
| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------+----------+--------------------+----------------------+---------+
45 rows in set (0.00 sec)

Если в выводе есть строка group_replication, значит, плагин репликации включен.

Запуск группы репликации

Запуск первой ноды

Примечание: Выполните этот раздел на одном сервере группы.

Переменная group_replication_bootstrap_group сообщает серверу из группы, что он не должен ожидать информации от других серверов, а вместо этого должен создать новую группу и стать в ней ведущим. Это возможно только в той ситуации, когда других членов группы ещё не существует, потому эту функцию нужно отключить сразу после запуска группы.

SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

Теперь у вас есть группа репликации, состоящая пока что из одного сервера. Чтобы убедиться в этом, запросите данные из таблицы replication_group_members базы данных performance_schema.

SELECT * FROM performance_schema.replication_group_members;

Вы должны увидеть вывод:

+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
1 row in set (0.00 sec)

Значение ONLINE в столбце MEMBER_STATE указывает, что на данный момент эта нода является единственным членом группы репликации.

Создайте тестовую БД и таблицу, чтобы проверить работу репликации:

CREATE DATABASE playground;
CREATE TABLE playground.equipment ( id INT NOT NULL AUTO_INCREMENT, type VARCHAR(50), quant INT, color VARCHAR(25), PRIMARY KEY(id));
INSERT INTO playground.equipment (type, quant, color) VALUES ("slide", 2, "blue");

Запросите содержимое таблицы

SELECT * FROM playground.equipment;
+----+-------+-------+-------+
| id | type  | quant | color |
+----+-------+-------+-------+
|  1 | slide |     2 | blue  |
+----+-------+-------+-------+
1 row in set (0.00 sec)

Теперь можно добавить в группу другие ноды.

Запуск остальных нод

Перейдите на второй сервер и запустите репликацию. Этот сервер можно просто подключить к существующей группе:

START GROUP_REPLICATION;

То же самое нужно сделать и на третьем сервере:

START GROUP_REPLICATION;

Запросите список членов группы репликации.

SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       |
| group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2  |        3306 | ONLINE       |
| group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3  |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
3 rows in set (0.01 sec)

В столбце MEMBER_STATE указывается состояние серверов группы. Все серверы должны быть ONLINE. Если в новой группе одна или несколько нод находится в состоянии RECOVERING дольше, чем пару секунд, это значит, что в группе произошел сбой или конфликт конфигураций. Подробную информацию можно найти в логе /var/log/mysql/error.log.

Убедитесь, что тестовая БД была скопирована на остальные ноды:

SELECT * FROM playground.equipment;
+----+-------+-------+-------+
| id | type  | quant | color |
+----+-------+-------+-------+
|  1 | slide |     2 | blue  |
+----+-------+-------+-------+
1 row in set (0.01 sec)

Тестирование операций записи

Теперь попробуйте выполнить операцию записи на нодах группы.

Операции записи в среде single primary

Группа в режиме single primary поддерживает операции записи только на ведущем сервере. Остальные серверы должны иметь доступ только к операциям чтения. Чтобы узнать, какой сервер является ведущим, отправьте запрос:

SHOW STATUS LIKE '%primary%';
+----------------------------------+--------------------------------------+
| Variable_name                    | Value                                |
+----------------------------------+--------------------------------------+
| group_replication_primary_member | 13324ab7-1b01-11e7-9dd1-22b78adaa992 |
+----------------------------------+--------------------------------------+
1 row in set (0.01 sec)

Вы получите значение MEMBER_ID, которое можно сравнить с хостом с помощью следующего запроса:

SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       |
| group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2  |        3306 | ONLINE       |
| group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3  |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
3 rows in set (0.01 sec)

Согласно результату, ведущим сервером на данный момент является 203.0.113.1. Если вы попробуете выполнить операцию записи на другом сервере, вы получите ошибку:

INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

Это нормальное поведение, поскольку в такой среде ведомые ноды не поддерживают операций записи. Если ведущий сервер не может продолжать работу из-за сбоя, группа автоматически выберет новый ведущий сервер, который сразу получит доступ к операциям записи.

Операции записи в среде Multi-Primary

В среде Multi-Primary операции записи поддерживают все члены группы репликации.

Чтобы убедиться, что группа работает в режиме Multi-Primary, запросите group_replication_primary_member.

SHOW STATUS LIKE '%primary%';
+----------------------------------+-------+
| Variable_name                    | Value |
+----------------------------------+-------+
| group_replication_primary_member |       |
+----------------------------------+-------+
1 row in set (0.02 sec)

Если эта переменная пуста, значит, в текущей среде нет ведущего сервера. Следовательно, все серверы группы поддерживают операции записи.

Попробуйте выполнить следующую операцию на любом сервере группы:

INSERT INTO playground.equipment (type, quant, color) VALUES ("swing", 10, "yellow");
Query OK, 1 row affected (0.00 sec)

Операция должна пройти без ошибок.

Перейдите на третий сервер группы и убедитесь, что он скопировал данные:

SELECT * FROM playground.equipment;
+----+-------+-------+--------+
| id | type  | quant | color  |
+----+-------+-------+--------+
|  1 | slide |     2 | blue   |
|  2 | swing |    10 | yellow |
+----+-------+-------+--------+
2 rows in set (0.00 sec)

Теперь попробуйте выполнить операцию записи на третьем сервере:

INSERT INTO playground.equipment (type, quant, color) VALUES ("seesaw", 3, "green");
Query OK, 1 row affected (0.02 sec)

Вернитесь на первый сервер группы и убедитесь, что он скопировал данные, добавленные с других серверов.

SELECT * FROM playground.equipment;
+----+--------+-------+--------+
| id | type   | quant | color  |
+----+--------+-------+--------+
|  1 | slide  |     2 | blue   |
|  2 | swing  |    10 | yellow |
|  3 | seesaw |     3 | green  |
+----+--------+-------+--------+
3 rows in set (0.01 sec)

Повторный запуск группы

После запуска отдельные участники могут присоединиться к группе и покинуть её, не влияя на доступность (пока в группе достаточно серверов для выбора ведущего). Однако после определенных изменений конфигурации (например, после переключения между режимами single и multi-primary или замены всех членов группы) может понадобиться перезагрузить группу.

На первом сервере установите переменную group_replciation_bootstrap_group и попробуйте инициировать группу.

SET GLOBAL GROUP_REPLICATION_BOOTSTRAP_GROUP=ON;
START GROUP_REPLICATION;
SET GLOBAL GROUP_REPLICATION_BOOTSTRAP_GROUP=OFF;

После запуска первого члена группы добавьте остальные серверы:

START GROUP_REPLICATION;

Теперь все серверы группы должны быть включены и доступны:

SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
| group_replication_applier | 13324ab7-1b01-11e7-9dd1-22b78adaa992 | 203.0.113.1  |        3306 | ONLINE       |
| group_replication_applier | 1ae4b211-1b01-11e7-9d89-ceb93e1d5494 | 203.0.113.2  |        3306 | ONLINE       |
| group_replication_applier | 157b597a-1b01-11e7-9d83-566a6de6dfef | 203.0.113.3  |        3306 | ONLINE       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+
3 rows in set (0.01 sec)

Автоматическое подключение к группе репликации

Согласно текущим настройкам, член группы после перезагрузки не будет подключаться к группе автоматически. Чтобы изменить это, нужно откорректировать конфигурационный файл.

Имейте в виду:

  • Эти настройки сработают только в случае, если экземпляр MySQL запущен. Если нода была исключена из группы из-за сбоя или ошибки, но экземпляр MySQL ещё запущен, нода не сможет автоматически подключиться к группе.
  • При первом запуске группы эти параметры могут вызвать ошибки. Если на момент запуска не существует группы, к которой может подключиться нода, MySQL будет пытаться обнаружить такие ноды, а этот процесс займёт немало времени.

Чтобы ноды автоматически подключались к группе после перезапуска, откройте файл:

sudo nano /etc/mysql/my.cnf

Найдите loose-group_replication_start_on_boot и установите значение ON.

[mysqld] . . .
loose-group_replication_start_on_boot = ON
. . .

Сохраните и закройте файл.

Заключение

Теперь вы умеете настраивать группы репликации MySQL в Ubuntu 16.04.

Группы репликации MySQL – удобный и гибкий метод обеспечения избыточности данных.

Tags: ,

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