MySQL-MHA高可用

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 过程原理

MySQL-MHA高可用

#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相关工具

MySQL-MHA高可用

通过解压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相关工具

MySQL-MHA高可用

#通过解压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
上一篇:MYSQL 之 MHA架构搭建


下一篇:MySQL--15 MHA简介