华子目录
- `MHA`概述
- 为什么要用`MHA`
- 什么是`MHA`
- `MHA`的组成
- `MHA`的特点
- 故障切换备选主库的算法
- `MHA`工作原理
- `MHA`环境搭建
- 环境准备
- 开始部署`MHA`
- `MHA软件`使用介绍
- 配置`MHA`的`管理环境`
- 创建`MHA管理`的`模板文件`
- 测试
- 模拟故障`MySQL-master`切换
- `手动切换`(在`master`存活状态下`切换`)
- `手动切换`(在`master`死亡状态下`切换`)
- `自动切换`
- `MHA`的`故障切换过程`
- 为`MHA`添加`vip功能`
- 测试1(`自动故障切换`)
- 测试2 (通过`vip`登录`数据库`)
MHA概述

为什么要用MHA
- 解决
MySQL集群中master的单点故障问题
什么是MHA
MHA(Master High Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件MHA的出现就是解决MySQL 中master单点故障的问题MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用
MHA的组成
MHA由两部分组成:MHA Manager(管理节点)MHA Node(数据库节点)MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上(MHA是独立出来的一台主机,只能在企业7中做)MHA Manager会定时探测集群中的master节点- 当
master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master MHA-master是可以是一台单独的服务器,node是MySQL服务器(包括mysql-master,mysql-slave)
MHA的特点
自动故障切换过程中,MHA从宕机的主服务器上保存二进制日志,最大程度的保证数据不丢失- 使用
半同步复制,可以大大降低数据丢失的风险,如果只有一个slave已经收到了最新的二进制日志,MHA可以将最新的二进制日志应用于其他所有的slave服务器上,因此可以保证所有节点的数据一致性 - 目前
MHA支持一主多从架构,最少三台服务,即一主两从
故障切换备选主库的算法
- 一般判断
从库的是从(position/gtid)判断优劣,数据有差异,最接近于master的slave,成为备选主 数据一致的情况下,按照配置文件顺序,选择备选主库- 设定
有权重(candidate_master=1),按照权重强制指定备选主默认情况下如果一个slave落后master 100M的relay logs的话,即使有权重,也会失效- 如果
check_repl_delay=0的话,即使落后很多日志,也强制选择其为备选主
MHA工作原理
- 目前
MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群必须最少有3台数据库服务器,一主二从,即一台充当Master,一台充当备用Master,另一台充当从库 MHA Node运行在每台MySQL服务器上MHA Manager会定时探测集群中的master节点- 当
master出现故障时,它可以自动将最新数据的slave提升为新的master - 然后将
所有其他的slave重新指向新的master,VIP自动漂移到新的master 整个故障转移过程对应用程序完全透明
MHA环境搭建
环境准备
- 准备一台
MHA主机,ip:172.25.254.50/24,主机名:mha.org

- 做
hosts解析
[root@mha ~]# vim /etc/hosts

[root@mysql-node1 ~]# vim /etc/hosts

[root@mysql-node2 ~]# vim /etc/hosts

[root@mysql-node3 ~]# vim /etc/hosts

mha和node1,node2,node3之间做免密认证
#mha制作公私钥
[root@mha ~]# ssh-keygen -t rsa
#将mha的公钥传给node1,node2,node3
[root@mha ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.254.10[root@mha ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.254.20[root@mha ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.254.30
#此时免密登录完成
- 修改
node1,node2,node3中的/etc/my.cnf文件实验要求:node1为master,node2为备用master,node3为slave
[root@mysql-node1 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=10
log-bin=master-bin #开启binlog
gtid_mode=ON
enforce-gtid-consistency=ON
[root@mysql-node2 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=10
log-bin=master-bin #开启binlog
gtid_mode=ON
enforce-gtid-consistency=ON
[root@mysql-node3 ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
symbolic-links=0
server-id=30
gtid_mode=ON
enforce-gtid-consistency=ON
因为
node2可能会成为master,所以,node2要开启binlog功能。由于node3是slave,不会被选举为master,所以不用开启binlog
node1,node2,node3重新部署MySQL
[root@mysql-node1 ~]# /etc/init.d/mysqld stop[root@mysql-node1 ~]# rm -rf /data/mysql/*[root@mysql-node1 ~]# mysqld --user=mysql --initialize[root@mysql-node1 ~]# mysql -uroot -p'p5Y0jI%DMp9h'mysql> alter user root@localhost identified by "123456";
node2,node3同上
node1上建立数据同步用户并进行主从复制的授权,并开启半同步模式
#node1上建立同步用户
mysql> create user huazi@'%' identified by "123456";
#授权
mysql> grant replication slave on *.* to huazi@'%';
#半同步设置
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';#开启半同步
mysql> set global rpl_semi_sync_master_enabled=1;mysql> show master status\G;

#node2
mysql> change master to \-> master_host='172.25.254.10',-> master_user='huazi',-> master_password='123456',-> master_auto_position=1;mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';mysql> set global rpl_semi_sync_slave_enabled=1;mysql> start slave;mysql> show slave status\G;

#node3上
mysql> change master to \-> master_host='172.25.254.10',-> master_user='huazi',-> master_password='123456',-> master_auto_position=1;mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';mysql> set global rpl_semi_sync_slave_enabled=1;mysql> start slave;mysql> show slave status\G;

- 在
MySQL-master和备用master上创建登录用户
#node1上
mysql> create user root@'%' identified by "123456";mysql> grant all on *.* to root@'%';
由于主从复制,我们在
node1上的创建了登录用户,node2上也自然会同步到
#node上
mysql> select user,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| huazi | % |
| root | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+#node2上
mysql> select user,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| huazi | % |
| root | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+#node3上
mysql> select user,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| huazi | % |
| root | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
开始部署MHA
- 上传
MHA包到mha.org主机

解压
[root@mha ~]# unzip MHA-7.zip
[root@mha ~]# cd MHA-7/
[root@mha MHA-7]# ls
mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
mha4mysql-manager-0.58.tar.gz
mha4mysql-node-0.58-0.el7.centos.noarch.rpm
perl-Config-Tiny-2.14-7.el7.noarch.rpm
perl-Email-Date-Format-1.002-15.el7.noarch.rpm
perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm
perl-Mail-Sender-0.8.23-1.el7.noarch.rpm
perl-Mail-Sendmail-0.79-21.el7.noarch.rpm
perl-MIME-Lite-3.030-1.el7.noarch.rpm
perl-MIME-Types-1.38-2.el7.noarch.rpm
perl-Net-Telnet-3.03-19.el7.noarch.rpm
perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
安装
[root@mha MHA-7]# yum install *.rpm -y
- 将
mha4mysql-node-0.58-0.el7.centos.noarch.rpm包发送给所有mysql服务器
[root@mha MHA-7]# rsync mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@172.25.254.10:/root/[root@mha MHA-7]# rsync mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@172.25.254.20:/root/[root@mha MHA-7]# rsync mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@172.25.254.30:/root/
node1,node2,node3安装mha4mysql-node-0.58-0.el7.centos.noarch.rpm
#node1上安装
[root@mysql-node1 ~]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
#node2上安装
[root@mysql-node2 ~]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
#node3上安装
[root@mysql-node3 ~]# yum install mha4mysql-node-0.58-0.el7.centos.noarch.rpm -y
MHA软件使用介绍
manager工具包主要包括以下几个工具
masterha_check_ssh检查MHA的ssh配置状况masterha_check_repl检查MySQL复制状况masterha_manger启动MHA,进行监控MySQL-master的状态masterha_check_status检查当前MHA运行状态masterha_master_monitor检查master是否宕机masterha_master_switch手动切换MySQL-mastermasterha_conf_host添加或删除配置的server信息
node工具包(通常由MHA主机直接调用,无需人为执行)
save_binary_logs保存和复制master的二进制日志apply_diff_relay_logs识别差异中的中继日志事件并将其差异的事件应用于其他的slavefilter_mysqlbinlog去除不必要的rollback事件(MHA已不再使用这个工具)purge_relay_logs清除中继日志(不会阻塞sql线程)
配置MHA的管理环境
#创建MHA配置文件存储位置
[root@mha ~]# mkdir /etc/masterha/
[root@mha ~]# masterha_manager --help
Usage:masterha_manager --global_conf=/etc/masterha_default.cnf--conf=/usr/local/masterha/conf/app1.cnfSee online reference(http://code.google.com/p/mysql-master-ha/wiki/masterha_manager) fordetails.
--global-conf是MHA的全局配置文件,记录公共设定--conf是MHA的子配置文件,不同管理配置文件,记录各自配置
创建MHA管理的模板文件
[root@mha MHA-7]# tar -zxf mha4mysql-manager-0.58.tar.gz[root@mha MHA-7]# cd mha4mysql-manager-0.58/[root@mha mha4mysql-manager-0.58]# ls -F
AUTHORS COPYING lib/ MANIFEST README samples/ tests/
bin/ debian/ Makefile.PL* MANIFEST.SKIP rpm/ t/[root@mha mha4mysql-manager-0.58]# cd samples/
[root@mha samples]# ls
conf scripts
[root@mha samples]# cd conf/
[root@mha conf]# ls
app1.cnf masterha_default.cnf#将两个文件中的内容合并为一个文件,并写到/etc/masterha/app1.conf文件中
[root@mha conf]# cat masterha_default.cnf app1.cnf > /etc/masterha/app1.conf
- 修改
app1.conf的内容
[root@mha conf]# cd /etc/masterha/
[server default]
user=root #MySQL中用于登录的用户
password=123456 #用户密码
ssh_user=root #node1,node2,node3中用户ssh登录的用户
repl_user=huazi #MySQL用户数据同步的用户
repl_password=123456 #用户密码
master_binlog_dir= /data/mysql #主库二进制日志的存储目录
remote_workdir=/tmp #在远程服务器上执行命令时的工作目录
secondary_check_script= masterha_secondary_check -s 172.25.254.10 -s 172.25.254.11 #此参数使为了提供冗余检测,方式是mha主机网络自身的问题无法连接数据库节点,第二个应为集群之外的主机
ping_interval=3 #MHA Manager检测从库存活状态的间隔(秒)
# master_ip_failover_script= /script/masterha/master_ip_failover #发生故障后调用的脚本,用来迁移vip
# shutdown_script= /script/masterha/power_manager #电源管理脚本
# report_script= /script/masterha/send_report #当发生故障后用此脚本发邮件或者告警通知
# master_ip_online_change_script= /script/masterha/master_ip_online_change #在线切换时调用的vip迁移脚本,手动
[server default]
manager_workdir=/etc/masterha #MHA-master的工作目录
manager_log=/etc/masterha/manager.log #MHA Manager的日志文件路径[server1]
hostname=172.25.254.10
candidate_master=1 #表示该服务器可以作为候选主库
check_repl_delay=0 #复制延迟检查阈值,0表示不进行延迟检查[server2]
hostname=172.25.254.20
candidate_master=1 #表示该服务器可以作为候选主库
check_repl_delay=0 #复制延迟检查阈值,0表示不进行延迟检查[server3]
hostname=172.25.254.30
no_master=1 #表示该服务器不会被选为主库

check_repl_delay=0,默认情况下如果一个slave落后master 100M的relay-log的话,MHA将不会选择该slave作为一个新的master,因为对于这个slave的恢复需要花费很长时间,通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master
- 在
node1,node2,node3上任意一个主机上创建一个子接口
#这里我们在node3上创建一个子接口
[root@mysql-node3 ~]# ip address add 172.25.254.11/24 dev eth0
- 将
MHA的ssh私钥发送给node1,node2,node3
[root@mha ~]# rsync ~/.ssh/id_rsa root@172.25.254.10:/root/.ssh/[root@mha ~]# rsync ~/.ssh/id_rsa root@172.25.254.20:/root/.ssh/[root@mha ~]# rsync ~/.ssh/id_rsa root@172.25.254.30:/root/.ssh/
测试
#ssh检测
[root@mha ~]# masterha_check_ssh --conf=/etc/masterha/app1.conf

#repl检测
[root@mha ~]# masterha_check_repl --conf=/etc/masterha/app1.conf

模拟故障MySQL-master切换
手动切换时,可以不删除锁文件,不设置--ignore_last_state参数,但是自动一定要删除锁文件
手动切换(在master存活状态下切换)
#现在的master是node1
mysql> show master status\G;
*************************** 1. row ***************************File: master-bin.000002Position: 1279Binlog_Do_DB:Binlog_Ignore_DB:
Executed_Gtid_Set: 85cf422c-b472-11ef-be1a-000c2928b963:1-5
手动切换(在MHA上做)
[root@mha ~]# masterha_master_switch \
> --conf=/etc/masterha/app1.conf \
> --master_state=alive \ #表示node1为存活状态
> --new_master_host=172.25.254.20 \
> --new_master_port=3306 \
> --orig_master_is_new_slave \ #原来的master变为slave
> --running_updates_limit=10000 #切换的超时时间为10秒
#一直yes回车
- 查看
node1的状态
mysql> show slave status\G;

- 查看
node2的状态

- 查看
node3的状态

- 再
手动将master切换为node1
[root@mha ~]# masterha_master_switch \
> --conf=/etc/masterha/app1.conf \
> --master_state=alive \
> --new_master_host=172.25.254.10 \
> --new_master_port=3306 \
> --orig_master_is_new_slave \
> --running_updates_limit=10000
- 查看
node1的状态

- 查看
node2的状态

- 查看
node3的状态

手动切换(在master死亡状态下切换)
- 将
node1挂掉
[root@mysql-node1 ~]# /etc/init.d/mysqld stop
手动切换(在MHA上切换)
[root@mha ~]# masterha_master_switch \
> --master_state=dead \ #原master的状态
> --conf=/etc/masterha/app1.conf \
> --dead_master_host=172.25.254.10 \
> --dead_master_port=3306 \
> --new_master_host=172.25.254.20 \
> --new_master_port=3306 \
> --ignore_last_failove #因为自动切换会生成锁文件
--ignore_last_failove表示忽略在/etc/masterha/目录中在切换过程中生成的锁文件
恢复故障
[root@mysql-node1 ~]# /etc/init.d/mysqld startmysql> change master to \-> master_host='172.25.254.20',-> master_user='huazi',-> master_password='123456',-> master_auto_position=1;mysql> start slave;
- 查看
node1的状态

- 查看
node2的状态

- 查看
node3的状态

手动切换回node1
[root@mha ~]# masterha_master_switch \
> --conf=/etc/masterha/app1.conf \
> --master_state=alive \
> --new_master_host=172.25.254.10 \
> --new_master_port=3306 \
> --orig_master_is_new_slave \
> --running_updates_limit=10000
自动切换
[root@mha ~]# cd /etc/masterha/
[root@mha masterha]# ls
app1.conf app1.failover.complete
app1.failover.complete是生成的锁文件,在做自动切换前,要删除这个锁文件自动切换时,一定要删除锁文件,否则下一次自动切换会失败
[root@mha masterha]# rm -rf app1.failover.complete
[root@mha masterha]# ls
app1.conf
- 对
MySQL-master进行监控(在MHA上做)
[root@mha masterha]# masterha_manager --conf=/etc/masterha/app1.conf
Sun Dec 8 00:19:12 2024 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Dec 8 00:19:12 2024 - [info] Reading application default configuration from /etc/masterha/app1.conf..
Sun Dec 8 00:19:12 2024 - [info] Reading server configuration from /etc/masterha/app1.conf..
#进程会一直运行着,等待着
- 停掉
node1,因为node1是master
[root@mysql-node1 ~]# /etc/init.d/mysql.server stop
- 发现
master自动切换到了node2

- 发现
masterha_manager的进程也自动结束了

- 一次
故障监控完masterha_manager进程就结束了
- 发现
自动切换时生成了日志manager.log
[root@mha masterha]# ls
app1.conf app1.failover.complete manager.log
恢复故障
[root@mysql-node1 ~]# /etc/init.d/mysqld start
自动切换后,原来的master不会自动成为slave,需要我们手动切换
[root@mysql-node1 ~]# mysql -uroot -p
Enter password:
mysql> show slave status\G;
Empty set (0.00 sec)#手动加入
mysql> change master to \-> master_host='172.25.254.20',-> master_user='huazi',-> master_password='123456',-> master_auto_position=1;mysql> start slave;mysql> show slave status\G;

MHA的故障切换过程
配置文件检查阶段,这个阶段会检查整个集群配置文件中的配置内容宕机的master处理,这个阶段包括虚拟ip摘除操作,主机关机操作- 复制
dead master和最新slave相差的relay log,并保存到MHA Manger具体的目录下 识别含有最新更新的slave- 应用
从master保存的二进制日志事件(binlog events) 提升一个slave为新的master进行复制- 使
其他的slave连接新的master进行复制
为MHA添加vip功能
- 防止
真实MySQL主机切换后,ip变化,导致业务不通
上传两个脚本文件

master_ip_failover是自动切换使用的脚本master_ip_online_change是手动切换使用的脚本
- 添加到
环境变量中,并赋予可执行权限
[root@mha ~]# cp master_ip_* /usr/local/bin/[root@mha ~]# chmod +x /usr/local/bin/master_ip_*
- 修改
master_ip_failover脚本内容
[root@mha ~]# vim /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 = '172.25.254.100/24';
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";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 \"`;
}
sub stop_vip() {return 0 unless ($ssh_user);`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";
}

- 修改
master_ip_online_change脚本内容
[root@mha ~]# vim /usr/local/bin/master_ip_online_change
#!/usr/bin/env perl
use strict;
use warnings FATAL =>'all';use Getopt::Long;my $vip = '172.25.254.100/24';
my $ssh_start_vip = "/sbin/ip addr add $vip dev eth0";
my $ssh_stop_vip = "/sbin/ip addr del $vip dev eth0";
my $exit_code = 0;my ($command, $orig_master_is_new_slave, $orig_master_host,$orig_master_ip, $orig_master_port, $orig_master_user,$orig_master_password, $orig_master_ssh_user, $new_master_host,$new_master_ip, $new_master_port, $new_master_user,$new_master_password, $new_master_ssh_user,
);
GetOptions('command=s' => \$command,'orig_master_is_new_slave' => \$orig_master_is_new_slave,'orig_master_host=s' => \$orig_master_host,'orig_master_ip=s' => \$orig_master_ip,'orig_master_port=i' => \$orig_master_port,'orig_master_user=s' => \$orig_master_user,'orig_master_password=s' => \$orig_master_password,'orig_master_ssh_user=s' => \$orig_master_ssh_user,'new_master_host=s' => \$new_master_host,'new_master_ip=s' => \$new_master_ip,'new_master_port=i' => \$new_master_port,'new_master_user=s' => \$new_master_user,'new_master_password=s' => \$new_master_password,'new_master_ssh_user=s' => \$new_master_ssh_user,
);exit &main();sub main {#print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";if ( $command eq "stop" || $command eq "stopssh" ) {# $orig_master_host, $orig_master_ip, $orig_master_port are passed.# If you manage master ip address at global catalog database,# invalidate orig_master_ip here.my $exit_code = 1;eval {print "\n\n\n***************************************************************\n";print "Disabling the VIP - $vip on old master: $orig_master_host\n";print "***************************************************************\n\n\n\n";
&stop_vip();$exit_code = 0;};if ($@) {warn "Got Error: $@\n";exit $exit_code;}exit $exit_code;
}
elsif ( $command eq "start" ) {# all arguments are passed.# If you manage master ip address at global catalog database,# activate new_master_ip here.# You can also grant write access (create user, set read_only=0, etc) here.
my $exit_code = 10;eval {print "\n\n\n***************************************************************\n";print "Enabling the VIP - $vip on new master: $new_master_host \n";print "***************************************************************\n\n\n\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";`ssh $orig_master_ssh_user\@$orig_master_host \" $ssh_start_vip \"`;exit 0;
}
else {
&usage();exit 1;
}
}# A simple system call that enable the VIP on the new master
sub start_vip() {
`ssh $new_master_ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $orig_master_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";
}

- 打开
MHA的vip功能
[root@mha ~]# vim /etc/masterha/app1.conf

vip需要手动添加(因为此时master在node2上,所以我们给node2添加一个vip)
[root@mysql-node2 ~]# ip address add 172.25.254.100/24 dev eth0
测试1(自动故障切换)
- 监控
master(在MHA上做)
#先删除锁文件
[root@mha ~]# cd /etc/masterha/
[root@mha masterha]# ls
app1.conf app1.failover.complete manager.log
[root@mha masterha]# rm -rf app1.failover.complete
[root@mha ~]# masterha_manager --conf=/etc/masterha/app1.conf
Sun Dec 8 01:32:22 2024 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Dec 8 01:32:22 2024 - [info] Reading application default configuration from /etc/masterha/app1.conf..
Sun Dec 8 01:32:22 2024 - [info] Reading server configuration from /etc/masterha/app1.conf..
- 在
node2上模拟故障
#将node2上的MySQL停掉
[root@mysql-node2 ~]# /etc/init.d/mysql.server stop
- 发现原来在
node2上的vip移到了node1上

node1成为了master

恢复故障
[root@mysql-node2 ~]# /etc/init.d/mysql.server start
手动加入
[root@mysql-node2 ~]# mysql -uroot -p
Enter password:
mysql> show slave status\G;
Empty set (0.00 sec)#手动加入
mysql> change master to \-> master_host='172.25.254.10',-> master_user='huazi',-> master_password='123456',-> master_auto_position=1;mysql> start slave;

测试2 (通过vip登录数据库)
[root@mysql-node3 ~]# mysql -h 172.25.254.100 -uroot -p123456mysql> select @@server_id;
+-------------+
| @@server_id |
+-------------+
| 10 |
+-------------+
