MHA高可用
一、 什么是MHA高可用?
MHA能够在较短的时间内实现自动故障检测和故障转移,通常在10-30秒以内;在复制框架中,MHA能够很好地解决复制过程中的数据一致性问题,由于不需要在现有的replication中添加额外的服务器,仅需要一个manager节点,而一个Manager能管理多套复制,所以能大大地节约服务器的数量;另外,安装简单,无性能损耗,以及不需要修改现有的复制部署也是它的优势之处。
MHA还提供在线主库切换的功能,能够安全地切换当前运行的主库到一个新的主库中(通过将从库提升为主库),大概0.5-2秒内即可完成。
MHA由两部分组成:MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以独立部署在一*立的机器上管理多个Master-Slave集群,也可以部署在一台Slave上。当Master出现故障时,它可以自动将最新数据的Slave提升为新的Master,然后将所有其他的Slave重新指向新的Master。整个故障转移过程对应用程序是完全透明的。
#原理:
当Master出现故障时
它可以自动将最新数据的Slave提升为新的Master(数据量最接近主库的那台服务器,每台服务器速度不能保证完全一样)
然后将所有其他的Slave重新指向新的Master(如果原主库恢复,只能当从库)
我们用过其他的高可用keepalived,lb01和lb02,使用的keepalived,但是当vip在一台机器上的时候,另一台机器是闲置的,数据用这种方式的话稍微有点浪费资源
所以mysql有自己的高可用MHA
二、MHA工作原理(详解):
1.保存master主库上所有的binlog事件
2.找到数据量最新的数据(通过对比relay-log)
3.将数据最新的从库数据同步至其他从库
4.提升数据最新的从库为主库(这个时候已经可以恢复业务使用数据库了)
5.通过主库保存的binlog补全到新的主库上
6.其他从库开启以数据最新从库为主的主从复制
#注意:如果主库是突然断电,机器已经连不上了,怎么保存binlog?
#注意:relay-log不是一直存在的,他在一个sql执行完之后会删除?
我们使用的时候可以看日志
通过MHA组件:manager 和 node
1.MHA架构
1.MHA是 C/S 结构的服务,类似于监控
2.MHA manager可以安装在任意一台机器上
3.其他所有机器都要装一个node
4.MHA manager监控主库的node,从库上的node会在切换时发送一些指令,主库保存binlog的工作就是node节点的作用
5.一个MHA manager可以管理多套mysql主从集群(指定配置文件启动多次就可以,像是多实例)
6.可以在主从运行中添加 MHA
7.MHA 尽量避免装在主库上
8.MHA 通过ssh 去管理的其他节点,先做免密
2.MHA Failover 过程原理
#0. 启动Manager
调用masterha_manager脚本启动manager程序
#1. 监控?
通过masterha_master_monitor心跳检测脚本,数据库节点,主从监控主库
默认探测四次,每隔(ping_interval=2s),如果从库还没有心跳,认为主库宕机
进入failover过程
#2. 选主
1.优先级(主观),如果在节点配置时,加入了candidate——master=1参数,如果备选住,日志量落后master太多(后master 100M的relay logs的话),也不会重新选主,也可以通过check_repl_delay=0,不检查日志落后的情景
2.日志量接近主库
3.日志量一样,配置文件顺序
#3. 日志补偿
情况1:ssh能连接上,通过save_binary_logs,立即保存缺失部分的日志到从库(/var/tmp目录下)并恢复
情况2:ssh不能连接上,两个从库进行relaylog日志和diff(apply_diff_relay_logs)差异补偿
#4. 主从身份切管,所有从库取消和原有主库的复制关系(stop slave; reset slave all)
新主库和剩余从库重新构建主从关系
#5. 故障库自动被剔除集群(masterha_conf_host) 配置信息去掉
#6. MHA是一次性的高可用,Failover后,Manager自动推出
以上是MHA的基础环境所有具备的功能
1)不足的地方有哪些?
1.数据补偿
2.自动提醒
3.自愈功能
MHA + k8s + operator
8.0 MGR + mysqlsh
三、MHA基础环境搭建
环境准备
hostname | 内网IP | 外网IP |
---|---|---|
db01 | 172.16.1.51 | 10.0.0.51 |
db02 | 172.16.1.52 | 10.0.0.52 |
db03 | 172.16.1.53 | 10.0.0.53 |
关闭防火墙
关闭selinux
能够实现远程xshell连接
#规划
主库:
10.0.0.51 node
从库:
10.0.0.52 node
10.0.0.53 node manager
1.软件结构
1)Manager:管理软件
masterha_manager 启动MHA
masterha_check_ssh 检查MHA的SSH配置状况
masterha_check_repl 检查MySQL复制状况
masterha_master_monitor 检测master是否宕机
masterha_check_status 检测当前MHA运行状态
masterha_master_switch 控制故障转移(自动或者手动)
masterha_conf_host 添加或删除配置的server信息
2)Node :被管理端软件
这些公户通常由MHA Manager的脚本触发,无需人为操作
save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志时间并将其差异的时间应用于其他的
purge_relay_logs 清除中继日志(不会阻塞SQL线程)
2.基础准备(1主2从GTID)
3.配置关键程序软连接
ln -s /service/database/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
ln -s /service/database/mysql/bin/mysql /sur/bin/mysql
4.配置各节点互信(秘钥对)
1)db01
rm -rf /root/.ssh
ssh-keygen
cd /root/.ssh
mv id_rsa.pub aythorized_keys
scp -r /root/.ssh 10.0.0.52:/root
scp -r /root/.ssh 10.0.0.53:/root
--各节点验证:
db01:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db02:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
db03:
ssh 10.0.0.51 date
ssh 10.0.0.52 date
ssh 10.0.0.53 date
5.安装软件
下载mha软件
https://code.google.com/archive/p/mysql-master-ha/ github
github下载地址
https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads
说明:
--8.0版本
1.密码加密模式 sha2 ---> native
2.使用0.58版本的MHA软件
6.安装node软件依赖包(所有节点都做)
yum install -y perl-DBD-MySQL -y
rpm -ivh mha4mysql-node-0.56-el.noarch.rpm
7.创建mha需要的用户(三台机器都要有,做了主从会自动同步)
grant all privileges on *.* to mha@'%' identified by 'mha';
8.Manager软件安装(db03)
管理节点安装在非主节点的原因,如果master节点断电了,Manager节点可以在其他node节点实现failover(故障切换)
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm
9.Manager 配置文件准备(db03)
#1.创建配置文件目录
mkdir -p /etc/mha
#2.创建日志目录
mkdir -p /var/log/mha/appl
#3.编辑mha配置文件
cat >/etc/mha/app1.cnf <<EOF
[server default]
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/binlog
user=mha password=mha
ping_interval=2
repl_password=123
repl_user=repl
ssh_user=root
[server1]
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
port=3306
[server3]
hostname=10.0.0.53
port=3306
EOF
10.状态检查
--互信检查
masterha_check_ssh --conf/etc/mha/app1.cnf
--主从状态检查
master_check_repl --conf/etc/mha/app1.cnf
--返回成功
masterha_check_repl --conf=/etc/mha/app1.cnf
11.开启MHA-manager(db03)
/var/log/mha/app1/manager.log为启动时日志
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null> /var/log/mha/app1/manager.log 2>&1 &
--详解
# 详解
nohup #后台启动
masterha_manager #MHA的启动程序
--conf=/service/mha/app1.cnf #指定配置文件
--remove_dead_master_conf #移除宕机的server标签从配置文件里
--ignore_last_failover #忽略上一次的切换(涉及一个mysql的工作机制)
< /dev/null > /service/mha/manager.log 2>&1 &
#MHA的安全机制:
1.完成一次切换后,会生成一个锁文件在工作目录中
2.下次切换之前,会检测锁文件是否存在
3.如果锁文件存在,8个小时之内不允许第二次切换
12.查看MHA状态
masterha_check_status --conf=/etc/mha/app1.cnf mysql -umha -pmha -h 10.0.0.51 -e "show variables like 'server_id'"
13.测试切换
#查看日志
tail -f /service/mha/manager.log
#停掉主库
[root@db01 ~]# systemctl stop mysql
提升数据量最多的为主库
如果数据量一样,根据配置文件里面server的顺序切换
#如果把原主库修复,再把提升的主库停止,谁会是主库?
数据量一样的情况下,根据server标签来切换的,标签越小优先级越高
#分析日志内容
#日志最后有一个sendreport机制,可以发送邮件给我们运维,不过一般不用,我们有zabbix可以帮我们监控
#最后执行的时候删除了主库的server信息,他会给他加上注释,然后删除注释的内容
14.修复MHA故障的主库
MHA环境修复步骤:
1.修复宕机的主库,启动主库
2.在MHA的日志中,找到change master 语句
[root@db-03 ~]# grep -i 'change master to' /etc/mha/manager.log
Thu Jul 25 04:38:35 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='172.16.1.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='rep', MASTER_PASSWORD='xxx';
3.在宕机的主库中修改密码并执行
4.start slave开启IO和SQL线程,将宕机的主库重新加入集群变成从库
5.在配置文件中,将server标签添加回去
6.启动MHA
[root@db-03 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 &
7.检测MHA启动状态
[root@db-03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:50155) is running(0:PING_OK), master:172.16.1.52
MHA工具介绍
1.manager相关工具
通过解压MHA源码包,了解MHA manager工具
[root@db-01 ~]# tar xf mha4mysql-manager-0.56.tar.gz
[root@db-01 bin]# ll /root/mha4mysql-manager-0.56/bin
#检查replication(主从复制)
masterha_check_repl
#检查ssh(检测免密)
masterha_check_ssh
#检查MHA的启动状态状态 systemctl status mha
masterha_check_status
#配置主机信息(MHA在切换主库之后,他会提升从库为主库,并且会把主库的信息删除,不论谁是主库都会删除)
masterha_conf_host
[server1]
hostname=10.0.0.51
port=3306
[server2]
hostname=10.0.0.52
port=3306
[server3]
hostname=10.0.0.53
port=3306
#MHA manager启动程序 systemctl start mha
masterha_manager
#监控主库心跳
masterha_master_monitor
#切换主机
masterha_master_switch
#建立TCP连接
masterha_secondary_check
#停止MHA systemctl stop mha
masterha_stop
--------------------------------------------------
#常用的
masterha_check_repl
masterha_check_ssh
masterha_manager
masterha_stop
2. node相关工具
#通过解压MHA源码包,了解MHA node工具
[root@db-01 ~]# tar xf mha4mysql-node-0.56.tar.gz
[root@db-01 bin]# ll /root/mha4mysql-node-0.56/bin
#对比中继日志
apply_diff_relay_logs
#防止binlog回滚 rollback(物理备份的时候会做redo,为了防止数据丢失,切换以后正常使用不能保证客户不会提交)
filter_mysqlbinlog
#删除relay-log ###关闭mysql自动清除relay-log的功能
purge_relay_logs
#保存binlog日志
save_binary_logs
四、MHA优点总结
1.Masterfailover and slave promotion can be done very quickly
自动故障转移快(10-30)
2.Mastercrash does not result in data inconsistency
主库崩溃不存在数据一致性问题
3.Noneed to modify current MySQL settings (MHA works with regular MySQL)
不需要对当前mysql环境做重大修改
4.Noneed to increase lots of servers
不需要添加额外的服务器(仅一台manager就可管理上百个replication)
5.Noperformance penalty
性能优秀,可工作在半同步复制和异步复制,支持gtid,当监控mysql状态时,仅需要每隔N秒向master发送ping包(默认3秒),所以对性能无影响。你可以理解为MHA的性能和简单的主从复制框架性能一样。
#ping baidu.com 10.0.0.50 (icmp协议)
#发送ping包属于sql ping , select ping 检测主库的心跳
6.Works with any storage engine
只要replication支持的存储引擎,MHA都支持,不会局限于innodb
五、主库切换优先级
1.数据量切换测试
1.做好主从
2.创建一个表
use test;
create table linux(id int not null primay key auto_increment,name varchar(10));
3.写一个一直添加数据的脚本
#!/bin/bash
while true;do
mysql -e "insert into test.oldboy(name) values(lhd)"
sleep 1
done
4.执行脚本
5.一台从库不停数据,一台数据库将IO线程停止
stop slave io_thread;
6.停止主库查看切换情况
2.优先级切换测试
1.配置优先级测试
candidate_master=1
check_repl_delay=0
六、VIP应用透明 === ip漂移
说明:只能同机房使用,无法跨机房跨网络
1.VIP漂移的两种方式
1)通过keepalived的方式,管理虚拟IP的漂移
2)通过MHA自带脚本方式,管理虚拟IP的漂移
注意:keepalived的话,需要candidate_master=1和check_repl_delay=0进行配合,防止VIP和主库选择不在一个节点
2.配置读取脚本
#编辑配置文件
[root@mysql-db03 ~]# vim /etc/mha/app1.cnf
#在[server default]标签下添加
[server default]
#使用MHA自带脚本
master_ip_failover_script=/service/mha/master_ip_failover
3.编写脚本
#将脚本复制到指定读取的位置
[root@db01 ~]# cp mha4mysql-manager-0.56/samples/scripts/master_ip_failover /service/mha/master_ip_failover
#编辑脚本
[root@mysql-db03 ~]# vim /etc/mha/master_ip_failover
#修改以下几行内容
my $vip = '10.0.0.55/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth1:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth1:$key down";
#如果ssh的用户和端口做了优化的话
my $ssh_user = 'lhd';
#英文字符转换为中文字符
yum install -y dos2unix
dos2unix /usr/local/bin/master_ip_failover
#添加执行权限,否则mha无法启动
[root@mysql-db03 ~]# chmod +x /etc/mha/master_ip_failover
4.手动绑定VIP(db01)
#我们在做keepalived的时候他会帮我们添加VIP,实际上操作就是
ifconfig eth0:0 10.0.0.55/24
切换的时候就是把VIP所在机器
ifconfig eth0:0 down
然后切换到另一台机器去执行
ifconfig eth0:0 10.0.0.55/24
#绑定vip
[root@mysql-db01 ~]# ifconfig eth0:0 10.0.0.55/24
#查看vip
[root@mysql-db01 ~]# ip a |grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
5.binlog server(db03)
参数
vim /etc/mha/app1.cnf
[binlog1]
no_master=1 #不参与选主
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog
6.创建必要目录
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/*
7.拉取主库binlog日志
cd /data/mysql/binlog ---> 必须进入到自己创建好的目录
mysqlbinlog -R --host=10.0.0.52 --user=mha --password=mha --raw --stop-never mysql-bin.0000001 &
注意:
拉取日志的起点,需要按照目前从库的已经获取到的二进制日志点为起点
8.启动MHA(db03)
--重启
masterha_stop --conf=/etc/mha/app1.cnf
--启动
[root@mysql-db03 ~]# nohup masterha_manager --conf=/service/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /service/mha/manager.log 2>&1 &
master_ip_failover脚本启动:
1.语法要正确
2.权限要正确
[root@db-03 mha]# chmod +x master_ip_failover
3.格式要正确
[root@db-03 ~]# yum install -y dos2unix
[root@db-03 mha]# dos2unix master_ip_failover
dos2unix: converting file master_ip_failover to Unix format ...
9.测试ip漂移
#登录db02
[root@mysql-db02 ~]# mysql -uroot -p123
#查看slave信息
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.51
Master_User: rep
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#停掉主库
[root@mysql-db01 ~]# /etc/init.d/mysqld stop
Shutting down MySQL..... SUCCESS!
#在db03上查看从库slave信息
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.52
Master_User: rep
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#在db01上查看vip信息
[root@mysql-db01 ~]# ip a |grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 10.0.0.51/24 brd 10.0.0.255 scope global eth0
#在db02上查看vip信息
[root@mysql-db02 ~]# ip a |grep eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
inet 10.0.0.52/24 brd 10.0.0.255 scope global eth0
inet 10.0.0.55/24 brd 10.0.0.255 scope global secondary eth0:0
七、MHA高可用-邮件提醒
#1. 参数:
report_script=/usr/local/bin/send
#2. 准备邮件脚本
send_report
(1)准备发邮件的脚本(上传 email_2019-最新.zip中的脚本,到/usr/local/bin/中)
(2)将准备好的脚本添加到mha配置文件中,让其调用
unzip email_2019-最新.zip
cd email
cp -a * /usr/local/bin
chmod +x /usr/local/bin/*
#3. 修改manager配置文件,调用邮件脚本
vi /etc/mha/app1.cnf
report_script=/usr/local/bin/send
(3)停止MHA
masterha_stop --conf=/etc/mha/app1.cnf
(4)开启MHA
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
(5) 关闭主库,看警告邮件
八、测试MHA Failover的功能
宕掉主库测试
测试查看 vip
查看邮件
切换日志:/var/log/mha/app1/manager
故障库是否剔除
主从状态
1.MHA故障排错思路
1. 排查进程状态
ps -ef | grep manager
2. 检查配置文件中的节点
cat /etc/mha/app1.cnf
如果节点已经被移除,说明切换过程已经大部分成功
如果节点还在,证明切换过程在中间卡住
3. 看日志
vim /var/log/mha/app1/manager
2.MHA 修复故障库的思路
1. 先启动数据库
(1)实例宕掉
/etc/init.d/mysqld start
(2)主机损坏,有可能数据也损坏了
备份并恢复故障节点。
2. 修复主从
3. 将故障库修好后,手工加入已有的主从中,作为从库
CHANGE MASTER TO
MASTER_HOST='10.0.0.52',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=444,
MASTER_CONNECT_RETRY=10;
show slave status \G
4. 检查ssh互信和repl的主从关系
masterha_check_ssh --conf=/etc/mhs/app1.cnf
masterha_check_repl --conf=/etc/mha/app1.cnf
5. 重新修复binlogserver
cd /data/mysql/binlog/
rm -rf *
mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-nerver mysql-bin.0000001 &
6. 检查主节点vip的状态
如果不在,再手工生成一下
7.启动MHA
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
================================
主库宕机,binlogserver 自动停掉,manager 也会自动停止。
处理思路:
1、重新获取新主库的binlog到binlogserver中
2、重新配置文件binlog server信息
3、最后再启动MHA
3.MHA Failover 原理
1. 监控:p
ing_interval=1
select user();
2. 选主:强制选主
candidate_master=1
check_repl_delay=0
3. 日志补偿
binlog_server
日志补偿阶段是最影响Failover速度
所以要从根本上降低日志补偿的时间
归根结底:减少主从之前的延时才是大方向
GTID,锁,大事务,SQl并发线程,双一
4. 切换:vip,主从重构
九、MHA高可用应用
1. 规划和实施
MHA基础架构+binlogserver+VIP+Sendreport
项目1:MHA高可用架构改造
1.历史架构:MHA基础架构
2.痛点
--应用
没有支持vip,应用端只能通过主库IP连接集群
如果主库宕机,需要修改应用端配置
高可用性不完整,需要管理员参与切换
--数据
如果主库整体宕掉,SSH连接不上,很有可能丢失部分事务
--提醒
没有故障提醒功能,管理员不能及时反应
3.架构改造方案
在MHA基础架构上进行升级改造
1. binlogserver 日志补偿
2. VIP功能 应用透明
3. sendreport 及时提醒
4.管理员职责
1. MHA切换之后可以快速反映,修复架构
2. MHA优化,尽可能缩短MHA Failover
项目2:MHA架构故障修复
三台节点,都关机没修复过程
1. 启动所有节点
2. 确认主库
db03 ---> show slave status \G
3. 修复1主2从复制环境(主从要是正常,就可以省略)
CHANGE MASTER TO
MASTER_HOST='10.0.0.52',
MASTER_USER='repl',
MASTER_PASSWORD='123',
MASTER_PORT=3307,
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=444,
MASTER_CONNECT_RETRY=10;
start slave;
4. 修复配置文件
[server2]
hostname=10.0.0.52
port=3306
5. 修复binlogserver(db03)
cd /data/mysql/binlog/
rm -rf *
mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-nerver mysql-bin.0000001 &
6. 主库修复vip
ifconfig ens33:1 10.0.0.55/24
7. 检查ssh和repl
masterha_check_ssh --conf=/etc/mha/app1.cnf
masterha_check_repl --conf=/etc/mha/app1.cnf
8. 启动MHA manager
nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
--检查状态
master_check_status --conf=/etc/mha/app1.cnf