原理图:
高可用:
最擅长的是为我们解决物理损坏
MHA Failover 原理
0.启动Manager
调用 masterha_manager 脚本启动manager程序
1.监控?
通过 masterha_master_monitor 心跳检测脚本,数据库节点,主要监控主库。
默认探测4次,每隔(ping interval=2)秒,如果主库还没有心跳,认为主库宕机,进入failover过程。(故障转移)
2 选主?
#1.优先级(主观) 如果在节点配置时(/etc/mha/app1.cnf 对应的[server2]此类节点下),加入了candidate_master=1 参数。
如果备选主,日志量落后master太多(默认是落后100M的日志量),也不会选择新主。
可以通过check_repl_delay=0,不检查日志落后的情况。
#2 日志量最接近主库
#3 日志量一样。配置文件顺序。
3.日志补偿
#情况1:ssh能连上,通过save_binary_logs
立即保存部分缺失部分的日志到从库并恢复
#情况2:ssh不能连,对比从库之间的relaylog的差异(apply_diff_relay_logs)
两个从库进行日志diff差异补偿。
4.主从身份切换,所有从库取消原有主库的复制关系(stop slave,reset slave all)
新主库和剩余从库从新构建主从关系。
5.故障库自动被剔除集群(master_conf_host配置信息去掉)
6.MHA是一次性高可用,Failover后,Manger自动退出.
以上是,MHA的基础环境所有具备的功能。
不足的地方有哪些?
0.应用透明
1.数据补偿
2.自动提醒
3.自愈功能
1) MHA + K8s + Operator
2) 8.0版本 MGR + mysqlsh
无状态服务: 没有数据的服务
4.应用透明vip功能
说明:只能同机房使用,无法跨机房网络
4.1配置参数(db03)
master_ip_failover_script=/usr/local/bin/master_ip_failover
注意:/usr/local/bin/master_ip_failover,必须事先准备好
修改脚本内容
vi /usr/local/bin/master_ip_failover
my $vip = '10.0.0.55/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip"; (eth0 三个节点网卡名称)
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
master_ip_failover脚本里有中文字符,需要转换
安装工具:yum -y install dos2unix
进行转换:[root@later03/usr/local/bin]# dos2unix master_ip_failover
dos2unix: converting file master_ip_failover to Unix format ...
更改manager配置文件:
vi /etc/mha/app1.cnf添加:master_ip_failover_script=/usr/local/bin/master_ip_failover
加入执行权限 [root@db03~]# chmod +x /usr/local/bin/master_ip_failover
主库上,手工生成第一个vip地址
手工在主库上绑定vip,注意一定要和配置文件中的ethN一致,我的是eth0:1(1是key指定的值)
ifconfig eth0:1 10.0.0.55/24
重启mha
masterha_stop --conf=/etc/mha/app1.cnf
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 &
检测:
masterha_check_status --conf=/etc/mha/app1.cnf
注意:
keeplive 的话,需要candidate_master=1和check_repl_delay=0进行配合,
防止vip飘逸不再一个节点上。
5.数据补偿:
解决办法:找一台机器实时拉取主库的binlog日志,如果主库损坏,
那么也保证了主库完整的binlog用于进行从库的日志补偿。
binlogserver配置:找一台额外的机器,必须要有5.6以上的版本,支持gtid并开启,我们直接用的第二个slave(db03)
vim/etc/mha/app1.cnf
[binlog1]
no_master=1 --不参与选主
hostname=39.101.204.8
master_binlog_dir=/binlog/3306
创建必要目录
mkdir -p /data/mysql/binlog
chown -R mysql.mysql /data/*
修改完成后,将主库binlog拉过来(从000001开始拉,之后的binlog会自动按顺序过来)
拉取主库binlog日志
cd /data/mysql/binlog -----》必须进入到自己创建好的目录
mysqlbinlog -R --host=39.101.199.159 --user=mha --password=mha --raw --stop-never mysql-bin.000001 &
生产中:
show master status; 查看主库正在使用的binlog日志位置点
查看为:mysql-bin.000003
也可以先 flush logs;然后在进行拉取
直接拉取正在用的日志点以及以后的:
mysqlbinlog -R --host=39.101.199.159 --user=mha --password=mha --raw --stop-never mysql-bin.000003 &
注意:拉取日志的起点,需要按照目前从库的已经获取到的二进制日志点为起点
重启mha:
masterha_stop --conf=/etc/mha/app1.cnf
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 &
检测:
masterha_check_status --conf=/etc/mha/app1.cnf
6.邮件提醒
1.参数:report_script=/usr/local/bin/send
2.准备邮件脚本send_report
(1)准备发邮件的脚本(上传 email_2019-最新.zip中的脚本,拷贝到/usr/local/bin/中)
cp -a * /usr/local/bin/
赋予执行权限:
chmod +x *
修改脚本,邮箱信息
注意:这里因为阿里云屏蔽了邮箱的25端口,导致不能使用linux自带的工具,所以没能用上老师提供的脚本,这里自己写了一个python脚本 test.py 然后集成到 send 脚本 进行调用.
[root@later03/data/mysql/binlog]# cat /usr/local/bin/send
#! /usr/bin/perl -w
system ("python3 /usr/local/bin/test.py")
(2)将准备好的脚本添加到mha配置文件中,让其调用
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)关闭主库,看警告邮件
7.测试MHA的功能
宕机主库测试
测试查看vip
查看邮件
切换日志
故障库是否剔除
8.故障修复思路
# 1.排查进程状态
故障修复:
1.恢复故障节点
(1)实例宕掉/etc/init.d/mysqld start
(2)主机损坏,有可能数据也损坏了备份并恢复故障节点。
2.恢复主从环境看日志文件:CHANGEMASTERTOMASTER_HOST='10.0.0.52',MASTER_PORT=3306,MASTER_AUTO_POSITION=1,MASTER_USER='repl',MASTER_PASSWORD='123';
start slave;
3.恢复manager
3.1修好的故障节点配置信息,加入到配置文件
[server1]hostname=10.0.0.51
port=3306
3.2启动
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 &