Multi-master репликация в MySQL позволяет нескольким серверам одновременно выступать в роли источников записей, что открывает путь к более гибкой и отказоустойчивой архитектуре. Когда данные должны быть доступны для записи на нескольких узлах, а изменения распространяются автоматически, GTID упрощает отслеживание транзакций, а semi-synchronous режим добавляет слой гарантий доставки. Такой подход превращает обычную репликацию в инструмент, который держит данные в синхронном состоянии даже при активной работе с двух сторон.
Подготовка серверов и проверка требований
Перед началом настройки убедитесь, что на всех серверах установлена одинаковая версия MySQL 8.0 или выше. Разные версии могут привести к неожиданным конфликтам в формате бинарных логов. Предположим два сервера: mysql1 с адресом 192.168.1.10 и mysql2 с адресом 192.168.1.20. Сначала обновите систему и установите MySQL, если его ещё нет.
sudo apt update && sudo apt upgrade -y
sudo apt install mysql-server -y
Проверьте текущую версию на каждом сервере.
mysql --version
Убедитесь, что серверы могут связаться друг с другом по сети и порту 3306 открыт. Это базовая проверка, которая предотвращает множество проблем на старте. Многие администраторы пропускают её и потом тратят часы на отладку соединений.
Базовая конфигурация в файле my.cnf
Конфигурационный файл /etc/mysql/my.cnf или /etc/mysql/mysql.conf.d/mysqld.cnf задаёт поведение репликации. На mysql1 добавьте следующие параметры в секцию [mysqld].
[mysqld]
server-id = 1
log-bin = mysql-bin
gtid-mode = ON
enforce-gtid-consistency = ON
log-replica-updates = ON
binlog-format = ROW
auto-increment-increment = 2
auto-increment-offset = 1
На mysql2 параметры будут почти идентичными, но с другими server-id и offset.
[mysqld]
server-id = 2
log-bin = mysql-bin
gtid-mode = ON
enforce-gtid-consistency = ON
log-replica-updates = ON
binlog-format = ROW
auto-increment-increment = 2
auto-increment-offset = 2
GTID делает каждую транзакцию уникально идентифицируемой, независимо от сервера-источника. Параметр log-replica-updates обязателен для multi-master, потому что изменения, полученные от другого узла, тоже должны попадать в бинарный лог. Auto-increment настройки предотвращают конфликты при вставке записей одновременно на двух серверах. После правок перезапустите MySQL на обоих узлах.
sudo systemctl restart mysql
Такая подготовка создаёт фундамент, на котором строится вся репликация.
Создание пользователя для репликации
На каждом сервере создайте специального пользователя repl, который будет использоваться для подключения в обоих направлениях. Выполните на mysql1.
CREATE USER 'repl'@'%' IDENTIFIED BY 'strong_password';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
Повторите точно такую же команду на mysql2. Этот пользователь получает минимальные права, достаточные только для репликации, что соответствует принципу наименьших привилегий. Пароль должен быть сложным, чтобы исключить несанкционированный доступ.
Настройка bidirectional репликации с GTID
Теперь настройте каждый сервер как реплику другого. Сначала на mysql1 укажите mysql2 как источник.
STOP REPLICA;
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.1.20',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'strong_password',
SOURCE_AUTO_POSITION = 1;
START REPLICA;
Аналогично на mysql2 настройте mysql1 как источник.
STOP REPLICA;
CHANGE REPLICATION SOURCE TO
SOURCE_HOST = '192.168.1.10',
SOURCE_USER = 'repl',
SOURCE_PASSWORD = 'strong_password',
SOURCE_AUTO_POSITION = 1;
START REPLICA;
Проверьте статус репликации на каждом сервере.
SHOW REPLICA STATUS\G
Ищите строки Replica_IO_Running: Yes и Replica_SQL_Running: Yes. GTID автоматически обрабатывает позицию, поэтому нет нужды вручную указывать binlog-файл и позицию. Это сильно упрощает failover и восстановление после сбоя.
Включение semi-synchronous режима
Semi-synchronous добавляет гарантию, что транзакция не считается завершённой, пока хотя бы один узел не подтвердит получение. Сначала установите плагины на обоих серверах, потому что каждый работает и источником, и репликой.
На mysql1 и mysql2 выполните.
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';
Затем включите режим на каждом сервере.
SET GLOBAL rpl_semi_sync_source_enabled = 1;
SET GLOBAL rpl_semi_sync_replica_enabled = 1;
SET GLOBAL rpl_semi_sync_source_timeout = 10000;
Чтобы настройки сохранились после перезапуска, добавьте их в my.cnf.
rpl_semi_sync_source_enabled = 1
rpl_semi_sync_replica_enabled = 1
rpl_semi_sync_source_timeout = 10000
Перезапустите репликацию.
STOP REPLICA;
START REPLICA;
Теперь каждая запись ждёт подтверждения от второго сервера перед возвратом клиенту. Это заметно снижает риск потери данных при внезапном отключении одного из узлов, хотя и добавляет небольшую задержку.
Практическая проверка и мониторинг
Создайте тестовую таблицу на mysql1 и вставьте запись.
CREATE DATABASE testdb;
USE testdb;
CREATE TABLE test (id INT AUTO_INCREMENT PRIMARY KEY, value VARCHAR(100));
INSERT INTO test (value) VALUES ('Тест из mysql1');
Проверьте на mysql2, что запись появилась.
USE testdb;
SELECT * FROM test;
Сделайте обратную проверку с mysql2. Мониторьте статус semi-sync.
SHOW GLOBAL STATUS LIKE 'Rpl_semi_sync%';
Rpl_semi_sync_source_status: ON подтверждает, что режим активен. Регулярно смотрите на эти метрики, чтобы вовремя заметить проблемы с задержками или отключениями.
Вот ключевые параметры, которые чаще всего настраивают вместе в такой схеме.
- gtid-mode и enforce-gtid-consistency для надёжного отслеживания транзакций
- log-replica-updates для циркуляции изменений в кольце
- rpl_semi_sync_source_enabled и rpl_semi_sync_replica_enabled для гарантий доставки
- auto-increment-increment и auto-increment-offset для избежания конфликтов идентификаторов
Правильная комбинация этих настроек делает систему устойчивой к сбоям и удобной в повседневной работе.
Возможные проблемы и рекомендации по эксплуатации
В multi-master репликации всегда существует риск конфликтов, если оба сервера одновременно меняют одни и те же строки. GTID помогает быстро выявить расхождения, а semi-sync снижает вероятность потери данных. Если конфликт всё же возник, MySQL остановит SQL-поток репликации и покажет ошибку. В таком случае вручную разрешите конфликт и продолжите.
Рекомендуется использовать ProxySQL или MaxScale перед серверами, чтобы распределять нагрузку и направлять записи только на один узел в критических случаях. Регулярно делайте бэкапы с помощью mysqldump или Percona XtraBackup. Мониторьте дисковое пространство под бинарными логами, потому что в multi-master они растут быстрее.
Экспериментируйте с таймаутом semi-sync под вашу сеть. В локальной среде 10 секунд обычно хватает, а при большом latency можно увеличить. Со временем такая конфигурация становится естественной частью инфраструктуры, где данные доступны для записи везде, но остаются согласованными.
Multi-master с GTID и semi-sync даёт баланс между производительностью и надёжностью. Когда оба узла активно используются, а изменения распространяются автоматически, вся система работает как единое целое. Настройка занимает не больше часа, если следовать шагам последовательно, но приносит годы спокойной эксплуатации. Главное - держать конфигурацию симметричной и постоянно наблюдать за статусом. Тогда multi-master перестаёт быть сложным экспериментом и превращается в надёжный инструмент для реальных задач.