Настройка многоканальной репликации в 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';