Настройка многоканальной репликации в MySQL

Содержание

Введение

Имеется кластер Percona XtraDB Cluster, состоящий из двух узлов с Percona XtraDB Cluster Server (проще говоря - с серверами MySQL) и одного узла Percona XtraDB Cluster Galera Arbitrator (проще говоря - с абритром Galera). Кластер настроен в первую очередь для обеспечения высокой доступности сервиса - узлы кластера можно поочерёдно выводить из работы для их обслуживания без прерывания работы сервиса. Кроме того, при выходе из строя одного из серверов, сервис может продолжить работу в штатном режиме или восстановить работу в штатном режиме автоматически. В случае более сложных проблем остаётся возможность оперативно восстановить работу сервиса в ручном режиме, исключив из работы проблемный сервер.

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

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

Ручная замена источника

Для решения проблемы можно воспользоваться автопозиционированием, для включения которого необходимо настроить репликацию с автоматическим позиционированием по глобальному идентификатору транзакций GTID, например, в соответствии со статьёй Нишант Неупан. Как преобразовать обычную репликацию в репликацию GTID в MySQL. В таком случае перенастройка реплики на использование другого источника становится тривиальной задачей, для которой достаточно остановить репликацию, поменять имя сервера-источника, и запустить репликацию снова, например, следующим образом:

SLAVE STOP;
RESET SLAVE ALL;
CHANGE MASTER TO MASTER_HOST = '192.168.122.14',
                 MASTER_USER = 'repl',
                 MASTER_PASSWORD = '$ecretP4$$w0rd',
                 MASTER_AUTO_POSITION = 1;
SLAVE START;

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

Однако есть решение лучше - можно воспользоваться многоканальной репликацией, когда на сервере-реплике можно указать сразу несколько серверов-источников. В таком случае реплика будет принимать изменения со всех источников и применять транзакции с одинаковыми GTID только один раз, независимо от того, через сколько источников эта транзакция была получена.

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

STOP SLAVE;
SET GLOBAL master_info_repository = 'TABLE';
SET GLOBAL relay_log_info_repository = 'TABLE';
START SLAVE;

Теперь новые настройки можно прописать в файл конфигурации сервера, например, в /etc/mysql/percona-server.conf.d/mysqld.cnf:

master_info_repository = TABLE
relay_log_info_repository = TABLE

Следующим этапом можно удалить безымянный канал репликации и добавить несколько именованных каналов:

SLAVE STOP;
RESET SLAVE ALL;
CHANGE MASTER TO MASTER_HOST = '192.168.122.13',
                 MASTER_USER = 'repl',
                 MASTER_PASSWORD = '$ecretP4$$w0rd',
                 MASTER_AUTO_POSITION = 1
                 FOR CHANNEL 'pxc1';
CHANGE MASTER TO MASTER_HOST = '192.168.122.14',
                 MASTER_USER = 'repl',
                 MASTER_PASSWORD = '$ecretP4$$w0rd',
                 MASTER_AUTO_POSITION = 1
                 FOR CHANNEL 'pxc2';
SLAVE START;

Управление каналами репликации

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

STOP SLAVE FOR CHANNEL 'pxc1';

При необходимости удалить один из каналов, можно сначала остановить репликацию по этому каналу указанной выше командой, а затем удалить сам канал следующим образом:

RESET SLAVE ALL FOR CHANNEL 'pxc1';

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

Для добавления нового именованного канала предназначена уже указанная выше команда следующего вида:

CHANGE MASTER TO MASTER_HOST = '192.168.122.13',
                 MASTER_USER = 'repl',
                 MASTER_PASSWORD = '$ecretP4$$w0rd',
                 MASTER_AUTO_POSITION = 1
                 FOR CHANNEL 'pxc1';

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

START SLAVE FOR CHANNEL 'pxc1';