优秀的编程知识分享平台

网站首页 > 技术文章 正文

MySQL基于MHA的FailOver过程(mysql mha搭建)

nanyue 2024-08-16 00:37:05 技术文章 6 ℃

大家好,我是anyux。本文介绍MySQL基于MHA的FailOver过程。


MHA FailOver过程详解

什么是FailOver

故障转移

主库宕机,一直到业务恢复正常的处理过程


如何处理FailOver

1.快速监控到主库宕机

2.选择新主节点,选择策略 mysqladmin ping检查数据库状态,主机状态,端口等,判断从库节点读取的master_log_file及read_master_log_pos节点大小,查看Retrieved_gtid_set(已接收到的gtid大小),executed_gtid_set(已执行的gtid号大小)

3.数据补偿

4.解除从库身份

5.剩余从库和新主库构建主从关系

6.应用透明

7.修复故障主节点(k8s可以实现节点自愈)


MHA的Failover如何实现

从启动--->故障--->转移---->业务恢复

1.MHA通过master_manager脚本启动MHA功能

2.在manager启动之前,会自动调用检查ssh互信脚本(masterha_check_ssh)和主从状态检查脚本(masterha_check_repl)。如果检查脚本不通过MHA无法启动

3.MHA-manager 通过masterha_master_monitor脚本(每隔ping_interval秒)

4.masterha_master_monitor探测主库3次无心跳之后,主认为主库宕机了

5.进行选主过程

算法一:

读取配置文件中是否有强制选主的参数

candidate_master=1

check_repl_delay=0

算法二:

自动判断所有从库的日志量,将最接近主库数据的从库作为新主

算法三:

按照配置文件先后顺序,选择新主

6.数据补偿

判断主库ssh的连通性

情况一:ssh能够连接

调用save_binary_logs脚本,立即保存缺失部分的binlog到各个节点,恢复

情况二:ssh法连接

调用 apply_diff_relay_logs 脚本,计算从库的relaylog差异,恢复到2号从库

提供额外的数据补偿功能

解除从库身份

剩余从库和主库构建主从关系

应用透明

故障节点自愈

故障提醒


MHA应用透明(vip)

$vip是一个未被占用的地址,将来可实现地址飘移的,需要自己按情况调整

$brdc是广播地址,按自身网络情况调整

$ifdev是网卡名称,设置为自己实际的网卡名称

$ssh_start_vip是添加vip功能的

$ssh_stop_vip是关闭vip功能的

 #############################添加内容部分#########################################
 my $vip = '192.168.255.200';
 my $brdc = '192.168.255.255';
 my $ifdev = 'ens33';
 my $key = '1';
 my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
 my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
 ##################################################################################


复制下面代码到db115主机下的 /usr/local/bin/master_ip_failover文件中

 #!/usr/bin/env perl
 use strict;
 use warnings FATAL => 'all';
 
 use Getopt::Long;
 
 my (
 $command, $ssh_user, $orig_master_host, $orig_master_ip,
 $orig_master_port, $new_master_host, $new_master_ip, $new_master_port
 );
 #############################添加内容部分#########################################
 my $vip = '192.168.255.200';
 my $brdc = '192.168.255.255';
 my $ifdev = 'ens33';
 my $key = '1';
 my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
 my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
 ##################################################################################
 GetOptions(
 'command=s' => \$command,
 'ssh_user=s' => \$ssh_user,
 'orig_master_host=s' => \$orig_master_host,
 'orig_master_ip=s' => \$orig_master_ip,
 'orig_master_port=i' => \$orig_master_port,
 'new_master_host=s' => \$new_master_host,
 'new_master_ip=s' => \$new_master_ip,
 'new_master_port=i' => \$new_master_port,
 );
 
 exit &main();
 
 sub main {
 
 print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
 
 if ( $command eq "stop" || $command eq "stopssh" ) {
 
 my $exit_code = 1;
 eval {
 print "Disabling the VIP on old master: $orig_master_host \n";
 &stop_vip();
 $exit_code = 0;
 };
 if ($@) {
 warn "Got Error: $@\n";
 exit $exit_code;
 }
 exit $exit_code;
 }
 elsif ( $command eq "start" ) {
 
 my $exit_code = 10;
 eval {
 print "Enabling the VIP - $vip on the new master - $new_master_host \n";
 &start_vip();
 $exit_code = 0;
 };
 if ($@) {
 warn $@;
 exit $exit_code;
 }
 exit $exit_code;
 }
 elsif ( $command eq "status" ) {
 print "Checking the Status of the script.. OK \n";
 exit 0;
 }
 else {
 &usage();
 exit 1;
 }
 }
 sub start_vip() {
 `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
 }
 # A simple system call that disable the VIP on the old_master
 sub stop_vip() {
 `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
 }
 
 sub usage {
 print
 "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
 }
 


字符转换

 yum install -y dos2unix
 cd /usr/local/bin/
 dos2unix master_ip_failover


添加执行权限

 chmod +x /usr/local/bin/master_ip_failover


编辑配置文件

 vim /etc/mha/app1.cnf
 [server default]
 master_ip_failover_script=/usr/local/bin/master_ip_failover


检查主库

 masterha_check_status --conf=/etc/mha/app1.cnf


db01手工添加vip

 yum install -y net-tools
 ifconfig ens33:1 192.168.255.200/24
 ip a | grep 200


db03重启mha


主从状态检查

 masterha_check_repl  --conf=/etc/mha/app1.cnf 
 返回ok


检查mha状态

 masterha_check_status --conf=/etc/mha/app1.cnf


先关闭mha

 masterha_stop ---conf=/etc/mha/app1.cnf

启动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 &


MHA故障邮箱提醒

安装邮件

 yum -y install sendmail
 yum -y install mailx
 

编辑配置文件,此次是使用163邮箱,需要获取授权码

 vim /etc/mail.rc
 
 set from=xxxx@163.com
 set smtp=smtp.163.com
 set smtp-auth-user=xxxx@163.com
 set smtp-auth-password=xxxxx
 set smtp-auth=login

测试验证

将xxxx替换为自己的邮箱地址

前面是内容主体,-s 后面的参数,是邮件标题

 echo "你好,先生" | mail -s "你好,请阅读此文件" xxxx@xxxx.com


MHA是一次性的高可用服务,即数据库如果宕机,mha就不再工作了,也会自动宕机

当mha出现时,我们可以使用send_report以邮件报警的方式来获得错误信息数据,方便了解数据库状态。

将发送邮件的脚本内容复制到send_report文件中

 cd /usr/local/bin
 vim send_report

脚本内容如下:

 #!/bin/bash
 echo "你好,先生,数据库宕机了" | mail -s "数据库宕机了,请登录系统查看mha状态" 1915530614@qq.com


添加执行权限

 chmod +x send_report


然后修改配置文件,只需添加report_script即可

 vim /etc/mha/app1.cnf
 [server default]
 report_script=/usr/local/bin/send_report  


重启mha

先关闭mha

 masterha_stop --conf=/etc/mha/app1.cnf

启动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 &

检查mha状态

 masterha_check_status --conf=/etc/mha/app1.cnf


额外的数据补偿(binlog_server)

实时地接收主库的数据,将数据保存到其他地区的机器上,可以理解为异地备份

找到一台额外机器,数据库版本大于5.6,支持gtid并开启

在db03上配置

no_master:表示不参与选主

hostname:设置ip地址

master_binlog_dir:新机器接收的二进制日志存放位置

 vim /etc/mha/app1.cnf
 [binlog1]
 no_master=1
 hostname=192.168.255.116
 master_binlog_dir=/data/mysql/binlog

创建必要目录

 mkdir -p /data/mysql/binlog
 chown -R mysql.mysql /data/*


修改完成后,将主库binlog接过来(从000001开始拉取,之后的binlog会自动按顺序过来)

拉取主库binlog日志

必须进入到自己创建好的目录

 cd /data/mysql/binlog
 mysqlbinlog -R --host=192.168.255.113 --user=mha --password=mha --raw --stop-never log-bin.000001 &

注意:

拉取日志的起点,需要按照目前从库的已经获得的二进制日志为起点


重启mha

先关闭mha

 masterha_stop ---conf=/etc/mha/app1.cnf

启动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 &


故障模拟及故障处理

关闭db01数据库

 systemctl stop mysqld


获取邮箱告警信息

恢复故障

启动故障节点

 systemctl start mysqld


恢复1主2从环境

在db115管理节点获取恢复节点信息

 grep -i "change master" /var/log/mha/app1/manager

登录db01将日志的语句修改密码后,在db01环境下执行即可

 CHANGE MASTER TO MASTER_HOST='192.168.255.114', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl'

启动从库

 start slave;


恢复db115上的配置文件

重新添加server1节点信息

 [server1]                                   
 hostname=192.168.255.113
 port=3306          


启动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 &

检查mha状态

 masterha_check_status --conf=/etc/mha/app1.cnf


恢复binlogServer

必须进入到自己创建好的目录

 cd /data/mysql/binlog
 rm -rf /data/mysql/binlog/*
 mysqlbinlog -R --host=192.168.255.11x --user=mha --password=mha --raw --stop-never log-bin.000001 &

注意:

log-bin.000001需要按照实现情况获取

?

最近发表
标签列表