MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现
MHA是一套MySQL高可用管理软件,除了检测Master宕机后,提升候选Slave为New Master之外(漂虚拟IP),还会自动让其他Slave与New Master 建立复制关系。MHA Manager可以单独部署在一台独立的机器上,并管理多个master-slave集群。当自动Failover完成后,MHA Manager服务器上的masterha_manager 进程自动退出。(Currently MHA Manager process does not run as a daemon. If failover completed successfully or the master process was killed by accident, the manager stops working. --官方文档)
面临的问题
我们知道开启MHA Manager监控,当MHA 发生自动漂移时,会将老的主库的ip将会从配置文件中移除。那么怎么可以自动将原Master 节点自动以Slave角色添加到集群中来是运维同学面临的问题。
并且大多数情况下,MHA FailOver 后,MHA Manager 监控进程也会关闭。所以很有必要再开启一个关于MHA Manager的保护进程。
背景知识
为简化MHA 配置,测试环境由一主一从一监控构成。

注意:主节点、辅助节点 之间 相互SSH 免密码登入。MHA Manger 到主、副节点之间 需要满足免密码登入(满足单向即可)

在主节点上虚拟出了 可读/写的IP;在从节点上虚拟出只读的IP。程序访问使用虚拟IP。
工具包主要功能
| 工具包 | 功能描述 |
| masterha_check_ssh | 检查MHA的SSH配置状况 |
| masterha_check_repl | 检查MySQL各节点复制状态 |
| masterha_manger | 开启 MHA Manager |
| masterha_check_status | 检测当前MHA Manager运行状态 |
| master_ip_failover | 自动切换时管理vip的脚本,主要是VIP的漂移。 |
| master_ip_online_change | 手动执行mysql master switchover时执行的切换脚本,含有管理vip的脚本 |
| masterha_master_switch | 控制故障转移(可手动) |
安装MHA Manager软件包后,路径/usr/local/bin上会出现以上工具包。
解决方案探究
脚本主要解决的问题

实现功能的文件及描述

主要文件mha_health_check_secondary.sh的处理逻辑

实现代码
文件mha_protect.sh的主要代码
########################################################################
# File Name: mha_protect.sh
# Excute: nohup sh mha_protect.sh &
# Created Time: Thu Jul EST
#########################################################################
#!/bin/sh
while true;
do
mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf | grep "stopped" | wc -l`
if [ "$mha_check_result" == "" ];then
echo "$mha_check_result"
sh /etc/masterha/mha_health_check_vip.sh > /etc/masterha/mhalog/MHA_Check_`date "+%Y%m%d%H%M%S"`.log >&
fi sleep
done
此文件中,调用MHA的配置文件的参数为 /etc/masterha/app1.conf。执行mha_health_check_secondary.sh产生的log位于路径 /etc/masterha/mhalog下面,文件以MHA_Check_时间命名。
文件mha_health_check_secondary.sh 中的主要代码
#!/bin/bash server1="172.XXX.XXX.XXX" ##此处请输入Server1的IP
server2="172.XXX.XXX.XXX" ##此处请输入Server2的IP
vip="172.XXX.XXX.XXX" ##此处请输入已配置的VIP
mysql_username=用户 ##此处数据用户名
mysql_password=密码 ## 此处输入用户名相应的密码 mha_conf=/etc/masterha/app1.conf
# Part:: String SQL
sql_change_master=""
mysql_status=""
slave_status=""
master_status="" #if has vip , master server ip
ipaddr1=`ssh root@"$server1" ip addr | grep "inet 172" | awk -F '[/]' '{print $1}' | awk '{print $2}' | grep "$vip"`
ipaddr2=`ssh root@"$server2" ip addr | grep "inet 172" | awk -F '[/]' '{print $1}' | awk '{print $2}' | grep "$vip"` ###此处应该添加一个判断当 ipaddr1 和 ipaddr2 都为 空时,说明,VIP设置有问题,退出需要告知管理员,去检查 if [ "$ipaddr1" = "$vip" ];then
masterip=$server1
echo masterip 在server1 $server1 上
fi
if [ "$ipaddr2" = "$vip" ];then
masterip=$server2
echo masterip 在server2 $server2 上
fi echo "master ip: $masterip" ## start ## 查看app1.conf mha 配置文件server的信息
conf_server1=`grep "server1" $mha_conf`
conf_server2=`grep "server2" $mha_conf` echo "conf_server1: $conf_server1 conf_server2 :$conf_server2 "
## end ## 查看app1.conf mha 配置文件server的信息 # 生成master mysql的[change master]SQL命令
sql_change_master="CHANGE MASTER TO MASTER_HOST='$masterip', MASTER_USER='$mysql_username', MASTER_PASSWORD='$mysql_password',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;" # --------------------------
# function # 对指定主机执行Linux命令
function do_linux_by_ssh() {
# variable
func_str_ip="$1"
func_str_user="$2"
func_str_command="$3"
# action
ssh $func_str_user@$func_str_ip "$func_str_command"
} function do_sql() {
# variable
func_str_ip="$1"
func_str_sql="$2"
# action
mysql -u $mysql_username -h $func_str_ip -p"$mysql_password" -e "$func_str_sql" -P3306
}
function mysql_stop_up() {
# 判断MySQL服务状态
# variable
func_str_ip="$1"
mysql_status=`do_linux_by_ssh "$func_str_ip" "root" "service mysqld status" | grep -c 'not running'`
if [ "$mysql_status" = ] ;then
do_linux_by_ssh "$func_str_ip" "root" "service mysqld start" > /dev/null
fi
sleep
mysql_status=`do_linux_by_ssh "$func_str_ip" "root" "service mysqld status" | grep -c 'running'`
echo ${mysql_status}
}
function mysql_slave_up() {
# variable
func_str_ip="$1"
slave_status=`do_sql "$func_str_ip" "show slave status \G;" > /dev/null | grep "Last_IO_Errno" | wc -l`
if [[ $slave_status == ]]
then
do_sql "$func_str_ip" "set global read_only=1;set global relay_log_purge=0;"
do_sql "$func_str_ip" "$sql_change_master"
do_sql "$func_str_ip" "start slave;"
fi
slave_status=`do_sql "$func_str_ip" "show slave status \G;" > /dev/null | grep "Last_IO_Errno: 0" | wc -l`
echo ${slave_status}
} ## MHA集群为2个数据节点,所以下面只循环判断server1、server2,同样如果是三个节点,则copy相关代码,修改if添加即可。 #if server1 down
if [ "$conf_server1" != "[server1]" ] ;then
#if myql status was dead , auto systemctl start mysqld
echo "check server1 mysql status start"
mysqlstatus=`mysql_stop_up "$server1"`
echo "server1 mysql status : $mysqlstatus"
if [ "$mysqlstatus" = ] ; then
echo "server1 slave up start"
slave_status=`mysql_slave_up "$server1"`
echo "server1 slave status :$slave_status server1: $server1"
if [ "$slave_status" = ] ; then
echo "write server1 app1.conf start"
echo -e "\n[server1]\nhostname=$server1\nport=3306" >> /etc/masterha/app1.conf
fi
mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf | grep "stopped" | wc -l`
if [ "$mha_check_result" = ] ;then
nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mhalog/manager.log >& & > /dev/null
fi
fi
fi
conf_server1=`grep "server1" /etc/masterha/app1.conf` #if server2 down
echo "$conf_server2":"$server2" if [ "$conf_server2" != "[server2]" ] ;then
#if server2 myql status was dead , auto systemctl start mysqld
echo "server2 mysql stop status start"
mysqlstatus=`mysql_stop_up "$server2"`
echo "server2 ysql_stop_up status: $mysqlstatus"
if [ "$mysqlstatus" = ] ; then
slave_satus=`mysql_slave_up "$server2"`
echo "server2 slave_status is : $slave_satus"
if [ "$slave_satus" = ] ; then
echo "write server2 in app1.conf start"
echo -e "\n[server2]\nhostname=$server2\nport=3306" >> /etc/masterha/app1.conf
fi
mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf | grep "stopped" | wc -l`
echo "$mha_check_result"
if [ "$mha_check_result" = ] ;then
nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mhalog/manager.log >& & > /dev/null
fi
fi
fi
conf_server2=`grep "server2" /etc/masterha/app1.conf` mha_check_result=`masterha_check_status --conf=/etc/masterha/app1.conf | grep "stopped" | wc -l`
if [ "$conf_server1" = "[server1]" ] && [ "$conf_server2" = "[server2]" ];then
if [ "$mha_check_result" = "" ];then
nohup masterha_manager --conf=/etc/masterha/app1.conf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/masterha/mhalog/manager.log >& & > /dev/null
fi
fi
此文件中,调用MHA的配置文件的参数为 /etc/masterha/app1.conf。
masterha_manager 监控所产生的log存放在 /etc/masterha/mhalog/manager.log 中。
感谢:以上代码实现主要是由同事Fly Chen完成。
本文版权归作者所有,未经作者同意不得转载,谢谢配合!!!
MySQL MHA FailOver后,原Master节点自动以Slave角色加入解群的研究与实现的更多相关文章
- 基于MySQL+MHA+Haproxy部署高可用负载均衡集群
一.MHA 概述 MHA(Master High Availability)是可以在MySQL上使用的一套高可用方案.所编写的语言为Perl 从名字上我们可以看到.MHA的目的就是为了维护Master ...
- 【线上测试之后的应用】基于MySQL+MHA+Haproxy构建高可用负载均衡数据库集群(详解)
这里我们先介绍一下MHA是什么,其次就是它的应用与测试,同时为了大家呈现了数据备份案例,最后总结了使用情况以及注意事项和解决办法 一.MHA 概述 MHA(Master High Availabili ...
- MySQL MHA 运行状态监控
一 项目描述 1.1 背景 MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了 automating master failover 功能.MHA ...
- kubeadm高可用master节点(三主两从)
1.安装要求 在开始之前,部署Kubernetes集群机器需要满足以下几个条件: 五台机器,操作系统 CentOS7.5+(mini) 硬件配置:2GBRAM,2vCPU+,硬盘30GB+ 集群中所有 ...
- 排查 k8s 集群 master 节点无法正常工作的问题
搭建的是 k8s 高可用集群,用了 3 台 master 节点,2 台 master 节点宕机后,仅剩的 1 台无法正常工作. 运行 kubectl get nodes 命令出现下面的错误 The c ...
- 记录一个奇葩的问题:k8s集群中master节点上部署一个单节点的nacos,导致master节点状态不在线
情况详细描述; k8s集群,一台master,两台worker 在master节点上部署一个单节点的nacos,导致master节点状态不在线(不论是否修改nacos的默认端口号都会导致master节 ...
- mysql mha 主从自动切换 高可用
mha(Master High Availability)目前在MySQL多服务器(超过二台),高可用方面是一个相对成熟的解决方案. 一,什么是mha,有什么特性 1. 主服务器的自动监控和故障转移 ...
- 本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动
重新安装MySQL数据库,由于安装的时候马虎,一路next(事实上,某些地方需要严格的配置,我忘记注意了),导致现在出了很多麻烦. 错误信息: 本地计算机上的MySQL服务启动后停止.某些服务在未由其 ...
- mysql57重新安装后无法再次启动mysql57服务“本地计算机上的MySQL服务启动后停止。某些服务在未由其他服务或程序使用时将自动。”--解决方法
本地计算机上的MySQL服务启动后停止.某些服务在未由其他服务或程序使用时将自动. (win10,mysql5.7+) 解决方法: 第一步:查看MySQL57安装路径 只要在programData路径 ...
随机推荐
- Jason Wang: 结对编程 CountWord(第三次作业)
本次作业地址: https://edu.cnblogs.com/campus/xnsy/SoftwareEngineeringClass1/homework/2882 学号: 201731072323 ...
- IO复用(较详细)
进程与线程的描述 一个进程至少会创建一个线程,多个线程共享一个程序进程的内存.程序的运行最终是靠线程来完成操作的.线程的数量跟CPU核数有关,一个核最多能发出两个线程.线程的操作主要分为:一:给CPU ...
- IntelliJ IDEA 自定义方法注解模板
最近没啥事开始正式用Eclipse 转入 idea工具阵营,毕竟有70%的开发者在使用idea开发,所以它的魅力可想而知.刚上手大概有一天,就知道它为啥取名为 intelli(智能化)了,确实很智能, ...
- python批量启动多线程
还未了解多线程的请查看博文 python3多线程趣味详解 python3多线程趣味详解 只是介绍了 python 多线程的使用,对于批量启动线程来说有些不适用,于是出现如下方法: 建立一个线程池,并将 ...
- Spring Boot Security
如图,是一种通用的用户权限模型.一般情况下会有5张表,分别是:用户表,角色表,权限表,用户角色关系表,角色权限对应表. 一般,资源分配时是基于角色的(即,资源访问权限赋给角色,用户通过角色进而拥有权限 ...
- redis 系列12 哈希对象
一. 哈希对象概述 Redis hash对象是一个string类型的field和value的映射表,hash特别适合用于存储对象.作为哈希对象的编码,有二种一是ziplist编码, 二是hashtab ...
- Android--SurfaceView播放视频
前言 本篇博客讲解一下如何在Android下,使用SurfaceView播放一个视频流媒体.之前有讲到如何使用MediaPlayer播放音频流媒体,其实MediaPlayer还可以播放视频,只需需要S ...
- Chapter 5 Blood Type——10
"What?" “什么?” "Your boyfriend seems to think I'm being unpleasant to you — he's debat ...
- 【ASP.NET Core快速入门】(十二)JWT 设计解析及定制
前言 上一节我们讲述的书如何使用jwt token,而且上一节的token是要加Authorization:bearer XXXXXXXXXXXX才能访问. 这一节我们来研究如何自定义类似jwt的to ...
- RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->新增记录SQL执行过程
有时我们需要记录整个系统运行的SQL以作分析,特别是在上线前这对我们做内部测试也非常有帮助,当然记录SQL的方法有很多,也可以使用三方的组件.3.2版本我们在框架底层新增了记录框架运行的所有SQl过程 ...