Настройка MySQL Master/Master репликации на Linux
TL;DR
Краткое пошаговое руководство по настройке двунаправленной (master/master) репликации MySQL на двух серверах Linux: правьте конфигурацию, создайте пользователя для репликации, синхронизируйте позиции бинарных логов и проверьте состояние. Включены рекомендации по безопасности, отладке и контрольный список для администратора.
Предпосылки
Эта инструкция предполагает, что MySQL уже установлен на каждом сервере. При необходимости скачайте пакеты с https://www.mysql.org/downloads. Для MariaDB процесс похож, но некоторые параметры и команды могут отличаться — используйте руководство для MariaDB, если применимо.
Важно: всегда делайте резервные копии данных перед изменением настроек репликации.
Измените SELinux на permissive (если установлен)
На каждом сервере отредактируйте файл /etc/selinux/config и установите режим permissive.
Сервер A
[root@mysqla ~]# vi /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
Сервер B
[root@mysqlb ~]# vi /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
# enforcing - SELinux security policy is enforced.
# permissive - SELinux prints warnings instead of enforcing.
# disabled - No SELinux policy is loaded.
SELINUX=permissive
# SELINUXTYPE= can take one of these two values:
# targeted - Targeted processes are protected,
# mls - Multi Level Security protection.
SELINUXTYPE=targeted
Отключите firewalld и проверьте iptables на каждом сервере
Если в вашей сети используются брандмауэры, учтите это при открытии портов (обычно 3306). Для простоты примера мы останавливаем firewalld.
Сервер A
[root@mysqla ~]# systemctl stop firewalld
[root@mysqla ~]# systemctl disable firewalldПроверьте, что правил нет:
[root@mysqla ~]# iptables -LОжидаемый вывод:
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destinationСервер B
[root@mysqlb ~]# systemctl stop firewalld
[root@mysqlb ~]# systemctl disable firewalld[root@mysqlb ~]# iptables -LОжидаемый вывод аналогичен.
Примечание: в продакшене чаще открывают порт 3306 и ограничивают доступ по IP вместо полного отключения брандмауэра.
Правки /etc/my.cnf на обоих серверах
Добавьте в секцию [mysqld] следующие параметры. Замените name_of_database на имя вашей базы.
Сервер A
[root@mysqla ~]# vi /etc/my.cnf
server-id=1
log-bin="mysql-bin"
binlog-do-db=name_of_database
replicate-do-db=name_of_database
relay-log="mysql-relay-log"
auto-increment-offset = 1
Сервер B
[root@mysqlb ~]# vi /etc/my.cnf
server-id=2
log-bin="mysql-bin"
binlog-do-db=name_of_database
replicate-do-db=name_of_database
relay-log="mysql-relay-log"
auto-increment-offset = 2
Объяснение коротко: server-id уникален для каждого сервера; auto-increment-offset полезен при параллельных вставках, чтобы избежать конфликтов PK.
Перезапустите и включите демоны MySQL
Сервер A
[root@mysqla ~]# systemctl restart mysqld[root@mysqla ~]# systemctl enable mysqldСервер B
[root@mysqlb ~]# systemctl restart mysqld[root@mysqlb ~]# systemctl enable mysqldСоздайте пользователя репликации на каждом сервере
[root@mysqla ~]# mysql -u root -p
mysql> CREATE USER 'replicator'@'%' IDENTIFIED BY 'change_me';
mysql> GRANT REPLICATION SLAVE ON foo.* TO 'replicator'@'%'[root@mysqlb ~]# mysql -u root -p
mysql> CREATE USER 'replicator'@'%' IDENTIFIED BY 'change_me';
mysql> GRANT REPLICATION SLAVE ON foo.* TO 'replicator'@'%'Совет: вместо ‘%’ укажите конкретный IP сервера-реплики для безопасности.
Получите данные по бинарному логу для использования на другом сервере
На одном сервере получите статус мастера и запомните File и Position.
Сервер A
[root@mysqla ~]# mysql -u root -p
mysql> SHOW MASTER STATUS;
+------------------+----------+------------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+------------------+------------------+
| mysql-bin.000001 | 154 | name_of_database | |
+------------------+----------+------------------+------------------+
1 row in set (0.00 sec)Запишите File и Position.
На другом сервере примените эти значения как мастер и запустите slave.
Сервер B
[root@mysqlb ~]# mysql -u root -p
mysql> STOP SLAVE;
mysql> CHANGE MASTER TO MASTER_HOST = 'Server A IP Address or HOSTNAME',MASTER_USER = 'replicator', MASTER_PASSWORD = 'change_me', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 154;
mysql> START SLAVE;Повторите зеркально: получите SHOW MASTER STATUS на Server B и используйте эти значения на Server A:
Сервер B
[root@mysqlb ~]# mysql -u root -p mysql> SHOW MASTER STATUS;
+------------------+----------+------------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+------------------+------------------+
| mysql-bin.000001 | 154 | name_of_database | |
+------------------+----------+------------------+------------------+
1 row in set (0.00 sec)Сервер A
[root@mysqla ~]# mysql -u root -p
mysql> STOP SLAVE; CHANGE MASTER TO MASTER_HOST = 'Server B IP Address or HOSTNAME', MASTER_USER = 'replicator', MASTER_PASSWORD = 'passw0rd', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 154;
mysql> START SLAVE;Перезагрузите оба сервера
Сервер A
[root@mysqla ~]# systemctl rebootСервер B
[root@mysqlb ~]# systemctl rebootСоздайте базу данных на любом сервере и проверьте репликацию
На одном сервере создайте базу:
[root@mysqla ~]# mysql -u root -p
mysql> CREATE DATABASE foo;На другом сервере убедитесь, что база появилась:
[root@mysqlb ~]# mysql -u root -p
mysql> SHOW DATABASES;
+--------------------+
| Database |
+--------------------+
| information_schema |
| foo |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)Контроль и отладка
- Проверить статус реплики: в mysql выполнить SHOW SLAVE STATUS\G и убедиться, что Slave_IO_Running: Yes и Slave_SQL_Running: Yes.
- Логи ошибок MySQL смотрите в /var/log/mysqld.log или в системном журнале.
- Частые причины ошибок: сетевые проблемы, несовпадающие схемы БД, отсутствующие разрешения пользователя репликации или конфликтующие автоинкрменты.
Безопасность и рекомендации
- Не используйте ‘%’ для пользователя репликации в продакшене — указывайте IP адрес(а).
- Шифруйте трафик репликации (TLS) в публичных сетях.
- Ограничьте доступ к порту 3306 межсетевыми правилами и VPN.
- Регулярно проверяйте бинарные логи и место на диске (binlog может быстро занимать место).
Когда этот метод не подходит
- Если вам нужна согласованность multi-master для записей с часто конфликтующими ключами — рассмотрите решение на уровне приложений, Galera Cluster или MySQL Group Replication.
- Для большого количества серверов лучше использовать однонаправленную мастер-реплику с репликационным бэкендом.
Альтернативные подходы
- MySQL Group Replication / InnoDB Cluster — автоматическое разрешение конфликтов и автоматическое восстановление.
- Galera (Percona XtraDB Cluster) — синхронная репликация для высокой доступности.
- Асинхронная master/slave для аналитических слётов и резервирования.
Ментальные модели и heuristics
- Минимизируйте время окна, когда оба сервера принимают записи одновременно без координации — это источник конфликтов.
- Относитесь к бинарным логам как к журналу изменений: важно синхронизировать позиции.
- Всегда тестируйте восстановление из резервной копии и откат конфигурации репликации до промо/демо.
Роль-ориентированные чеклисты
Администратор ОС:
- Проверить доступность сети между серверами.
- Настроить SELinux и firewall.
DBA:
- Проверить уникальность server-id.
- Убедиться, что binlog включён.
- Создать пользователя репликации и проверить SHOW MASTER STATUS.
DevOps / Release Engineer:
- Планировать обслуживание при перезапуске mysqld.
- Мониторить диск и размер binlog.
Критерии приёмки
- SHOW SLAVE STATUS\G на обоих серверах показывает Slave_IO_Running: Yes и Slave_SQL_Running: Yes.
- Изменение в базе на одном сервере появляется на другом в пределах ожидаемого времени задержки.
- Отработан сценарий отката и документирован план восстановления.
Быстрый план действий при отказе (runbook)
- Проверить сетевые соединения (ping, telnet хост 3306).
- Проверить SHOW SLAVE STATUS\G — искать Last_IO_Error и Last_SQL_Error.
- Временно остановить записи на обоих серверах (read-only или переключение трафика).
- При необходимости выполнить CHANGE MASTER TO … RESET SLAVE и повторную настройку с известной позиции или из резервной копии.
Факт-бокс: бинарные логи — ключевой механизм репликации; имейте план ротации и мониторьте диск.
Источники
- https://www.howtoforge.com/mysql_database_replication
- https://www.digitalocean.com/community/tutorials/how-to-set-up-mysql-master-master-replication
- https://www.howtoforge.com/mysql_master_master_replication
- http://www.ryadel.com/en/mysql-master-master-replication-setup-in-5-easy-steps/
Краткое резюме
Двусторонняя репликация MySQL на двух серверах достигается с помощью настройки уникального server-id, включения бинарных логов, создания пользователя репликации и синхронизации позиций бинарных логов. Тестируйте репликацию, ограничивайте доступ по сети и имейте план отката.
Похожие материалы
Несколько аккаунтов Skype: Multi Skype Launcher
Журнал для работы: повысить продуктивность
Персональные звуки уведомлений на Android
Скачивание шоу Hulu для офлайн‑просмотра
Microsoft Start: персонализированная новостная лента