一、MMM 概述
1. 什么是 MMM
MMM(Master-Master replication manager for MySQL,MySQL 主主复制管理器)是一套支持双主故障切换和双主日常管理的脚本程序。MMM 使用 Perl 语言开发,主要从来监控和管理 MySQL Master-Master(双主)复制,虽然叫做双主复制,但是业务上同一时刻只允许一个主进行写入,另一台备选主上提供部分读服务,以加速在主主切换时备选主的预热,可以说 MMM 这套脚本程序一方面实现了故障切换的功能,另一方面其内部附加的工具也可以实现多个 Slave 的 read 负载均衡。
2. 应用场景
MMM 提供了自动和手动两种方式移除一组服务器中复制延迟较高的服务器的虚拟 ip,同时它还可以备份数据,实现两节点之间的数据同步等。由于 MMM 无法完全保证数据的一致性,所以 MMM 适用于对数据的一致性要求不是很高的,但是又想最大程度地保证业务可用性的场景。对于那些对数据的一致性要求很高的业务,非常不建议采用 MMM 这种高可用架构。
3. MMM 特点
- MMM 是一套灵活的脚本程序
- 基于 perl 语言实现
- 用来对 mysql replication 进行监控和故障迁移
- 管理 MySQL Master-Master 复制的配置
4. 关于 MMM 高可用架构的说明
mmm_mon:监控进程,负责所有的监控工作,决定和处理所有节点角色活动。此脚本需要在监管机上运行。
mmm_agent:运行在每个 MySQL 服务器上的代理进程,完成监控的探针工作和执行简单的远端服务设置。此脚本需要在被监管机上运行。
mmm_control:一个简单的脚本,提供管理 mmm_mond 进程的命令。
mysql-mmm 的监管端会提供多个虚拟 IP(VIP),包括一个可写 VIP,多个可读 VIP,通过监管的管理,这些 IP 会绑定在可用 MySQL 之上,当某一台 MySQL 宕机时,监管会将 VIP 迁移至其他 MySQL。
5. 用户及授权
在整个监管过程中,需要在 MySQL 中添加相关授权 yoghurt,以便让 MySQL 可以支持监理机的维护。授权的用户包括一个 mmm_monitor 用户和一个 mmm_agent 用户,如果想使用 MMM 的备份工具则还需要添加一个 mmm_tools 用户。
二、案例环境
1. 服务器配置
2. 服务器环境
systemctl stop firewalld && systemctl disable firewalld
setenforce 0
3 修改主机名
hostnamectl set-hostname master1
su
master1 master2 slave1 slave2 monitor
三、案例实施
1. 搭建 MySQL 多主多从架构
(1) master1、master2、slave1、slave2 节点安装 mysql
(2) 修改 master1 配置文件
[client]
port = 3306
default-character-set=utf8
socket=/usr/local/mysql/mysql.sock
[mysql]
port = 3306
default-character-set=utf8
socket=/usr/local/mysql/mysql.sock
auto-rehash
[mysqld]
user = mysql
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
port = 3306
character-set-server=utf8
pid-file = /usr/local/mysql/mysqld.pid
socket=/usr/local/mysql/mysql.sock
server-id = 1
log-error=/usr/local/mysql/data/mysql_error.log
general_log=ON
general_log_file=/usr/local/mysql/data/mysql_general.log
slow_query_log=ON
slow_query_log_file=mysql_slow_query.log
long_query_time=5
binlog-ignore-db=mysql,information_schema
log_bin=mysql_bin
log_slave_updates=true
sync_binlog=1
innodb_flush_log_at_trx_commit=1
auto_increment_increment=2
auto_increment_offset=1
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_AUTO_VALUE_ON_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,PIPES_AS_CONCAT,ANSI_QUOTES
重启 mysqld
systemctl restart mysqld
参数说明
...... server-id = 1 #每台 Mysql 主机的 server-id 不能相同 log-error=/usr/local/mysql/data/mysql_error.log #错误日志 general_log=ON #通用查询日志 general_log_file=/usr/local/mysql/data/mysql_general.log slow_query_log=ON #慢查询日志 slow_query_log_file=mysql_slow_query.log long_query_time=5 binlog-ignore-db=mysql,information_schema #不需要同步的库名 log_bin=mysql_bin #开启二进制日志用于主从数据复制 log_slave_updates=true #允许slave从master复制数据时可以写入到自己的二进制日志 sync_binlog=1 #"双1设置",MySQL 在每写一次二进制日志时都会同步到磁盘中去 innodb_flush_log_at_trx_commit=1 #"双1设置",每次事务提交时MySQL都会把缓存的数据写入日志文件,并且刷到磁盘中去 auto_increment_increment=2 #自增字段一次递增多少 auto_increment_offset=1 #自增字段的起始值
(3) 修改其他三台 mysql 并重启服务
把配置文件复制到其他 3 台数据库服务器并重启 mysql 服务器
注意:配置文件中的 server-id 不可相同,需要修改
(4) 配置主主复制,两台主服务器相互复制
① 在两台主服务器上都执行授予从的权限,从服务器上不需要执行
master1 服务器(192.168.10.20
mysql> grant replication slave on *.* to 'replication'@'192.168.10.%' identified by '123456';
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+--------------------------+-----------------
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Se
+------------------+----------+--------------+--------------------------+-----------------
| mysql_bin.000001 | 1023 | | mysql,information_schema |
+------------------+----------+--------------+--------------------------+-----------------
1 row in set (0.00 sec)
master2 服务器(192.168.10.30)
mysql> grant replication slave on *.* to 'replication'@'192.168.10.%' identified by '123456';
mysql> flush privileges;
mysql> show master status;
+------------------+----------+--------------+--------------------------+-----------------
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Se
+------------------+----------+--------------+--------------------------+-----------------
| mysql_bin.000001 | 1023 | | mysql,information_schema |
+------------------+----------+--------------+--------------------------+-----------------
1 row in set (0.00 sec)
② 在 master1 上配置同步
192.168.10.20
change master to master_host='192.168.10.30',master_user='replication',master_password='123456',master_log_file='mysql_bin.000001',master_log_pos=1023; start slave; show slave status\G; #查看 IO 和 SQL 线程是不是 YES,位置偏移量对不对
③ 在 master2 上配置同步
192.168.10.30
change master to master_host='192.168.10.20',master_user='replication',master_password='123456',master_log_file='mysql_bin.000001',master_log_pos=1023;
start slave;
show slave status\G;
#查看 IO 和 SQL 线程是不是 YES,位置偏移量对不对
(5) 配置主从复制,在两台从服务器上做
① slave1 服务器
192.168.10.40
change master to master_host='192.168.10.20',master_user='replication',master_password='123456',master_log_file='mysql_bin.000001',master_log_pos=1023;
start slave;
show slave status\G;
② slave2 服务器
192.168.10.50
change master to master_host='192.168.10.20',master_user='replication',master_password='123456',master_log_file='mysql_bin.000001',master_log_pos=1023;
start slave;
show slave status\G;
(6) 测试主主、主从同步情况
2. 安装配置 MySQL-MMM
(1) 在所有服务器上安装 MySQL-MMM
注:若本地仓库中无以上软件,需先为各服务器配置在线源仓库。
yum -y install epel-release && yum -y install mysql-mmm*
(2) 在 master1 上对 MySQL-MMM 进行配置
192.168.10.20
[root@master1 ~]# cd /etc/mysql-mmm/
[root@master1 mysql-mmm]# cp mmm_common.conf mmm_common.conf.bak
#修改配置文件前,先备份
[root@master1 mysql-mmm]# vim mmm_common.conf
active_master_role writer
<host default>
cluster_interface ens33
pid_path /run/mysql-mmm-agent.pid
bin_path /usr/libexec/mysql-mmm/
replication_user replication
##指定主主、主从复制用户,要与前面一致
replication_password 123456
agent_user mmm_agent
##指定monitor代理进程的用户名
agent_password 123456
</host>
<host db1>
ip 192.168.10.20
mode master
peer db2
##peer设置同级数据库
</host>
<host db2>
ip 192.168.10.30
mode master
peer db1
</host>
<host db3>
ip 192.168.10.40
mode slave
</host>
<host db4>
ip 192.168.10.50
mode slave
</host>
<role writer>
hosts db1, db2
ips 192.168.10.200
##设定写VIP
mode exclusive
#只有一个 host 可以进行写操作模式
</role>
<role reader>
hosts db3, db4
ips 192.168.10.201, 192.168.10.202
##设定读VIP
mode balanced
##多个 slave 主机可以进行读操作模式
</role>
(3) 把配置文件复制到其他 4 台主机
所有主机该配置文件内容都是相同的
scp mmm_common.conf root@192.168.10.30:/etc/mysql-mmm/
scp mmm_common.conf root@192.168.10.40:/etc/mysql-mmm/
scp mmm_common.conf root@192.168.10.50:/etc/mysql-mmm/
scp mmm_common.conf root@192.168.10.90:/etc/mysql-mmm/
(4) 修改所有数据库服务器的代理配置文件 mmm_agent.conf
master1
[root@master1 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db1
##根据不同的主机分别修改为db1/db2/db3/db4,默认配置为db1,因此master1无需修改
master2
[root@master2 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db2
slave1
[root@slave ~]# vim /etc/mysql-mmm/mmm_agent.conf include mmm_common.conf this db3
slave 2
[root@slave2 ~]# vim /etc/mysql-mmm/mmm_agent.conf
include mmm_common.conf
this db4
(5) 在 monitor 监控服务器上修改监控配置文件 mmm_mon.conf
monitor 服务器(192.168.10.90)
[root@monitor ~]# vim /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
ip 127.0.0.1
pid_path /run/mysql-mmm-monitor.pid
bin_path /usr/libexec/mysql-mmm
status_path /var/lib/mysql-mmm/mmm_mond.status
ping_ips 192.168.10.20,192.168.10.30,192.168.10.40,192.168.10.50
##指定所有数据库服务器的IP
auto_set_online 10
##指定自动上线时间
# The kill_host_bin does not exist by default, though the monitor will
# throw a warning about it missing. See the section 5.10 "Kill Host
# Functionality" in the PDF documentation.
#
# kill_host_bin /usr/libexec/mysql-mmm/monitor/kill_host
#
</monitor>
<host default>
monitor_user mmm_monitor
##指定mmm_monitor的用户名
monitor_password 123456
##指定mmm_monitor的密码
</host>
debug 0
(6) 在所有数据库上为 mmm_agent(代理进程)授权
所有数据库执行下列语句
grant super,replication client,process on *.* to 'mmm_agent'@'192.168.10.%' identified by '123456';
flush privileges;
(7) 在所有数据库上为 mmm_monitor(监控进程)授权
grant replication client on *.* to 'mmm_monitor'@'192.168.10.%' identified by '123456';
flush privileges;
(8) 在所有数据库服务器上启动 mysql-mmm-agent
systemctl start mysql-mmm-agent.service && systemctl enable mysql-mmm-agent.service
(9) 在 monitor 服务器上启动 mysql-mmm-monitor
systemctl start mysql-mmm-monitor.service && systemctl enable mysql-mmm-monitor.service
(10) 在 monitor 服务器上测试群集
① 查看各节点的情况
[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles: writer(192.168.10.200)
db2(192.168.10.30) master/ONLINE. Roles:
db3(192.168.10.40) slave/ONLINE. Roles: reader(192.168.10.202)
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201)
② 检测监控功能是否完善
[root@monitor ~]#mmm_control checks all
db4 ping [last change: 2021/11/04 16:13:20] OK
db4 mysql [last change: 2021/11/04 16:13:20] OK
db4 rep_threads [last change: 2021/11/04 16:13:20] OK
db4 rep_backlog [last change: 2021/11/04 16:13:20] OK: Backlog is null
db2 ping [last change: 2021/11/04 16:13:20] OK
db2 mysql [last change: 2021/11/04 16:13:20] OK
db2 rep_threads [last change: 2021/11/04 16:13:20] OK
db2 rep_backlog [last change: 2021/11/04 16:13:20] OK: Backlog is null
db3 ping [last change: 2021/11/04 16:13:20] OK
db3 mysql [last change: 2021/11/04 16:13:20] OK
db3 rep_threads [last change: 2021/11/04 16:13:20] OK
db3 rep_backlog [last change: 2021/11/04 16:13:20] OK: Backlog is null
db1 ping [last change: 2021/11/04 16:13:20] OK
db1 mysql [last change: 2021/11/04 16:13:20] OK
db1 rep_threads [last change: 2021/11/04 16:13:20] OK
db1 rep_backlog [last change: 2021/11/04 16:13:20] OK: Backlog is null
③ 指定绑定 VIP 的主机
[root@monitor ~]#mmm_control move_role writer db2
OK: Role 'writer' has been moved from 'db1' to 'db2'. Now you can wait some time and check new roles info!
[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles:
db2(192.168.10.30) master/ONLINE. Roles: writer(192.168.10.200)
db3(192.168.10.40) slave/ONLINE. Roles: reader(192.168.10.202)
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201)[root@monitor ~]#mmm_control move_role writer db1
OK: Role 'writer' has been moved from 'db2' to 'db1'. Now you can wait some time and check new roles info!
[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles: writer(192.168.10.200)
db2(192.168.10.30) master/ONLINE. Roles:
db3(192.168.10.40) slave/ONLINE. Roles: reader(192.168.10.202)
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201)
3. 故障测试
(1) 模拟 master 宕机以及恢复
① 停止 master1 的 mysql 服务
② 查看 VIP 漂移情况
monitor
[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/HARD_OFFLINE. Roles:
db2(192.168.10.30) master/ONLINE. Roles: writer(192.168.10.200)
db3(192.168.10.40) slave/ONLINE. Roles: reader(192.168.10.202)
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201)
VIP 成功漂移至 master2,且 master1 显示 HARD_OFFLINE
③ 重启 master1 的 mysql 服务
master1
systemctl start mysqld
master1 恢复后 VIP 仍在 master2 上,并未转移到 master1
(2) 模拟从服务器宕机以及恢复
① 停止 slave1 的 mysql 服务
slave1
systemctl stop mysqld
② 查看 VIP 漂移情况
monitor
[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles:
db2(192.168.10.30) master/ONLINE. Roles: writer(192.168.10.200)
db3(192.168.10.40) slave/HARD_OFFLINE. Roles:
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201), reader(192.168.10.202)
slave1 所对应的的 VIP 被 slave2 接管
③ 重启 slave1 的 mysql 服务
slave1
systemctl start mysqld
④ 查看 slave1 是否恢复
monitor
[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles:
db2(192.168.10.30) master/ONLINE. Roles: writer(192.168.10.200)
db3(192.168.10.40) slave/AWAITING_RECOVERY. Roles:
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201), reader(192.168.10.202)[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles:
db2(192.168.10.30) master/ONLINE. Roles: writer(192.168.10.200)
db3(192.168.10.40) slave/ONLINE. Roles:
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201), reader(192.168.10.202)[root@monitor ~]#mmm_control show
db1(192.168.10.20) master/ONLINE. Roles:
db2(192.168.10.30) master/ONLINE. Roles: writer(192.168.10.200)
db3(192.168.10.40) slave/ONLINE. Roles: reader(192.168.10.202)
db4(192.168.10.50) slave/ONLINE. Roles: reader(192.168.10.201)
在一段时间的交接后,slave1 重新获取到 VIP,继续工作
(3) 客户端测试
① 在 master1 服务器上为 monitor 服务器地址授权登录
grant all on *.* to 'test'@'192.168.10.90' identified by '123456';
flush privileges;
② 在 monitor 服务器上使用 VIP 登录
yum -y install mariadb-server mariadb
systemctl start mariadb.service && systemctl enable mariadb.service
mysql -utest -p123456 -h 192.168.10.200 #能登录则成功
③ 客户端创建数据,测试同步情况
monitor