Инструмент управления тиражированием с несколькими основными репликами (MultiMaster replication Manager) использует для репликации традиционный механизм “master-slave”. Он работает на основе набора серверов MySQL с, как минимум, двумя основными репликами с набором подчиненных реплик, а также с выделенным узлом мониторинга. Поверх этого набора узлов настраивается пул IP-адресов, который MMM может динамически перемещать от узла к узлу, в зависимости от их доступности. У нас есть два типа этих адресов:
— “Записывающий”: клиент может записывать в базу данных, подключаясь к этому IP-адресу (во всем кластере может быть только один адрес записывающего узла).
— “Читающий ”: клиент может читать в базе данных, подключаясь к этому IP-адресу (может быть несколько читающих узлов для масштабирования чтения).
Узел мониторинга проверяет доступность серверов MySQL и включает перенос “записывающих” и “читающих” IP-адресов в случае отказа сервера. Набор проверок относительно прост: он включает проверку доступности сети, проверку присутствия mysqld на узле, присутствия ветки репликации и размера журнала репликации. Распределение нагрузки по чтению между “читающими” IP-адресами выполняется пользователем (его можно сделать с помощью HAProxy, Keepalived или циклического перебора DNS и т.п.).
MMM использует традиционную асинхронную репликацию. Это значит, что всегда есть шанс, что в момент сбоя мастера реплики отстают от мастера.
В данной схеме будет использоваться 4 сервера
1 2 3 4 |
Active master(centos641vz110) c реальным IP-адресом 192.168.1.110 Passive master(centos641vz111) с реальным IP-адресом 192.168.1.111 Slave-сервер(centos642) с реальным IP-адресом 192.168.1.39 Монитор-сервер(centos641) с реальным IP-адресом 192.168.1.38 |
VIP(virtual IP) на запись 192.168.1.128 будет расшарен/плавающий между двумя master-серверами(в конкретный момент времени только один –АКТИВНЫЙ мастер будет иметь на себе этот адрес. При выходе из строя активного мастера этот адрес будет автоматически перемещаться на пассивный мастер, тем самым делая его активным)
Именно этот VIP-адрес и прописывается в настройках подключения к серверу баз данных в приложениях
VIP адреса на чтение для
1 2 3 |
active master 192.168.1.129 (db1) passive master 192.168.130 (db2) slave-сервер 192.168.1.131 (db3) |
Перед настройкой mysql-mmm необходимо соответственно настроить master-master-репликацию между двумя серверами, а также master-slave репликацию между active master и slave-сервером.
Принцип настройки master-master репликации изложен здесь
Принцип настройки master-slave репликации изложен здесь
Ниже я кратко приведу набор команд для настройки master(192.168.1.110) и slave(192.168.1.39) репликации
1 |
# mysql -u root -p123456789 |
1 |
mysql> grant replication slave on *.* to 'replicationuser'@'192.168.1.39' identified by 'replicationpassword'; |
1 |
mysql> flush tables with read lock; |
С другой консоли!!!
1 |
# mysqldump -u root -p123456789 --all-databases --events --master-data > all.sql |
В старой консоли
1 |
mysql> unlock tables; |
1 |
# scp /root/all.sql 192.168.1.39:/root/ |
на slave-севрере
1 |
# nano /etc/my.cnf |
1 |
server-id = 39 |
1 |
# /etc/init.d/mysqld restart |
1 |
# mysql -u root -p123456789 < /root/all.sql |
1 2 3 4 5 6 |
MariaDB [(none)]> change master to -> master_host='192.168.1.110', -> master_user='replicauser', -> master_password='replicapassword', -> master_log_file='centos641vz110-bin.000009', -> master_log_pos=29444; |
1 |
MariaDB [(none)]> slave start; |
1 |
MariaDB [(none)]> show slave status\G |
Подготовка к настройки mysql-mmm
Создаем MySQL- пользователей mmm_monitor, mmm_agent, replicauser
Например,выполняем команды на active master(автоматически все реплицируется на passive master и slave-сервер)
mmm_monitor с доступом с монитор-сервера(192.168.1.38)
1 |
mysql> grant replication client on *.* to 'mmm_monitor'@'192.168.1.38' identified by 'monitor_password'; |
Пользователя mmm_agent с доступом со всех серверов баз данных(агентов)(192.168.1.110, 192.168.1.111, 192.168.1.39)
1 |
mysql> grant super,replication client,process on *.* to 'mmm_agent'@'192.168.1.110' identified by 'agent_password'; |
1 |
mysql> grant super,replication client,process on *.* to 'mmm_agent'@'192.168.1.111' identified by 'agent_password'; |
1 |
mysql> grant super,replication client,process on *.* to 'mmm_agent'@'192.168.1.39' identified by 'agent_password'; |
Пользователя replicauser с доступом со всех серверов баз данных(агентов)(192.168.1.110, 192.168.1.111, 192.168.1.39)
Этого же пользователя можно использовать и при настройке репликации master/master и master/slave
1 |
mysql> grant replication slave on *.* to 'replicauser'@'192.168.1.110' identified by 'replicapassword'; |
1 |
mysql> grant replication slave on *.* to 'replicauser'@'192.168.1.111' identified by 'replicapassword'; |
1 |
mysql> grant replication slave on *.* to 'replicauser'@'192.168.1.39' identified by 'replicapassword'; |
Итого на выходе имеем
1 |
mysql> select user,host,password from mysql.user where user='mmm_monitor'; |
1 2 3 4 5 6 |
+-------------+--------------+-------------------------------------------+ | user | host | password | +-------------+--------------+-------------------------------------------+ | mmm_monitor | 192.168.1.38 | *C1F414D9BAF378B656A849B31F9F8AF3125F558B | +-------------+--------------+-------------------------------------------+ 1 row in set (0.00 sec) |
1 |
mysql> select user,host,password from mysql.user where user='mmm_agent'; |
1 2 3 4 5 6 7 8 |
+-----------+---------------+-------------------------------------------+ | user | host | password | +-----------+---------------+-------------------------------------------+ | mmm_agent | 192.168.1.110 | *9404D503D0FAE1825CFEF873D0E7A38A26BBAB0F | | mmm_agent | 192.168.1.111 | *9404D503D0FAE1825CFEF873D0E7A38A26BBAB0F | | mmm_agent | 192.168.1.39 | *9404D503D0FAE1825CFEF873D0E7A38A26BBAB0F | +-----------+---------------+-------------------------------------------+ 3 rows in set (0.00 sec) |
1 |
mysql> select user,host,password from mysql.user where user='replicauser'; |
1 2 3 4 5 6 7 8 |
+-------------+---------------+-------------------------------------------+ | user | host | password | +-------------+---------------+-------------------------------------------+ | replicauser | 192.168.1.111 | *77384625DF0DB7C06BAC97CD42574994A8F2A96A | | replicauser | 192.168.1.110 | *77384625DF0DB7C06BAC97CD42574994A8F2A96A | | replicauser | 192.168.1.39 | *77384625DF0DB7C06BAC97CD42574994A8F2A96A | +-------------+---------------+-------------------------------------------+ 3 rows in set (0.00 sec) |
Установка mysql-mmm
1 |
# yum search mmm |
1 2 3 4 |
mysql-mmm-agent.noarch : MMM Database Server Agent Daemon and Libraries mysql-mmm-monitor.noarch : MMM Monitor Server Daemon and Libraries mysql-mmm-tools.noarch : MMM Control Scripts and Libraries mysql-mmm.noarch : Multi-Master Replication Manager for MySQL |
Я устанавливаю на всех серверах (монитор-сервер и 3 сервера баз данных(2 мастера активный/пассивный и 1 slave) все пакеты mysql-mmm
Хотя для монитор-сервера достаточно mysql-mmm и mysql-mmm-monitor, а для агентов(2 мастера и слейв) mysql-mmm-agent
1 |
# yum install mysql-mmm* |
Настройка mysql-mmm
1.Создаем на монитор-сервере общий для всех файл,предварительно сохранив его резервную копию
1 |
# cp /etc/mysql-mmm/mmm_common.conf /etc/mysql-mmm/mmm_common.conf~ |
1 |
# nano /etc/mysql-mmm/mmm_common.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
active_master_role writer <host default> cluster_interface eth0 pid_path /var/run/mysql-mmm/mmm_agentd.pid bin_path /usr/libexec/mysql-mmm/ replication_user replicauser replication_password replicapassword agent_user mmm_agent agent_password agent_password </host> <host db1> ip 192.168.1.110 mode master peer db2 </host> <host db2> ip 192.168.1.111 mode master peer db1 </host> <host db3> ip 192.168.1.39 mode slave </host> <role writer> hosts db1, db2 ips 192.168.1.128 mode exclusive </role> <role reader> hosts db1, db2, db3 ips 192.168.1.129, 192.168.1.130, 192.168.1.131 mode balanced </role> |
Копируем конфиг на все сервера
1 |
# scp /etc/mysql-mmm/mmm_common.conf 192.168.1.110:/etc/mysql-mmm/ |
1 |
# scp /etc/mysql-mmm/mmm_common.conf 192.168.1.111:/etc/mysql-mmm/ |
1 |
# scp /etc/mysql-mmm/mmm_common.conf 192.168.1.39:/etc/mysql-mmm/ |
2.На серверах баз данных настраиваем файл mmm_agent.conf ,предварительно сохранив его резервную копию
1 |
# cp /etc/mysql-mmm/mmm_agent.conf /etc/mysql-mmm/mmm_agent.conf~ |
110-сервер
1 |
# nano /etc/mysql-mmm/mmm_agent.conf |
1 2 |
include mmm_common.conf this db1 |
111-сервер
1 |
# nano /etc/mysql-mmm/mmm_agent.conf |
1 2 |
include mmm_common.conf this db2 |
39-сервер
1 |
# nano /etc/mysql-mmm/mmm_agent.conf |
1 2 |
include mmm_common.conf this db3 |
3.На монитор-сервере настраиваем файл mmm_mon.conf, предварительно сделав его резервную копию
1 |
# cp /etc/mysql-mmm/mmm_mon.conf /etc/mysql-mmm/mmm_mon.conf~ |
1 |
# nano /etc/mysql-mmm/mmm_mon.conf |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
include mmm_common.conf <monitor> ip 127.0.0.1 pid_path /var/run/mysql-mmm/mmm_mond.pid bin_path /usr/libexec/mysql-mmm status_path /var/lib/mysql-mmm/mmm_mond.status ping_ips 192.168.1.1 auto_set_online 60 </monitor> <host default> monitor_user mmm_monitor monitor_password monitor_password </host> debug 0 |
ping_ips — здесь указаны IP-адреса,которые будет проверять(пинговать) монитор-сервер для определния в порядке ли сетевое соединение монитор-сервера.
Я использую здесь адрес шлюза
4.Запускаем агента(mysql-mmm-agent) на всех серверах баз данных
Например,на активном мастере
1 |
# /etc/init.d/mysql-mmm-agent start |
1 |
# netstat -nlpt | grep mmm |
1 |
tcp 0 0 192.168.1.110:9989 0.0.0.0:* LISTEN 1877/mmm_agentd |
1 |
# ps ax | grep -v grep | grep mmm |
1 2 |
1875 ? S 0:00 mmm_agentd 1877 ? S 0:00 mmm_agentd |
на 111-сервере
1 |
# /etc/init.d/mysql-mmm-agent start |
на 39-сервере
1 |
# /etc/init.d/mysql-mmm-agent start |
5.На монитор-сервере запускаем mysql-mmm-monitor
1 |
# /etc/init.d/mysql-mmm-monitor start |
1 |
# ps ax | grep mmm | grep -v grep |
1 2 3 4 5 6 7 8 9 10 11 |
24911 ? S 0:00 mmm_agentd 24913 ? S 0:00 mmm_agentd 25307 ? S 0:00 mmm_agentd 25309 ? S 0:00 mmm_agentd 25460 ? S 0:00 mmm_mond 25461 ? Sl 0:00 mmm_mond 25491 ? S 0:00 perl /usr/libexec/mysql-mmm/monitor/checker ping_ip 25495 ? S 0:00 perl /usr/libexec/mysql-mmm/monitor/checker mysql 25496 ? S 0:00 perl /usr/libexec/mysql-mmm/monitor/checker ping 25498 ? S 0:00 perl /usr/libexec/mysql-mmm/monitor/checker rep_backlog 25500 ? S 0:00 perl /usr/libexec/mysql-mmm/monitor/checker rep_threads |
Добавление в автозагрузку mysql-mmm-monitor на монитор-сервере
1 |
# chkconfig --level 2345 mysql-mmm-monitor on |
Добавление в автозагрузку mysql-mmm-agent на севрерах баз данных
1 |
# chkconfig --level 2345 mysql-mmm-agent on |
Проверяем состояние mysql-кластера
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130), writer(192.168.1.128) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.131) |
На самом деле после первой проверки кластера все сервера будут находится в статусе AWAITING_RECOVERY, а не в статусе ONLINE
Я использую опцию auto_set_online 60 в файле /etc/mysql-mmm/mmm_mon.conf, что позволяет автоматически переводить севрер из состояния AWAITING_RECOVERY в состояние ONLINE по истечению 60 секунд при условии,что все четыре проверки с монитора(ping,mysql,rep_threads,rep_backlog) успешны
Работа с mysql-mmm
Просмотр всех проверок всех севреров баз данных(агентов)
1 |
# mmm_control checks |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
db2 ping [last change: 2013/12/25 22:52:00] OK db2 mysql [last change: 2013/12/25 22:52:00] OK db2 rep_threads [last change: 2013/12/25 22:52:00] OK db2 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null db3 ping [last change: 2013/12/25 22:52:00] OK db3 mysql [last change: 2013/12/25 22:52:00] OK db3 rep_threads [last change: 2013/12/25 22:52:00] OK db3 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null db1 ping [last change: 2013/12/25 22:52:00] OK db1 mysql [last change: 2013/12/25 22:52:00] OK db1 rep_threads [last change: 2013/12/25 22:52:00] OK db1 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null |
Просмотр всех проверок конкретного сервера(агента) баз данных(например,db1)
1 |
# mmm_control checks db1 |
1 2 3 4 |
db1 ping [last change: 2013/12/25 22:52:00] OK db1 mysql [last change: 2013/12/25 22:52:00] OK db1 rep_threads [last change: 2013/12/25 22:52:00] OK db1 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null |
Просмотр конкретной проверки конкретного сервера(агента)
1 |
# mmm_control checks db1 rep_backlog |
1 |
db1 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null |
Просмотр конкретной проверки(например,rep_backlog для всех серверов баз-данных(агентов)
1 |
# mmm_control checks all rep_backlog |
1 2 3 |
db2 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null db3 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null db1 rep_backlog [last change: 2013/12/25 22:52:00] OK: Backlog is null |
Ручной вывод сервера(агента) с кластера(например, на обслуживание)
Если это passive master или slave, тогда достаточно одной команды(например,для db2)
1 |
# mmm_control set_offline db2 |
1 |
OK: State of 'db2' changed to ADMIN_OFFLINE. Now you can wait some time and check all roles! |
Проверяем
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130), writer(192.168.1.128) db2(192.168.1.111) master/ADMIN_OFFLINE. Roles: db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.129), reader(192.168.1.131) |
Ручной ввод cервера в кластер.
1 |
# mmm_control set_online db2 |
1 |
OK: State of 'db2' changed to ONLINE. Now you can wait some time and check its new roles! |
Проверяем
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130), writer(192.168.1.128) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.131) |
Если из mysql-кластера необходимо вывести active master,тогда сначала переводим роль writer к passive master(который после такого операции становится active master), а потом выводим бывший active master с кластера
1 |
# mmm_control move_role writer db2 |
1 |
OK: Role 'writer' has been moved from 'db1' to 'db2'. Now you can wait some time and check new roles info! |
Проверяем
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129), writer(192.168.1.128) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.131) |
1 |
# mmm_control set_offline db1 |
1 |
OK: State of 'db1' changed to ADMIN_OFFLINE. Now you can wait some time and check all roles! |
Проверяем
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ADMIN_OFFLINE. Roles: db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129), writer(192.168.1.128) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.130), reader(192.168.1.131) |
Монитор-сервер проверяет сервера баз данных(агентов) по ping-проверке(checker ping), проверке mysql(checker mysql) ,на предмет остановки/разлома репликация(checker rep_threads ),отставания репликации превышает порог (checker rep_backlog)( по умолчанию устанавливается в 60 секунд – за это отвечает параметр max_backlog в секции .Если его нужно увеличить, например, до 5 минут, тогда на мониторе в /etc/mysql-mmm/mmm_mon.conf
добавляем и перезапускаем mysql-mmm-monitor
1 |
# nano /etc/mysql-mmm/mmm_mon.conf |
1 2 3 |
<check rep_backlog> max_backlog 300 </check> |
1 |
# /etc/init.d/mysql-mmm-monitor restart |
Если какой-либо севрер баз данных(агент) не будет доступен с монитор-сервера по одной из вышеуказанных проверок, то этот сервер(агент) будет выведен монитором из кластера с соответствующим статусом в mmm_control show
Например slave-сервер(db3-192.168.1.39) имеет адрес для чтения 192.168.1.131
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129), writer(192.168.1.128) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.131) |
1 |
# ip addr show | grep 131 |
1 |
inet 192.168.1.131/32 scope global eth0 |
Например,заблокируем через iptables доступ к 3306 tcp-порту на сервере 39
1 |
# iptables -I INPUT -p tcp --dport 3306 -j DROP |
После этого кластер выглядит так
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130), reader(192.168.1.131) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129), writer(192.168.1.128) db3(192.168.1.39) slave/HARD_OFFLINE. Roles: |
Адрес на чтение для db3 был перевед на на другой сервер(на db1)
1 2 |
# ip addr show | grep 131 # |
Проверка slave-сервера db3
1 |
# mmm_control checks db3 |
1 2 3 4 |
db3 ping [last change: 2013/12/25 23:46:32] OK db3 mysql [last change: 2013/12/25 23:59:24] ERROR: Connect error (host = 192.168.1.39:3306, user = mmm_monitor)! Can't connect to MySQL server on '192.168.1.39' (4) db3 rep_threads [last change: 2013/12/25 23:46:32] OK db3 rep_backlog [last change: 2013/12/25 23:46:32] OK: Backlog is null |
После удаления запрещающего подключения к порту 3306 правила из iptables
я остановил репликацию на db3
Проверка с монитор-сервера выглядит так
1 |
# mmm_control checks db3 |
1 2 3 4 |
db3 ping [last change: 2013/12/25 23:46:32] OK db3 mysql [last change: 2013/12/26 00:05:27] OK db3 rep_threads [last change: 2013/12/26 00:05:34] ERROR: Replication is broken db3 rep_backlog [last change: 2013/12/25 23:46:32] OK: Backlog is null |
Состояние кластера
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130), reader(192.168.1.131) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129), writer(192.168.1.128) db3(192.168.1.39) slave/REPLICATION_FAIL. Roles: |
Логи на мониторе смотрим в файле
1 |
# tail -f /var/log/mysql-mmm/mmm_mond.log |
После смены active master все slave-севрвра будут автоматически переведены на новый active master
Например,
до смены мастера
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130), writer(192.168.1.128) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.131) |
Slave-сервер реплицируется с 192.168.1.110
1 |
# mysql -u root -p123456789 -e "show slave status\G" | grep Master_Log_File |
1 2 |
Master_Log_File: centos641vz110-bin.000010 Relay_Master_Log_File: centos641vz110-bin.000010 |
после смены active master
1 |
# mmm_control move_role writer db2 |
1 |
OK: Role 'writer' has been moved from 'db1' to 'db2'. Now you can wait some time and check new roles info! |
1 |
# mmm_control show |
1 2 3 |
db1(192.168.1.110) master/ONLINE. Roles: reader(192.168.1.130) db2(192.168.1.111) master/ONLINE. Roles: reader(192.168.1.129), writer(192.168.1.128) db3(192.168.1.39) slave/ONLINE. Roles: reader(192.168.1.131) |
Slave-сервер реплицируется с новым active master 192.168.1.111
1 |
# mysql -u root -p123456789 -e "show slave status\G" | grep Master_Log_File |
1 2 |
Master_Log_File: centos641vz111-bin.000016 Relay_Master_Log_File: centos641vz111-bin.000016 |
в логах slave-сервера
1 2 3 4 5 6 7 |
131226 0:58:48 [Note] Error reading relay log event: slave SQL thread was killed 131226 0:58:48 [ERROR] Error reading packet from server: Lost connection to MySQL server during query ( server_errno=2013) 131226 0:58:48 [Note] Slave I/O thread killed while reading event 131226 0:58:48 [Note] Slave I/O thread exiting, read up to log 'centos641vz110-bin.000010', position 65137 131226 0:58:48 [Note] 'CHANGE MASTER TO executed'. Previous state master_host='192.168.1.110', master_port='3306', master_log_file='centos641vz110-bin.000010', master_log_pos='65137'. New state master_host='192.168.1.111', master_port='3306', master_log_file='centos641vz111-bin.000016', master_log_pos='62055'. 131226 0:58:48 [Note] Slave SQL thread initialized, starting replication in log 'centos641vz111-bin.000016' at position 62055, relay log './mysqld-relay-bin.000001' position: 4 131226 0:58:48 [Note] Slave I/O thread: connected to master 'replicauser@192.168.1.111:3306',replication started in log 'centos641vz111-bin.000016' at position 62055 |
Источники:
2.http://habrahabr.ru/company/mirantis_openstack/blog/177357/