MySQL高可用之MMM
MMM简介
MMM即Multi-Master Replication Manager for MySQL:mysql多主复制管理器,基于perl实现,关于mysql主主复制配置的监控、故障转移和管理的一套可伸缩的脚本套件(在任何时候只有一个节点可以被写入),MMM也能对从服务器进行读负载均衡,所以可以用它来在一组用于复制的服务器启动虚拟ip,除此之外,它还有实现数据备份、节点之间重新同步功能的脚本。
MySQL本身没有提供replication failover的解决方案,通过MMM方案能实现服务器的故障转移,从而实现mysql的高可用。MMM不仅能提供浮动IP的功能,如果当前的主服务器挂掉后,会将你后端的从服务器自动转向新的主服务器进行同步复制,不用手工更改同步配置。这个方案是目前比较成熟的解决方案。详情请看官网:http://mysql-mmm.org
优点: 高可用性,扩展性好,出现故障自动切换,对于主主同步,在同一时间只提供一台数据库写操作,保证的数据的一致性。当主服务器挂掉以后,另一个主立即接管,其他的从服务器能自动切换,不用人工干预。
缺点: monitor节点是单点,不过这个你也可以结合keepalived或者haertbeat做成高可用;至少三个节点,对主机的数量有要求,需要实现读写分离,还需要在前端编写读写分离程序。在读写非常繁忙的业务系统下表现不是很稳定,可能会出现复制延时、切换失效等问题。
使用场景: MMM方案并不太适应于对数据安全性要求很高,并且读、写繁忙的环境中。 MMM的适用场景为数据库访问量大,并且能实现读写分离的场景。
Mmm主要功能由下面三个脚本提供:
- mmm_mond 负责所有的监控工作的监控守护进程,决定节点的移除(mmm_mond进程定时心跳检测,失败则将write ip浮动到另外一台master)等等。
- mmm_agentd 运行在mysql服务器上的代理守护进程,通过简单远程服务集提供给监控节点。
- mmm_control 通过命令行管理mmm_mond进程 在整个监管过程中,需要在mysql中添加相关授权用户,授权的用户包括一个mmm_monitor用户和一个mmm_agent用户,如果想使用mmm的备份工具则还要添加一个mmm_tools用户。
部署实施
1、 环境:
OS:centos7.2(64位),数据库系统:mysql5.7.13
关闭selinux , 配置ntp同步时间
IP规划
主机名 | IP |
---|---|
master1 | 192.168.1.65 |
master2 | 192.168.1.70 |
slave1 | 192.168.1.71 |
slave2 | 192.168.1.72 |
monitor | 192.168.1.73 |
vip | 读 | 写 |
---|---|---|
192.168.1.51 | ||
192.168.1.52 | ||
192.168.1.53 | ||
192.168.1.50 | ||
在所有主机上配置添加/etc/hosts文件如下 |
cat /etc/hosts
....
192.168.1.65 master1
192.168.1.70 master2
192.168.1.71 slave1
192.168.1.72 slave2
192.168.1.73 monitor
在所有主机上安装以下包
yum -y install perl-* libart_lgpl.x86_64 rrdtool.x86_64 rrdtool-perl.x86_64
注:使用centos7在线yum源安装 安装perl的相关库
(1)更改国内源
//默认cpan shell 使用的是cpan.org的源,在国内使用的话速度会非常的慢,所有修改为国内的源
~]# cpan
#一律yes,等待片刻
//查看当前配置源
cpan[2]> o conf
....
0 [http://ftp.kr.freebsd.org/pub/CPAN/]
1 [http://mirror.rol.ru/CPAN/]
2 [http://mirror.downloadvn.com/cpan/]
....
// 移除默认的三个源
cpan[7]> o conf urllist pop http://ftp.kr.freebsd.org/pub/CPAN/
Please use 'o conf commit' to make the config permanent!
cpan[8]> o conf urllist pop http://ftp.kr.freebsd.org/pub/CPAN/
Please use 'o conf commit' to make the config permanent!
cpan[9]> o conf urllist pop http://mirror.rol.ru/CPAN/
Please use 'o conf commit' to make the config permanent!
cpan[10]> o conf commit
commit: wrote '/root/.cpan/CPAN/MyConfig.pm'
//添加国内源
cpan[12]> o conf urllist push http://mirrors.aliyun.com/CPAN/
Please use 'o conf commit' to make the config permanent!
cpan[13]> o conf commit //添加完成后别忘记提交
commit: wrote '/root/.cpan/CPAN/MyConfig.pm'
cpan[14]> o conf urllist //查看源
urllist
0 [http://mirrors.aliyun.com/CPAN/]
Type 'o conf' to view all configuration items
cpan[15]> exit
//安装perl的相关库
cpan -i Algorithm::Diff Class::Singleton DBI DBD::mysql Log::Dispatch Log::Log4perl Mail::Send Net::Ping Proc::Daemon Time::HiRes Params::Validate Net::ARP
可能有些包没有安装上我们进行手动安装
我这里Net::ARP、Net::Ping、DBD::mysql三个包没有安装上,我们进行手动安装
https://mirrors.aliyun.com/CPAN/?spm=a2c6h.13651104.0.0.47b5cbf2FaSJRP
同样的方法下载剩下的两个包,此处省略
wget https://cpan.metacpan.org/authors/id/C/CR/CRAZYDJ/Net-ARP-1.0.11.tgz
wget https://cpan.metacpan.org/authors/id/R/RU/RURBAN/Net-Ping-2.74.tar.gz
wget https://cpan.metacpan.org/authors/id/D/DV/DVEEDEN/DBD-mysql-4.050.tar.gz
tar zxf Net-ARP-1.0.11.tgz
cd Net-ARP-1.0.11/
perl Makefile.PL
make install
tar zxf Net-Ping-2.74.tar.gz
cd Net-Ping-2.74/
perl Makefile.PL
make install
tar zxf DBD-mysql-4.050.tar.gz
cd DBD-mysql-4.050/
perl Makefile.PL --mysql_config=/usr/local/mysql/bin/mysql_config
make
make install
2、配置主从复制
master1和master2互为主从,slave1、slave2为master1的从
在每个mysql的配置文件/etc/my.cnf中加入以下内容, 注意server-id不能重复。
master1主机:
[mysqld]
....
log-bin = mysql-bin
binlog_format = mixed
server-id = 1
relay-log = relay-bin
relay-log-index = slave-relay-bin.index
log-slave-updates = 1
auto-increment-increment = 2
auto-increment-offset = 1
master2主机:
[mysqld]
....
log-bin = mysql-bin
binlog_format = mixed
server-id = 2
relay-log = relay-bin
relay-log-index = slave-relay-bin.index
log-slave-updates = 1
auto-increment-increment = 2
auto-increment-offset = 2
slave1主机:
[mysqld]
....
server-id = 3
relay-log = relay-bin
relay-log-index = slave-relay-bin.index
read_only = 1
slave2主机:
[mysqld]
....
server-id = 4
relay-log = relay-bin
relay-log-index = slave-relay-bin.index
read_only = 1
在完成了对my.cnf的修改后,重新启动mysql服务
//防火墙设置
4 台数据库主机若要开启防火墙,要么关闭防火墙或者创建访问规则
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload
//主从配置(master1和master2配置成主主,slave1和slave2配置成master1的从)
//在master1上授权:
grant replication slave on *.* to rep@'192.168.1.%' identified by '123.com';
//在master2上授权:
grant replication slave on *.* to rep@'192.168.1.%' identified by '123.com';
把master2、slave1和slave2配置成master1的从库
在master1上执行show master status; 获取binlog文件和Position点
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 154 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在master2、slave1和slave2执行
三台主机同步执行
mysql> change master to
-> master_host='192.168.1.65',
-> master_user='rep',
-> master_password='123.com',
-> master_log_file='mysql-bin.000002',
-> master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.02 sec)
三台主机验证
mysql> show slave status\G
.......
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Slave_IO_Running和Slave_SQL_Running都为yes,那么主从就已经配置OK了
把master1配置成master2的从
在master2上执行show master status ;获取binlog文件和Position点
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 | 451 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
在master1上执行:
mysql> change master to
-> master_host='192.168.1.70',
-> master_user='rep',
-> master_password='123.com',
-> master_log_file='mysql-bin.000002',
-> master_log_pos=451;
Query OK, 0 rows affected, 2 warnings (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
验证主从复制: master1主机:
mysql> show slave status\G
Slave_IO_Running和Slave_SQL_Running都为yes,那么主从就已经配置OK了
3、mysql-mmm配置
在4台mysql节点上创建用户
//创建代理账号:
grant super,replication client,process on *.* to 'mmm_agent'@'192.168.1.%' identified by '123.com';
//创建监控账号
grant replication client on *.* to 'mmm_monitor'@'192.168.1.%' identified by '123.com';
注:因为之前的主从复制,以及主从已经是ok的,所以我只在master1服务器执行就ok了。
检查master2和slave1、slave2
三台db上是否都存在监控和代理账号
mysql> select user,host from mysql.user where user in ('mmm_monitor','mmm_agent');
+-------------+-------------+
| user | host |
+-------------+-------------+
| mmm_agent | 192.168.1.% |
| mmm_monitor | 192.168.1.% |
+-------------+-------------+
mmm_monitor用户:mmm监控用于对mysql服务器进程健康检查
mmm_agent用户:mmm代理用来更改只读模式,复制的主服务器等
4、 mysql-mmm安装
在monitor主机上安装监控程序
wget http://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz
tar -zxf mysql-mmm-2.2.1.tar.gz
cd mysql-mmm-2.2.1
make install
//在数据库服务器(master1、master2、slave1、slave2
)上安装代理
wget http://pkgs.fedoraproject.org/repo/pkgs/mysql-mmm/mysql-mmm-2.2.1.tar.gz/f5f8b48bdf89251d3183328f0249461e/mysql-mmm-2.2.1.tar.gz
tar -zxf mysql-mmm-2.2.1.tar.gz
cd mysql-mmm-2.2.1
make install
5、 配置mmm 编写配置文件,五台主机必须一致
// 完成安装后,所有的配置文件都放到了/etc/mysqlmmm/下面。管理服务器和数据库服务器上都要包含一个共同的文件mmm_common.conf,内容如下
cat /etc/mysql-mmm/mmm_common.conf
active_master_role writer #积极的master角色的标示,所有的db服务器要开启read_only参数,对于writer服务器监控代理会自动将read_only属性关闭。
<host default>
cluster_interface ens33 #群集的网络接口
pid_path /var/run/mmm_agentd.pid #pid路径
bin_path /usr/lib/mysql-mmm/ #可执行文件路径
replication_user rep #复制用户
replication_password 123.com #复制用户密码
agent_user mmm_agent #代理用户
agent_password 123.com #代理用户密码
</host>
<host master1> #master1的host名
ip 192.168.1.65 #master的ip地址
mode master #角色属性,master代表是主
peer master2 #与master1对等的服务器的host名,也就是master2的服务器host名
</host>
<host master2> #和master的概念一样
ip 192.168.1.70
mode master
peer master1
</host>
<host slave1> #从库的host名,如果存在多个从库可以重复一样的配置
ip 192.168.1.71 #从的ip地址
mode slave #slave的角色属性代表当前host是从
</host>
<host slave2> #和slave1的概念一样
ip 192.168.1.72
mode slave
</host>
<role writer> #writer角色配置
hosts master1,master2 #能进行写操作的服务器的host名,如果不想切换写操作这
里可以只配置master,这样也可以避免因为网络延时而进行write的切换,但是一旦 master出现故障那么当前的MMM就没有writer了只有对外的read操作了。
ips 192.168.1.50 #对外提供的写操作的虚拟IP
mode exclusive #exclusive代表只允许存在一个主,也就是只能提供一个写的IP
</role>
<role reader> #read角色配置
hosts master2,slave1,slave2 #对外提供读操作的服务器的host名,当然这里也可以把master加进来
ips 192.168.1.51, 192.168.1.52, 192.168.1.53 ##对外提供读操作的虚拟ip,这三个ip和host不是一一对应的,并且ips也hosts的数目也可以不相同,如果这样配置的话其中一个hosts会分配两个ip
mode balanced #balanced代表负载均衡
</role>
将这个文件拷贝到其它的服务器,配置不变
for host in master1 master2 slave1 slave2 ; do scp /etc/mysql-mmm/mmm_common.conf $host:/etc/mysql-mmm/ ; done
代理文件配置
// 编辑 4台mysql
节点机上的/etc/mysql-mmm/mmm_agent.conf
includemmm_common.conf
this master1
#this后面的host名改成当前服务器的主机名
启动代理进程 在 /etc/init.d/mysql-mmm-agent的脚本文件的#!/bin/sh下面,加入如下内容
head -2 /etc/init.d/mysql-mmm-agent
#!/bin/sh
source /root/.bash_profile
添加成系统服务并设置为自启动
chkconfig --add mysql-mmm-agent
chkconfigmysql-mmm-agent on
/etc/init.d/mysql-mmm-agent start
注:添加source /root/.bash_profile目的是为了mysql-mmm-agent服务能启机自启。 自动启动和手动启动的唯一区别,就是激活一个console 。那么说明在作为服务启动的时候,可能是由于缺少环境变量 服务启动失败,
报错信息如下:
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Can't locate Proc/Daemon.pm in @INC (@INC contains:
/usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at
/usr/sbin/mmm_agentd line 7.
BEGIN failed--compilation aborted at /usr/sbin/mmm_agentd line 7.
failed
解决方法
cpan Proc::Daemon
cpan Log::Log4perl
/etc/init.d/mysql-mmm-agent start
Daemon bin: '/usr/sbin/mmm_agentd'
Daemon pid: '/var/run/mmm_agentd.pid'
Starting MMM Agent daemon... Ok
[root@monitor ~]# netstat -anput | grep mmm
tcp 0 0 127.0.0.1:9988 0.0.0.0:* LISTEN 3676/mmm_mond
配置防火墙
firewall-cmd --permanent --add-port=9989/tcp
firewall-cmd --reload
编辑 monitor主机上的/etc/mysql-mmm/mmm_mon.conf
[root@monitor ~]# cat /etc/mysql-mmm/mmm_mon.conf
include mmm_common.conf
<monitor>
ip 127.0.0.1 #为了安全性,设置只在本机监听,mmm_mond默认监听9988
pid_path /var/run/mmm_mond.pid
bin_path /usr/lib/mysql-mmm/
status_path /var/lib/misc/mmm_mond.status
ping_ips 192.168.1.65, 192.168.1.72,192.168.1.71 5#用于测试网络可用性 IP 地址列表,只要其中有一个地址 ping 通,就代表网络正常,这里不要写入本机地址
auto_set_online 0 #设置自动online的时间,默认是超过60s就将它设置为online,默认是60s,这里将其设为0就是立即online
</monitor>
<check default>
check_period 5
trap_period 10
timeout 2
#restart_after 10000
max_backlog 86400
</check>
<host default>
monitor_user mmm_monitor #监控db服务器的用户
monitor_password 123.com #监控db服务器的用户密码
</host>
debug 0 #debug 0正常模式,1为debug模式
check_period
描述:检查周期默认为5s
trap_period
描述:一个节点被检测不成功的时间持续trap_period秒,就慎重的认为这个节点失败了。
默认值:10s
timeout
描述:检查超时的时间
默认值:2s
restart_after
描述:在完成restart_after次检查后,重启checker进程
默认值:10000
max_backlog
描述:记录检查rep_backlog日志的最大次数
默认值:60
启动监控进程: 在 /etc/init.d/mysql-mmm-agent的脚本文件的#!/bin/sh下面,加入如下内容
[root@monitor ~]# head -2 /etc/init.d/mysql-mmm-agent
#!/bin/sh
source /root/.bash_profile
添加成系统服务并设置为自启动
chkconfig --add mysql-mmm-monitor
chkconfigmysql-mmm-monitor on
/etc/init.d/mysql-mmm-monitor start
启动报错:
Starting MMM Monitor daemon: Can not locate Proc/Daemon.pm in @INC (@INC contains:
/usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl
/usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at
/usr/sbin/mmm_mond line 11.
BEGIN failed--compilation aborted at /usr/sbin/mmm_mond line 11.
failed
解决方法:安装下列perl的库
cpan Proc::Daemon
cpan Log::Log4perl
[root@monitor1 ~]# /etc/init.d/mysql-mmm-monitor start
Daemon bin: '/usr/sbin/mmm_mond'
Daemon pid: '/var/run/mmm_mond.pid'
Starting MMM Monitor daemon: Ok
[root@monitor ~]# netstat -anpt | grep 9988
tcp 0 0 127.0.0.1:9988 0.0.0.0:* LISTEN 8546/mmm_mond
注1:无论是在db端还是在监控端如果有对配置文件进行修改操作都需要重启代理进程和监控进程。
注2:MMM启动顺序:先启动monitor,再启动 agent
检查集群状态
root@monitor ~]# mmm_control show
master1(192.168.1.65) master/ONLINE. Roles: writer(192.168.1.50)
master2(192.168.1.70) master/ONLINE. Roles: reader(192.168.1.53)
slave1(192.168.1.71) slave/ONLINE. Roles: reader(192.168.1.52)
slave2(192.168.1.72) slave/ONLINE. Roles: reader(192.168.1.51)
//从上面的显示可以看到,写请求的VIP在master1上,所有从节点也都把master1当做主节点
注:错误:如果MySQL主机是HARD_OFFLINE如下图
解决方法:
[root@monitor ~]# vim /etc/ld.so.conf
添加:
/usr/local/mysql/lib
/usr/lib
[root@monitor ~]# ldconfig
[root@monitor ~]# for i in master1 master2 slave1 slave2;do scp /etc/ld.so.conf $i:/etc/;done
如果服务器状态不是ONLINE,可以用如下命令将服务器上线,例如:
mmm_control set_online 主机名
master1主机,查看是否启用vip
[root@master1 ~]# ip a show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:57:8d:1c brd ff:ff:ff:ff:ff:ff
inet 192.168.1.65/24 brd 192.168.1.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.1.50/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::7c0:18fc:ee75:c06b/64 scope link
valid_lft forever preferred_lft forever
//在master2、slave1、slave2主机上查看vip,此处省略
在master2,slave1,slave2
主机上查看主mysql的指向
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.65
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
可以看到master2,slave1,slave2主机 Master_Host指定的都是master1(192.168.1.65)
MMM高可用性测试
服务器读写采有VIP地址进行读写,出现故障时VIP会漂移到其它节点,由其它节点提供服务。 首先查看整个集群的状态,可以看到整个集群状态正常
[root@monitor ~]# mmm_control show
master1(192.168.1.65) master/ONLINE. Roles: writer(192.168.1.50)
master2(192.168.1.70) master/ONLINE. Roles: reader(192.168.1.53)
slave1(192.168.1.71) slave/ONLINE. Roles: reader(192.168.1.52)
slave2(192.168.1.72) slave/ONLINE. Roles: reader(192.168.1.51)
模拟master1宕机,手动停止mysql服务,观察monitor日志,master1的日志如下:
[root@monitor ~]# tail -f /var/log/mysql-mmm/mmm_mond.log
2021/03/10 12:33:12 WARN Check 'rep_backlog' on 'master1' is in unknown state! Message: UNKNOWN: Connect error (host = 192.168.1.65:3306, user = mmm_monitor)! Can't connect to MySQL server on '192.168.1.65' (111)
2021/03/10 12:33:12 WARN Check 'rep_threads' on 'master1' is in unknown state! Message: UNKNOWN: Connect error (host = 192.168.1.65:3306, user = mmm_monitor)! Can't connect to MySQL server on '192.168.1.65' (111)
2021/03/10 12:33:22 ERROR Check 'mysql' on 'master1' has failed for 10 seconds! Message: ERROR: Connect error (host = 192.168.1.65:3306, user = mmm_monitor)! Can't connect to MySQL server on '192.168.1.65' (111)
2021/03/10 12:33:24 FATAL State of host 'master1' changed from ONLINE to HARD_OFFLINE (ping: OK, mysql: not OK)
2021/03/10 12:33:24 INFO Removing all roles from host 'master1':
2021/03/10 12:33:24 INFO Removed role 'writer(192.168.1.50)' from host 'master1'
2021/03/10 12:33:24 INFO Orphaned role 'writer(192.168.1.50)' has been assigned to 'master2'
查看群集的最新状态
[root@monitor ~]# mmm_control show
master1(192.168.1.65) master/HARD_OFFLINE. Roles:
master2(192.168.1.70) master/ONLINE. Roles: reader(192.168.1.53), writer(192.168.1.50)
slave1(192.168.1.71) slave/ONLINE. Roles: reader(192.168.1.52)
slave2(192.168.1.72) slave/ONLINE. Roles: reader(192.168.1.51)
//从显示结果可以看出master1的状态有ONLINE转换为HARD_OFFLINE,写VIP转移到了master2主机上。
检查所有的db服务器群集状态
[root@monitor ~]# mmm_control checks all
master1 ping [last change: 2021/03/10 09:34:46] OK
master1 mysql [last change: 2021/03/10 12:33:24] ERROR: Connect error (host = 192.168.1.65:3306, user = mmm_monitor)! Can't connect to MySQL server on '192.168.1.65' (111)
master1 rep_threads [last change: 2021/03/10 10:19:48] OK
master1 rep_backlog [last change: 2021/03/10 10:19:48] OK: Backlog is null
slave1 ping [last change: 2021/03/10 09:34:46] OK
slave1 mysql [last change: 2021/03/10 10:19:48] OK
slave1 rep_threads [last change: 2021/03/10 10:19:48] OK
slave1 rep_backlog [last change: 2021/03/10 10:19:48] OK: Backlog is null
master2 ping [last change: 2021/03/10 09:34:46] OK
master2 mysql [last change: 2021/03/10 10:19:48] OK
master2 rep_threads [last change: 2021/03/10 10:19:48] OK
master2 rep_backlog [last change: 2021/03/10 10:19:48] OK: Backlog is null
slave2 ping [last change: 2021/03/10 09:34:46] OK
slave2 mysql [last change: 2021/03/10 10:19:48] OK
slave2 rep_threads [last change: 2021/03/10 10:19:48] OK
slave2 rep_backlog [last change: 2021/03/10 10:19:48] OK: Backlog is null
//从上面可以看到master1能ping通,说明只是服务死掉了。
查看master2主机的ip地址
[root@master2 ~]# ip a show dev ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:ae:db:25 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.70/24 brd 192.168.1.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.1.53/32 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.1.50/32 scope global ens33 #写的vip从master1漂移到了master2上了
valid_lft forever preferred_lft forever
inet6 fe80::ff86:cfc1:18a9:828e/64 scope link
valid_lft forever preferred_lft forever
//写的vip从master1漂移到了master2上了,所有现在master2才是主
验证slave1,slave2
,主机是否手动指定Master_Host为master2的ip地址
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.70
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
启动master1主机的mysql服务,观察monitor日志,master1的日志如下:
2021/03/10 12:43:01 INFO Check 'rep_threads' on 'master1' is ok!
2021/03/10 12:43:01 INFO Check 'rep_backlog' on 'master1' is ok!
2021/03/10 12:43:01 INFO Check 'mysql' on 'master1' is ok!
2021/03/10 12:43:04 FATAL State of host 'master1' changed from HARD_OFFLINE to AWAITING_RECOVERY
从上面可以看到master1的状态由hard_offline改变为awaiting_recovery状态 用如下命令将服务器上线:
[root@monitor ~]# mmm_control set_online master1
OK: State of 'master1' changed to ONLINE. Now you can wait some time and check its new roles!
[root@monitor ~]# mmm_control show
master1(192.168.1.65) master/ONLINE. Roles:
master2(192.168.1.70) master/ONLINE. Roles: reader(192.168.1.53), writer(192.168.1.50)
save1(192.168.1.71) slave/ONLINE. Roles: reader(192.168.1.52)
slave2(192.168.1.72) slave/ONLINE. Roles: reader(192.168.1.51)
//可以看到主库启动不会接管主,只到现有的主再次宕机。
执行write切换(手动切换): 查看当前的slave对应的master
[root@monitor ~]# mmm_control move_role writer master1
OK: Role 'writer' has been moved from 'master2' to 'master1'. Now you can wait some time and check new roles info!
[root@monitor ~]# mmm_control show
master1(192.168.1.65) master/ONLINE. Roles: writer(192.168.1.50)
master2(192.168.1.70) master/ONLINE. Roles: reader(192.168.1.53)
slave1(192.168.1.71) slave/ONLINE. Roles: reader(192.168.1.52)
slave2(192.168.1.72) slave/ONLINE. Roles: reader(192.168.1.51)
总结
(1)master2备选主节点宕机不影响集群的状态,就是移除了master2备选节点的读状态。
(2)master1主节点宕机,由master2备选主节点接管写角色,slave1,slave2指向新master2主库进行复制,slave1,slave2会自动change master到master2。
(3)如果master1主库宕机,master2复制应用又落后于master1时就变成了主可写状态,这时的数据主无法保证一致性。 如果master2,slave1,slave2延迟于master1主,这个时master1宕机,slave1,slave2将会等待数据追上db1后,再重新指向新的主node2进行复制操作,这时的数据也无法保证同步的一致性。
(4)如果采用MMM高可用架构,主,主备选节点机器配置一样,而且开启半同步进一步提高安全性或采用MariaDB/mysql5.7进行多线程从复制,提高复制的性能。
总结2
1.对外提供读写的虚拟IP是由monitor程序控制。如果monitor没有启动那么db服务器不会被分配虚拟ip,但是如果已经分配好了虚拟ip,当monitor程序关闭了原先分配的虚拟ip不会立即关闭外部程序还可以连接访问(只要不重启网络),这样的好处就是对于monitor的可靠性要求就会低一些,但是如果这个时候其中的某一个db服务器故障了就无法处理切换,也就是原先的虚拟ip还是维持不变,挂掉的那台DB的虚拟ip会变的不可访问。
2.agent程序受monitor程序的控制处理write切换,从库切换等操作。如果monitor进程关闭了那么agent进程就起不到什么作用,它本身不能处理故障。
3.monitor程序负责监控db服务器的状态,包括Mysql数据库、服务器是否运行、复制线程是否正常、主从延时等;它还用于控制agent程序处理故障。
4.monitor会每隔几秒钟监控db服务器的状态,如果db服务器已经从故障变成了正常,那么monitor会自动在60s之后将其设置为online状态(默认是60s可以设为其它的值),有监控端的配置文件参数“auto_set_online”决定,群集服务器的状态有三种分别是:HARD_OFFLINE→AWAITING_RECOVERY→online
5.默认monitor会控制mmm_agent会将writer db服务器read_only修改为OFF,其它的db服务器read_only修改为ON,所以为了严谨可以在所有的服务器的my.cnf文件中加入read_only=1由monitor控制来控制writer和read,root用户和复制用户不受read_only参数的影响。