0

MySQL master — master репликация

Краткая заметка с основными шагами для организации master-master репликации MySQL

Условно имеется два узла node01 и node02. Нужно организовать между ними master-master репликацию. Такое решение будет работать в режиме active-passive (Запись будет происходить только на один узел, а второй будет находиться в режиме горячей замены).

Подготовка

Итак минимальные изменения на node01 в my.cnf:

# uniq id
server-id               = 1
# path to binlog
log_bin                 = /var/log/mysql/mysql-bin.log
# listen on all interfaces
# bind-address            = 127.0.0.1

Для удачного запуска создаю директорию для binlog:
# mkdir -p /var/log/mysql && chown -R mysql:mysql /var/log/mysql
Создаю пользователя для репликации:
# mysql
mysql> create user 'repl'@'node02' identify by 'p@ssword';
mysql> grant replication slave on *.* to 'repl'@'%';
После этого можно перезапускать mysqld.
В консоли можно посмотреть статус следующей командой:
mysql> show master status;

На узле node02 делаю в my.cnf вношу изменения по аналогии:

# uniq id
server-id               = 2
# path to binlog
log_bin                 = /var/log/mysql/mysql-bin.log
# listen on all interfaces
# bind-address            = 127.0.0.1

Так же создаю директорию и пользователя в mysql
mysql> create user 'repl'@'node01' identify by 'p@ssword';
mysql> grant replication slave on *.* to 'repl'@'%';
Перезапускаю сервер.

Дальше начинается самое интересное.

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

Для запуска механизма репликации необходимо сначала уточнить позицию, с которой начинать репликацию.
Для этого на node1 (с нее node2 будет брать данные) выполняю:
mysql> show master status;
В результате имею имя файла бинарного лога и текущую позицию:

+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000058 |     1203 |              |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

для начала репликации на node2 выполняю:
mysql> slave stop;
mysql> CHANGE MASTER TO MASTER_HOST = 'node1',
> MASTER_USER = 'repl', MASTER_PASSWORD = 'p@ssword',
> MASTER_LOG_FILE = 'mysql-bin.000058',
> MASTER_LOG_POS = 1203;

start slave;
Теперь node2 будет применять изменения, которые произошли на node1. Если включен лог ошибок, то в нем будет соответсвующая запись.

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

Если одна из баз боевая и случайные изменения там абсолютно не нужны, поможет установка на другом узле (passive-master)
mysql> set global read_only=on;
Как понятно из названия, операции на изменение данных узел принимать не будет, следовательно в бинарном логе новые записи появлять не будут, а значит с этого узла нечего будет реплицировать.

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

Alexey Egorychev

FreeBSD and Linux sysadmin. Know many systems like mailsystems, DB, WWW stack. Automation with salt, ansible. Monitoring with nagios, zabbix.