MySQL高可用架构全面解析:MHA原理、部署与运维实践(九)

本文深入解析MySQL高可用架构的核心解决方案------MHA(Master High Availability)的完整技术体系。全面介绍MHA的高可用原理、组件架构、部署配置、故障切换机制、数据补偿策略以及运维管理实践。详细阐述MHA如何实现0-30秒内自动完成数据库故障切换,并最大限度地保证数据一致性。涵盖从基础环境搭建、VIP透明切换、故障报警到高级维护操作的全流程,为构建生产级MySQL高可用架构提供完整解决方案。

1.高可用概述

数据库中的高可用功能,主要是用于避免数据库服务或数据信息的损坏问题,其中数据损坏的类型有:

  • 数据物理损坏:磁盘、主机、程序实例、数据文件误删除
  • 数据逻辑损坏:drop update ...

数据库高可用解决方案选型依据:(全年无故障率)

无故障率 故障时间 解决方案
99.9% 0.1%(525.6min) keepalived+双主架构,但需要人为干预
99.99% 0.01%(52.56min) MHA ORCH TMHA,具有自动监控,自动切换,自动数据补偿,但还是属于半自动化 比较适合非金融类互联网公司 eg: facebook taobao前端-TMHA-->polaradb
99.999% 0.001%(5.256min) PXC MGR MGC,数据是高一致性 比较适合金融类互联网公司
99.9999% 0.0001%(0.5256min) 自动化、云计算化、平台化,仍然属于概念阶段

2.MHA概述

HA(Master High Availability)目前在MySQL高可用方面是一个相对成熟的解决方案,它由日本DeNA公司youshimaton研发,此人目前就职于Facebook公司,MHA是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件;

MySQL进行故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换过程中;

MHA能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

MHA Manager(管理节点)

MHA Manager 会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master;

然后将所有其他的slave重新指向新的master,整个故障转移过程对应用程序是完全透明的;

MHA Node(数据节点)

运行在每台MySQL服务器上

节点信息 软件组件 作用介绍
MHA Manager(管理节点) masterha_manger 用于启动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信息
MHA Node(数据节点) save_binary_logs 保存和复制master的二进制日志
apply_diff_relay_logs 识别差异的中继日志事件并将其差异的事件应用于其他slave
purge_relay_logs 清除中继日志(不会阻塞SQL线程)

3.MHA高可用环境搭建

3.1 MHA高可用架构基础环境

db01、db02、db03

sh 复制代码
#对原有数据库服务环境清理:(基于GTID环境构建)
#所有节点均进行清理操作
[root@db03 ~]# pkill mysqld
[root@db03 ~]# rm -rf /data/3306/*
[root@db03 ~]# chown -R mysql.mysql /data/*

# 主库db01配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=51
port=3306
secure-file-priv=/tmp
#log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db01 [\\d]>
EOF

# 从库db02配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=52
port=3306
secure-file-priv=/tmp
#log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db02 [\\d]>
EOF

# 从库db03配置文件编写
cat >/etc/my.cnf <<EOF
[mysqld]
basedir=/usr/local/mysql
datadir=/data/3306/data
socket=/tmp/mysql.sock
server_id=53
port=3306
secure-file-priv=/tmp
#log_bin=/data/binlog/mysql-bin
binlog_format=row
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
[mysql]
prompt=db03 [\\d]>
EOF

# 所有节点初始化数据库操作
[root@db02 ~]# mysqld --initialize-insecure --user=mysql --basedir=/usr/local/mysql --datadir=/data/3306/data
[root@db03 ~]#  /etc/init.d/mysqld start

# 重构主从关系-主库操作(db01)
db01 [(none)]>create user repl@'10.0.0.%' identified with mysql_native_password by '12366';
db01 [(none)]>grant replication slave on *.* to repl@'10.0.0.%';
-- 主库上创建主从复制用户信息

# 重构主从关系-从库操作(db01、db02)
db02 [(none)]>change master to
master_host='10.0.0.51',
master_user='repl',
master_password='12366',
master_auto_position=1;
-- 表示让从库自己找寻复制同步数据的起点;
-- 在第一次启动gtid功能时,会读取从库中的binlog日志信息,根据主库uuid信息,获取从库中执行过的主库gtid信息
-- 从从库中没有执行过的主库gtid信息之后进行进行数据同步操作
db02 [(none)]> start slave;
3.2 MHA高可用软件安装部署
sh 复制代码
1. 创建命令软连接(所有节点)
#MHA程序加载数据库命令,会默认在/usr/bin下面进行加载(会影响数据补偿和监控功能)
[root@db01 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/mysqlbinlog
[root@db01 ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql

2. 配置各节点互信
[root@db01 ~]# rm -rf /root/.ssh 
[root@db01 ~]# ssh-keygen
[root@db01 ~]# cd /root/.ssh 
[root@db01 .ssh]# mv id_rsa.pub authorized_keys
[root@db01 .ssh]#  scp  -r  /root/.ssh  10.0.0.52:/root 
[root@db01 .ssh]#  scp  -r  /root/.ssh  10.0.0.53:/root 

3. 安装mha软件程序 
#安装包下载
https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
#所有节点安装
[root@db01 ~]# yum install perl-DBD-MySQL -y
[root@db01 ~]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm 

#Manager软件安装(db03)
安装包下载:https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
[root@db03 ~]# yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
[root@db03 ~]# yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

4.创建mha用户(db01)
# 在db01主库中创建mha需要的用户
db01 [(none)]>create user mha@'10.0.0.%' identified with mysql_native_password by 'mha';
db01 [(none)]>grant all privileges on *.* to mha@'10.0.0.%';
-- 在主库创建完毕后,主从复制功能,核实所有从库也都有mha用户信息
db03 [(none)]>select user,host from mysql.user;

5. Manager配置文件准备(db03)
#创建配置文件目录
[root@db03 ~]# mkdir -p /etc/mha
# 创建日志目录
[root@db03 ~]# mkdir -p /var/log/mha/app1

#编辑配置文件
[root@db03 ~]# cat > /etc/mha/app1.cnf <<EOF
[server default]
manager_log=/var/log/mha/app1/manager         
-- MHA的工作日志设置
manager_workdir=/var/log/mha/app1             
-- MHA的工作目录        
master_binlog_dir=/data/binlog                
-- 主库的binlog目录
user=mha                                      
-- 监控用户,利用此用户连接各个节点,做心跳检测(主要是检测主库的状态)                      
password=mha                                  
-- 监控密码
ping_interval=2                              
-- 心跳检测的间隔时间
repl_password=12366                             
-- 复制密码
repl_user=repl                                
-- 复制用户(用于告知从节点通过新主同步数据信息的用户信息)
ssh_user=root                                
-- ssh互信的用户(可以利用互信用户从主库scp获取binlog日志信息,便于从库进行数据信息补偿)
[server1]                                     
-- 节点信息....
hostname=10.0.0.51
port=3306                                  
[server2]            
hostname=10.0.0.52
port=3306
candidate_master=1
[server3]
hostname=10.0.0.53
port=3306
EOF

6. MHA状态检查(db03)
#在MHA管理节点,进行ssh互信功能检查,并且显示成功表示检查通过
[root@db03 ~]# masterha_check_ssh   --conf=/etc/mha/app1.cnf 
...
Thu Oct 12 21:31:21 2023 - [info] All SSH connection tests passed successfully.
#在MHA管理节点,检查主从关系与配置文件信息是否正确
[root@db03 ~]# masterha_check_repl  --conf=/etc/mha/app1.cnf
...
MySQL Replication Health is OK.

7.开启MHA-manager、查看MHA状态
[root@db03 ~]# 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 &
[1] 3003

#查看MHA状态
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:3003) is running(0:PING_OK), master:10.0.0.51
--显示以上提示信息,表示MHA基础环境搭建成功了,但还不能在生产环境使用,还需要有后续的操作配置

4.数据库高可用工作原理

4.1 高可用架构作用
  • 实现高可用的监控需求
  • 实现高可用的选主功能(并且选择数据量越接近主库的从库成为新主)
  • 实现高可用的数据补偿
  • 实现高可用的应用透明(VIP)
  • 实现高可用的报警功能
  • 实现高可用的额外补偿
  • 实现高可用的自愈功能
4.2 MHA的设计原理分析(Failover 过程)
01 MHA软件启动

根据启动命令,分析MHA软件启动原理:

sh 复制代码
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 &

<   输入重定向 将有交互的脚本输入到/dev/null,不至于卡住
  • 启动时,先调取MHA启动脚本文件masterha_manager ,然后再调取加载MHA软件的配置文件--conf=.../app1.cnf

  • 根据加载的MHA的配置文件不同,实现管理多个高可用架构环境,进行高可用业务的架构环境的区分;

  • --remove_dead_master_conf参数表示在主节点出现宕机情况时,将会从集群中被踢出,即从配置文件中删除掉故障节点;

  • --ignore_last_failover 默认MHA服务是不能频繁进行故障切换的,需要有一定的间隔时间,加此参数表示忽略切换的间隔时间;

  • 最后将MHA启动运行的信息放入到日志文件中即可 /var/log/mha/app1/manager.log 2>&1

02 MHA实现监控
  • 利用MHA启动脚本文件masterha_manager会自动调用监控脚本文件masterha_master_monitor,可以实现连接数据库执行SQL语句,并且每隔配置文件指定时间;
  • ping_interval=2 进行脚本监控一次,从而判断主节点是否处于存活状态,连续4次还没有主库心跳,即说明主库宕机;
sh 复制代码
# 监控脚本验证主节点存活方法
[root@db03 ~]# mysql -umha -pmha -h10.0.0.51 -e "select user();"
+---------------+
| user()        |
+---------------+
| mha@10.0.0.53 |
+---------------+
03 MHA从库选主过程

利用masterha_master_switch实现选主和切换;

利用四个数组(存活、数据量最接近、备选数组-candidate_master、不选数组)获取从节点信息

根据一定选举原则,进行主节点的选举

  • 在MHA中进行选主时,根据选主源码文件信息分析,主要会利用到四个数组:alive latest pref bad,并且会识别节点编号信息;

  • 在进行选主时,主要会关注竞选新主节点的日志量、以及是否设置candidate_master参数配置信息;

数组信息 简述 作用说明
alive 存活数组 主要用于探测存活的节点状态;当主库宕机后,探测的就是两个从库节点
latest 最新数组 表示获取日志最新的从库信息,即数据量最接近主库的从库(根据GTID信息 或 position信息)
pref 备选数组 在数组中具有candidate_master参数判断条件,此参数可以放入配置文件节点中,便于节点优先选择为新主
bad 不选数组 如果设定了参数:no_master=1,表示相应节点不参与竞选主; 如果设定了参数:log_bin=0(二进制日志没开),表示相应节点不参与竞选主; 如何设定了参数:check_slave_delay,检查从库延迟主库100M数据信息日志量,表示节点不参与竞选主

MHA选主判断总结(利用if判断选主的情况)

  • 循环对比latest数组和pref数组的slave,如果存在相同的slave,并且这个slave不在bad数组当中,该slave会被推选为新的master

    DB02节点即满足latest数组信息,又满足perf数组信息,但不满足bad数据信息,即会被选为新主,有多个按照号码顺序选举;

  • 如果pref和bad数组当中的个数为0,则选择latest数组当中的第一个slave为master;

    DB02节点没有candidate_master参数配置,又没有不选数组里的三种情况配置,即db02恰好是latest,为新主;

  • 循环对比alive数组和pref数组当中的slaves,如果有一个slave相同,并且不在bad数组当中,该节点就会成为新的master;

    DB02节点即不满足latest,也不满足bad,但是满足pref,也会被选择作为新主;

  • 循环latest数组,如果又循环到slave不在bad数组当中,这个slave就会成为master,就算添加了candidate_master=1参数;

    该slave也不一定会成为主库;

    DB02节点即满足latest数组,不是bad数组,也会成为新的主;

  • 从活着的slave当中进行循环,如果循环到slave不在bad数组当中,那么这个slave就会成为主库;

    DB02节点是活着的,不满足bad,也可以成为新的主;

  • 如果进行了多次选择都找不到主库,那么主库选择失败,failover失败;

选主策略简述表:

优先级 alive数组 latest数组 pref数组 bad数组 选主策略 多个选择情况
01 满足 满足 满足 不满足 优选选择 按照节点号码顺序选择
02 满足 满足 不满足 不满足 优选选择 按照节点号码顺序选择
03 满足 不满足 满足 不满足 优选选择 按照节点号码顺序选择
04 满足 不满足 不满足 不满足 优选活着节点 按照节点号码顺序选择

说明:在进行手工指定切换新主时,即应用了prio_new_master_host参数信息时,会最优先选择相应节点为新主;

04 MHA数据补偿

在进行数据补偿之前,需要让新主库与原有宕机主库进行对比,获悉需要补偿的数据量情况,即对比差的数据日志量信息;

然后可以从binlog日志中,进行补充数据信息的截取,随之进行数据信息补偿,但是有种特殊情况,原有主库无法访问了;

所以进行数据补偿操作,也需要分各种情景进行处理:

  • 原主库SSH连接正常:

    各个从节点自动调用主节点:save_binary_logs脚本文件,立即保存缺失部分的bin_log,到各节点/var/tmp/目录;

  • 原主库SSH连接异常:

    各个从节点相互自动调用:apply_diff_relay_logs脚本文件,进行relay_log日志差异信息补偿;

  • 额外特殊数据补充:(利用主库日志冗余机制)

    MHA提供了binlog_server功能,可以实时拉取主库的binlog日志到备份节点,从而进行数据额外补偿;

05 MHA应用透明(VIP)

实现MHA的VIP功能,利用脚本实现,上传mha_script.tar文件到/usr/local/bin目录中,然后进行解压处理。

sh 复制代码
1. 上传MHA脚本
[root@db03 ~]#  cd /usr/local/bin/
[root@db03 bin]# chmod +x /usr/local/bin/*
[root@db03 bin]#  dos2unix /usr/local/bin/*
[root@db03 bin]# ll
total 28
-rwxr-xr-x 1 root root   581 Aug 23 22:21 app1.cnf
-rwxr-xr-x 1 root root  2230 Aug 23 22:21 master_ip_failover
-rwxr-xr-x 1 root root 10312 Aug 23 22:21 master_ip_online_change
-rwxr-xr-x 1 root root   789 Aug 23 22:21 mha_check.sh
-rwxr-xr-x 1 root root  2238 Aug 23 22:21 send_report

2. 修改脚本信息
#MHA脚本文件的信息 VIP漂移信息
[root@db03 bin]# vim master_ip_failover
my $vip = '10.0.0.50/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.0.50";

3. 修改配置文件
#配置文件中添加VIP漂移参数
[root@db03 bin]# vim /etc/mha/app1.cnf
master_ip_failover_script=/usr/local/bin/master_ip_failover

4 .重启MHA服务
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 ~]#  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. 手工在主库上添加VIP(第一次启动需要手工添加)
#核实此时的MHA的主库节点
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:5946) is running(0:PING_OK), master:10.0.0.51
#在主库节点手工添加vip地址信息
[root@db01 ~]# ifconfig eth0:1 10.0.0.50/24
[root@db01 ~]# ip a
#进行VIP地址连接测试
[root@db02 ~]# mysql -urepl -p12366 -h10.0.0.50

说明:进行MHA的VIP地址漂移时,只能在局域网环境进行漂移,不能实现跨网段的VIP地址漂移;

06 MHA故障报警

实现MHA的报警功能,利用脚本实现

sh 复制代码
1. 编写脚本
[root@db03 bin]# vim send_report 
my $smtp='smtp.qq.com';
my $mail_from='1573374330@qq.com';
my $mail_user='1573374330';
my $mail_pass='xppiwvswtotnhggf';
#my $mail_to=['to1@qq.com','to2@qq.com'];
my $mail_to='1573374330@qq.com';

2. 修改配置文件
#发送邮件配置到mha中
[root@db03 bin]# vim /etc/mha/app1.cnf
report_script=/usr/local/bin/send_report

3 .重启MHA服务
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 ~]#  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 &
07 MHA额外补偿

利用binlog_server作为额外的日志补偿的冗余方案,即实时保存主库的bin_log日志文件到特定节点目录中;

sh 复制代码
1. 创建日志存放目录
[root@db03 ~]# mkdir -p /data/binlog_server/
[root@db03 ~]# chown -R mysql.mysql /data/*
[root@db03 ~]# cd /data/binlog_server
[root@db03 binlog_server]# mysql -e "show slave status\G"|grep "Master_Log"
              Master_Log_File: binlog.000001
          Read_Master_Log_Pos: 1185
        Relay_Master_Log_File: binlog.000001
          Exec_Master_Log_Pos: 1185
2. 将主节点日志实时保存到db03服务器中的binlog_server目录
[root@db03 binlog_server]# mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never binlog.000001 &
[2] 6669
[root@db03 binlog_server]# ps -ef |grep mysqlbinlog
root       6669   5720  0 23:10 pts/2    00:00:00 mysqlbinlog -R --host=10.0.0.51 --user=mha --password=x x --raw --stop-never binlog.000001
[root@db03 binlog_server]# ll
total 4
-rw-r----- 1 root root 1185 Oct 12 23:10 binlog.000001

3. 编写配置文件信息
[root@db03 ~]# vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/binlog_server/

[binlog1]
no_master=1  #不存于竞选
hostname=10.0.0.53  #将日志额外补偿到哪个主机上
master_binlog_dir=/data/binlog_server/   #日志额外补偿的存储目录

4 .重启MHA服务
[root@db03 ~]# masterha_stop --conf=/etc/mha/app1.cnf
[root@db03 ~]#  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.数据库高可用故障切换

5.1 故障模拟

模拟进行指定主库节点故障情况,检查核实MHA相应功能脚本是否能够正确运行

sh 复制代码
# 确认目前的MHA的状态是良好的
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:6828) is running(0:PING_OK), master:10.0.0.51

# 模拟DB01数据库节点宕机
[root@db01 ~]# /etc/init.d/mysqld stop
Shutting down MySQL........... SUCCESS!

# 监控DB03日志信息的变化
[root@db03 ~]# tail -f /var/log/mha/app1/manager
5.2 实现MHA高可用切换
01 健康检查异常

MHA健康检查报错,显示主数据库节点无法正常连接

sh 复制代码
# 日志信息分析
[waring] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '10.0.0.51' (111))
[waring] Connection failed 2 time(s)..
[waring] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '10.0.0.51' (111))
[waring] Connection failed 3 time(s)..
[waring] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '10.0.0.51' (111))
[waring] Connection failed 4 time(s)..
[waring] Master is not reachable from health checker!
[waring] Master 10.0.0.51(10.0.0.51:3306) is not reachable!
-- 对故障主节点进行4次健康检查,主节点数据库服务仍旧无法连接,即判定主节点故障
02 MHA重新选主

MHA进行重新选主,根据数组信息选择合适的备用新主节点

sh 复制代码
[info] Connecting to a master server failed. Reading configuration file /etc/masterha_default.cnf and /etc/mha/app1.cnf again, and trying to connect to all servers to check server status..
[info] Reading application default configuration from /etc/mha/app1.cnf
....
[info] Starting master failover
....
[info] ** Phase 1: Configuration Check Phase completed.
03 MHA节点关闭

MHA进行节点关闭,选择完新的主节点后会将原有主节点的VIP地址消除

tiki 复制代码
[info] * Phase 2: Dead Master Shutdown Phase..
[info] Forcing shutdown so that applications never connect to the current master..
Disabling the VIP on old master: 10.0.0.51
04 MHA节点切换

MHA进行节点切换,在新的主节点上进行非同步数据信息的补偿,

sh 复制代码
[info] * Phase 3: Master Recovery Phase..
[info] * Phase 3.1: Getting Latest Slaves Phase..
....
[info] * Phase 3.3: Determining New Master Phase..
[info] New master is 10.0.0.52(10.0.0.52:3306)
[info] Starting master failover..
[info] * Phase 3.3: New Master Recovery Phase..
[info] Executing binlog save command: save_binary_logs --command=save --start_file=mysql-bin.000002  --start_pos=1201 --output_file=/var/tmp/saved_binlog_binlog1_20230102153233.binlog --handle_raw_binlog=0 --skip_filter=1 --disable_log_bin=0 --manager_version=0.58 --oldest_version=8.0.26  --binlog_dir=/data/binlog_server/
[info] Additional events were not found from the binlog server. No need to save.
Enabling the VIP - 10.0.0.50/24 on the new master - 10.0.0.52
Mon Jan  2 15:32:36 2023 - [info]  OK.
Mon Jan  2 15:32:36 2023 - [info] ** Finished master recovery successfully.
[info] * Phase 3: Master Recovery Phase completed.
05 主从重构

MHA进行主从重构,将从库连接到新的主库上

sh 复制代码
[info] * Phase 4: Slaves Recovery Phase..
[info] * Phase 4.1: Starting Slaves in parallel..
[info]  Resetting slave 10.0.0.53(10.0.0.53:3306) and starting replication from the new master 10.0.0.52(10.0.0.52:3306)..
[info]  Executed CHANGE MASTER.
[info]  Slave started.
[info]  All new slave servers recovered successfully.
06 MHA切换完毕

MHA切换完毕过程,架构故障转移切换完毕后做清理阶段,并进行最终汇报

sh 复制代码
[info] * Phase 5: New master cleanup phase..
----- Failover Report -----
Master failover to 10.0.0.52(10.0.0.52:3306) completed successfully.
Mon Jan  2 15:32:37 2023 - [info] Sending mail..
07 切换完成结果查看
sh 复制代码
1. VIP已成功漂移到db02
[root@db01 ~]# ip a |grep 10.0.0.50
[root@db01 ~]# 
[root@db02 ~]# ip a |grep 10.0.0.50
    inet 10.0.0.50/24 brd 10.0.0.255 scope global secondary eth0:1

2. 核实主从关系
[root@db03 ~]# mysql -e "show slave status\G"
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.0.0.52
                  Master_User: repl
                  Master_Port: 3306
3. 查看MHA配置文件信息
[root@db03 ~]# cat /etc/mha/app1.cnf
[binlog1]
hostname=10.0.0.53
master_binlog_dir=/data/binlog_server/
no_master=1

[server default]
manager_log=/var/log/mha/app1/manager
manager_workdir=/var/log/mha/app1
master_binlog_dir=/data/binlog
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=mha
ping_interval=2
repl_password=12366
repl_user=repl
report_script=/usr/local/bin/send_report
ssh_user=root
user=mha

[server2]
candidate_master=1
hostname=10.0.0.52
port=3306

[server3]
hostname=10.0.0.53
port=3306

--故障节点db01信息已从配置文件中清理

4. MHA程序已终止
[root@db03 ~]# ps -ef|grep mha
root       6994   5720  0 23:35 pts/2    00:00:00 grep --color=auto mha
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 is stopped(2:NOT_RUNNING).

6.数据库高可用修复方法

MHA故障通用修复方法步骤:(前提是MHA进行正常故障切换,通过日志可以检查是否进行正常的故障转移)

6.1 检查节点状态
sh 复制代码
# 检查节点数据库运行状态
[root@db01 ~]#  /etc/init.d/mysqld status
 ERROR! MySQL is not running
[root@db01 ~]#  /etc/init.d/mysqld start
Starting MySQL.. SUCCESS! 
-- 恢复DB01异常数据库服务节点

在实际生产环境中,如果主库异常无法实现重新启动修复,可能就需要准备一台新的节点主机,重新构建1主2从的架构;

但是如果使用新的节点主机,进行主从架构重构,修复高可用环境,就需要考虑新主机的在恢复数据的时间损耗;

总之,需要将新节点的数据信息进行同步后,再将新节点变为新的从库,从而修复高可用主从关系,具体如何修复数据需要考虑实际情况

6.2 检查、修复主从关系
sh 复制代码
1. 确认切换后的新主库信息
[root@db03 ~]# mysql -e "show slave status\G"|grep "Master_Host"
                  Master_Host: 10.0.0.52

2. db01上修复主从
db01 [(none)]>change master to
master_host='10.0.0.52',
master_user='repl',
master_password='12366',
master_auto_position=1;
db01 [(none)]>start slave;
db01 [(none)]>show slave status\G;

3. 核实主从关系
[root@db01 ~]# mysql -e "show slave status\G"|grep "Master_Host"
                  Master_Host: 10.0.0.52
6.3 master节点检查VIP漂移地址
sh 复制代码
[root@db02 ~]# ip a |grep 10.0.0.50
    inet 10.0.0.50/24 brd 10.0.0.255 scope global secondary eth0:1

--若漂移VIP失败,则可以手工设置
ifconfig eth0:1 10.0.0.50/24
6.4 恢复日志同步
sh 复制代码
[root@db03 ~]# ps -ef|grep mysqlbinlog
-- binlog_server日志同步进程消失

#修复binlog_server状态
[root@db03 ~]# rm -rf /data/binlog_server/*
[root@db03 ~]# cd /data/binlog_server/
[root@db03 binlog_server]# mysql -e "show slave status\G"|grep "Master_Log"
              Master_Log_File: binlog.000001
          Read_Master_Log_Pos: 1213
        Relay_Master_Log_File: binlog.000001
          Exec_Master_Log_Pos: 1213
[root@db03 binlog_server]#  mysqlbinlog -R --host=10.0.0.52 --user=mha --password=mha --raw --stop-never binlog.000001 &
[1] 7031
[root@db03 binlog_server]# ll
total 4
-rw-r----- 1 root root 1213 Oct 12 23:53 binlog.000001
6.5 调整配置文件
sh 复制代码
1.添加DB01故障节点到配置文件中
[root@db03 binlog_server]# masterha_conf_host --command=add --conf=/etc/mha/app1.cnf --hostname=10.0.0.51 --block=server1 --params="port=3306"
[root@db03 binlog_server]# cat /etc/mha/app1.cnf 
...
[server1]
hostname=10.0.0.51
port=3306
...

#利用命令脚本删除指定的节点信息
[root@liux-03 ~]# masterha_conf_host --command=delete --conf=/etc/mha/app1.cnf --block=server1 
6.6 核实互信情况
sh 复制代码
[root@db03 binlog_server]# masterha_check_ssh --conf=/etc/mha/app1.cnf
[root@db03 binlog_server]# masterha_check_repl --conf=/etc/mha/app1.cnf
6.7 恢复启动MHA
sh 复制代码
[root@db03 binlog_server]# 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 &
[2] 7152
[root@db03 binlog_server]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:7152) is running(0:PING_OK), master:10.0.0.52

7.数据库高可用维护操作

7.1 实现MHA高可用主节点在线切换(手工操作)

可以在主库没有故障的情况下,利用手工方式将主库业务切换到其它的从库节点上,从而解放原有主库节点(维护性操作时应用);

sh 复制代码
1.关闭MHA服务程序
[root@db03 binlog_server]# masterha_stop --conf=/etc/mha/app1.cnf
-- 关闭mha程序是保证手工切换时,不会受到mha自动切换的影响

2. 执行MHA手工切换
[root@db03 ~]#masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.0.0.51 --orig_master_is_new_slave --running_updates_limit=10000
...
It is better to execute FLUSH NO_WRITE_TO_BINLOG TABLES on the master before switching. Is it ok to execute on 10.0.0.52(10.0.0.52:3306)? (YES/no):
-- 以上说明信息,表示在进行切换之前,在原有主库节点执行FLUSH NO_WRITE_TO_BINLOG TABLES这个命令
-- 此命令表示,关闭所有打开的表,强制关闭所有正在使用的表,不写入binlog;
-- 因为此时VIP还没有漂移,表示禁止原主库继续写入数据信息
#关闭原主库的写入功能
db02 [(none)]>FLUSH NO_WRITE_TO_BINLOG TABLES ;

Is it ok to execute on 10.0.0.52(10.0.0.52:3306)? (YES/no):YES
Starting master switch from 10.0.0.52(10.0.0.52:3306) to 10.0.0.51(10.0.0.51:3306)? (yes/NO): yes

master_ip_online_change_script is not defined. If you do not disable writes on the current master manually, applications keep writing on the current master. Is it ok to proceed? (yes/NO):
--出现master_ip_online_change_script is not defined时,提示没有配置在线漂移VIP脚本,停止下一步操作
3. 编写MHA手工切换脚本文件master_ip_online_change_script功能脚本
#此脚本可以在线进行切换时,自动锁定原主库,以及将原主库VIP地址进行自动飘移
[root@db03 ~]# cd /usr/local/bin/
[root@db03 bin]# vim master_ip_online_change 
...
###########################################################################
my $vip = "10.0.0.50";
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key $vip down";
my $ssh_Bcast_arp= "/sbin/arping -I eth0 -c 3 -A 10.0.0.50";
###########################################################################
...

4. 修改MHA服务程序配置文件
[root@db03 ~]# vim /etc/mha/app1.cnf
master_ip_online_change_script=/usr/local/bin/master_ip_online_change

5. 再次进行MHA服务手工在线切换
[root@db03 ~]#masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=10.0.0.51 --orig_master_is_new_slave --running_updates_limit=10000
--步骤参照2操作
...
[info] Switching master to 10.0.0.51(10.0.0.51:3306) completed successfully.

6. 重构binlogserver功能
[root@db03 ~]# cd /data/binlog_server/
[root@db03 binlog_server]# rm -rf ./*
[root@db03 binlog_server]# mysql -e "show slave status\G"|grep "Master_Log"
              Master_Log_File: binlog.000002
          Read_Master_Log_Pos: 196
        Relay_Master_Log_File: binlog.000002
          Exec_Master_Log_Pos: 196
[root@db03 binlog_server]# mysqlbinlog -R --host=10.0.0.51 --user=mha --password=mha --raw --stop-never binlog.000001 &
[root@db03 binlog_server]# ll
total 8
-rw-r----- 1 root root 1208 Oct 13 00:20 binlog.000001
-rw-r----- 1 root root  196 Oct 13 00:20 binlog.000002

7.恢复启动MHA
[root@db03 ~]# 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 &
[3] 7441
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:7441) is running(0:PING_OK), master:10.0.0.51

#查看主从关系
[root@db01 ~]# mysql -e "show slave hosts;"
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|        53 |      | 3306 |        51 | 80c3ac5f-6900-11ee-95a7-000c29878b35 |
|        52 |      | 3306 |        51 | 7ed80e81-6900-11ee-9663-000c2957def8 |
+-----------+------+------+-----------+--------------------------------------+

执行切换命令参数信息说明:

序号 参数信息 解释说明
01 --master_state 执行手工切换的状态,alive表示主节点存活状态进行切换
02 --new_master_host 指定切换后的新主库节点的地址信息
03 -- orig_master_is_new_slave 将原有主库指定为新的从库角色
04 --running_updates_limit 指定切换过程的时间限制,超过指定时间未完成切换,即切换失败,单位毫秒

在进行MHA高可用节点在线手工切换时,有以下信息需要注意:

  • 无法自动调整原有主库的binlog_server,需要手工重新拉取新主库的binlog;
  • 无法进行触发邮件脚本功能,邮件发送功能只能在MHA产生故障转移时触发;
  • 需要进行架构主从关系的切换,以及可以调整转移VIP地址信息;
  • 需要对切换前的主库进行锁定(FTWRL flush tables with read lock),避免数据不一致。

8.总结

MHA作为MySQL高可用生态的重要组成部分,虽然有其特定限制,但在许多生产环境中仍然发挥着关键作用。随着技术发展,虽然出现了更多新型高可用方案(如MGR、云原生方案等),但MHA的设计思想和实践经验仍然具有重要参考价值。掌握MHA不仅是为了应对当前需求,更是为了培养全面的高可用架构思维,为应对未来更复杂的技术挑战打下坚实基础。

在实际应用中,建议结合具体业务需求、技术团队能力和基础设施条件,选择最适合的高可用方案。无论选择哪种方案,核心目标都是相同的:在保证数据安全的前提下,提供持续可用的数据服务,为业务创造稳定可靠的技术支撑。

相关推荐
洛_尘2 小时前
MySQL 7:数据库设计
数据库·mysql
heze092 小时前
sqli-labs-Less-22
数据库·mysql·网络安全
墨雨晨曦883 小时前
如何保证redis和mysql数据一致性方案对比
数据库·redis·mysql
rfidunion3 小时前
springboot+VUE+部署(9。安装MySql)
spring boot·后端·mysql
计算机学姐3 小时前
基于SpringBoot的社区互助系统
java·spring boot·后端·mysql·spring·信息可视化·推荐算法
独自破碎E3 小时前
如何在MySQL中监控和优化慢SQL?
数据库·sql·mysql
前进的李工3 小时前
SQL数据操作实战指南
数据库·sql·mysql
Maggie_ssss_supp4 小时前
Linux-MySQL数据备份与恢复
数据库·mysql