文章目录

  • MHA 架构部署
  • 一、部署信息
  • 1、安装软件信息
  • 2、软件下载地址
  • 3、环境规划
  • 二、主机环境配置
  • 1、永久修改主机名
  • 2、添加 IP 映射
  • 3、开放端口
  • 4、配置互信
  • 三、安装依赖包
  • 1、配置 MHA Node 所需依赖包(每台机都需要配)
  • 2、配置 MHA Manager 所需依赖包(只需在 manager 上配置即可)
  • 四、RPM 安装 MHA
  • 1、安装 MHA Node (所有节点都安装)
  • 2、安装 MHA Manager (manager 节点安装即可)
  • 五、源码安装 MHA
  • 1、安装 MHA Node (所有节点都安装)
  • 2、安装 MHA Manager (manager 节点安装即可)
  • 总结
  • 六、搭建主从复制环境
  • 1、在master上备份数据
  • 2、在master上创建复制账号和 MHA 监控账号
  • 3、将备份传送到slave机器
  • 4、在 slave 上搭建备库
  • 七、配置 MHA
  • 1、设置 Relay Log 清除方式
  • 2、配置 mysqlbinlog 环境
  • 3、app1.cnf
  • 八、通过脚本管理 VIP 配置
  • 1、master_ip_failover
  • 2、master_ip_online_change
  • 九、keepalived 管理 VIP 配置
  • 1、 keepalived 安装配置
  • 2、脚本配置方法一
  • 3、脚本配置方法二
  • 十、测试
  • 1、检查 SSH 的配置
  • 2、检查整个复制环境状况
  • 3、启动 MHA
  • 4、在线切换测试
  • 5、Master 异常宕机
  • 6、宕机恢复
  • 7、模拟网络故障
  • 总结
  • 十一、常见报错
  • 1、检查 SSH 的配置时报错
  • 2、检查整个复制环境状况报错


MHA 架构部署

一、部署信息
1、安装软件信息

安装软件

软件版本

CentOS

CentOS Linux release 7.6.1810 (Core)

mysql

mysql-5.7.30-linux-glibc2.12-x86_64

mha

mha4mysql-manager-0.58-0.el7.centos.noarch / mha4mysql-node-0.58-0.el7.centos.noarch

keepalived

keepalived-2.0.15

2、软件下载地址

软件

下载地址

CentOS

http://isoredirect.centos.org/centos/7/isos/x86_64/

mysql

https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.30-linux-glibc2.12-x86_64.tar.gz

mha

https://github.com/yoshinorim/mha4mysql-manager

keepalived

https://www.keepalived.org/download.html

3、环境规划

角色

IP

hostname

权限

master

192.168.136.137

ip137

读写

slave1(备master)

192.168.136.136

ip136


slave2(manager)

192.168.136.135

ip135


二、主机环境配置
1、永久修改主机名
hostnamectl set-hostname ip135

#或修改 hostname 文件
vi /etc/hostname
2、添加 IP 映射
# vi /etc/hosts 在文件默认加上

192.168.136.135 ip135
192.168.136.136 ip136
192.168.136.137 ip137
3、开放端口
#查看防火墙状态
firewall-cmd --state

#开放 3306 端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent

#重新再入
firewall-cmd --reload

#查询端口号 3306 是否开启
firewall-cmd --query-port=3306/tcp
4、配置互信
#在 135 上
ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.135
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.136
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.137

#在 136 上
ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.135
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.137

#在 137 上
ssh-keygen -t rsa
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.135
ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.136.136
三、安装依赖包
1、配置 MHA Node 所需依赖包(每台机都需要配)

1) 所需依赖包

perl-DBD-MySQL
perl-Compress-Raw-Bzip2
perl-Compress-Raw-Zlib
perl-DBI
perl-IO-Compress
perl-Net-Daemon
perl-PlRPC

2) 安装依赖

yum install perl-DBD-MySQL -y
2、配置 MHA Manager 所需依赖包(只需在 manager 上配置即可)

1) 所需依赖包

perl-DBD-MySQL
perl-Compress-Raw-Bzip2
perl-Compress-Raw-Zlib
perl-DBI
perl-IO-Compress
perl-Net-Daemon
perl-DBD-MySQL
perl-Config-Tiny
perl-PlRPC
perl-Class-Load
perl-Data-OptList               
perl-List-MoreUtils             
perl-Module-Implementation      
perl-Module-Runtime             
perl-Package-DeprecationManager 
perl-Package-Stash              
perl-Package-Stash-XS           
perl-Params-Util                
perl-Sub-Install                
perl-Try-Tiny                   
perl-Params-Validate
perl-Sys-Syslog
perl-IO-Socket-SSL
perl-IO-Socket-IP  
perl-Mozilla-CA    
perl-Net-LibIDN    
perl-Net-SSLeay    
perl-MailTools     
perl-Net-SMTP-SSL  
perl-TimeDate  
perl-Log-Dispatch    
perl-Parallel-ForkManager

2)安装依赖

yum install perl-DBD-MySQL -y
yum install perl-Config-Tiny -y
yum install  perl-Log-Dispatch -y
yum install  perl-Parallel-ForkManager -y

问题: yum 缺少依赖

[root@ip135 tmp]# yum install  perl-Log-Dispatch -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
No package perl-Log-Dispatch available.
Error: Nothing to do
[root@ip135 tmp]# yum install  perl-Parallel-ForkManager -y
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
No package perl-Parallel-ForkManager available.
Error: Nothing to do

解决方法:从 http://www.rpmfind.net/ 上下载相应的 rpm,进行 rpm 安装

3) 安装 rpm

rpm -ivh perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm
rpm -ivh perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm

问题:安装缺少其它依赖包

[root@ip135 tmp]# rpm -ivh perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm
warning: perl-Log-Dispatch-2.41-1.el7.1.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID 352c64e5: NOKEY
error: Failed dependencies:
        perl(Class::Load) is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(MIME::Lite) is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(Mail::Send) is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(Mail::Sender) is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(Mail::Sendmail) is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(Params::Validate) is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(Params::Validate) >= 0.15 is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch
        perl(Sys::Syslog) >= 0.25 is needed by perl-Log-Dispatch-2.41-1.el7.1.noarch

解决方法:先进行 yum 进行安装所需依赖包,如果还是缺少的,到 http://www.rpmfind.net/ 上下载相应的 rpm,进行 rpm 安装

重复 2 、3 步骤,直到所有依赖包安装完毕。

#偷懒方法
yum install perl-Mail* -y
四、RPM 安装 MHA
1、安装 MHA Node (所有节点都安装)

MHA Node 其他下载地址: https://qiniu.wsfnk.com/mha4mysql-node-0.58-0.el7.centos.noarch.rpm

#安装
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm


#查看
# rpm -qa | grep mha4mysql-node-0.58-0.el7.centos.noarch
#卸载
# rpm -e mha4mysql-node-0.58-0.el7.centos.noarch

安装成功如下显示并在 /usr/bin/ 下有如下文件

[root@ip135 tmp]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:mha4mysql-node-0.58-0.el7.centos ################################# [100%]
[root@ip135 tmp]# ll /usr/bin/ |grep _logs
-rwxr-xr-x.   1 root root     17639 Mar 22  2018 apply_diff_relay_logs
-rwxr-xr-x.   1 root root      8337 Mar 22  2018 purge_relay_logs
-rwxr-xr-x.   1 root root      7525 Mar 22  2018 save_binary_logs
2、安装 MHA Manager (manager 节点安装即可)

MHA Manager其他下载地址: https://qiniu.wsfnk.com/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

#安装
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm


#查看
# rpm -qa | grep mha4mysql-manager-0.58-0.el7.centos.noarch
#卸载
# rpm -e mha4mysql-manager-0.58-0.el7.centos.noarch

安装成功如下显示并在 /usr/bin/ 下有如下文件

[root@ip135 tmp]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
Preparing...                          ################################# [100%]
Updating / installing...
   1:mha4mysql-manager-0.58-0.el7.cent################################# [100%]
[root@ip135 tmp]# ll /usr/bin/ |grep masterha
-rwxr-xr-x.   1 root root      1995 Mar 22  2018 masterha_check_repl
-rwxr-xr-x.   1 root root      1779 Mar 22  2018 masterha_check_ssh
-rwxr-xr-x.   1 root root      1865 Mar 22  2018 masterha_check_status
-rwxr-xr-x.   1 root root      3201 Mar 22  2018 masterha_conf_host
-rwxr-xr-x.   1 root root      2517 Mar 22  2018 masterha_manager
-rwxr-xr-x.   1 root root      2165 Mar 22  2018 masterha_master_monitor
-rwxr-xr-x.   1 root root      2373 Mar 22  2018 masterha_master_switch
-rwxr-xr-x.   1 root root      5172 Mar 22  2018 masterha_secondary_check
-rwxr-xr-x.   1 root root      1739 Mar 22  2018 masterha_stop
五、源码安装 MHA
1、安装 MHA Node (所有节点都安装)

1) 编译

tar -zxvf mha4mysql-node-0.58.tar.gz


cd mha4mysql-node-0.58
# INSTALL_BASE 指定安装路径
perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft

问题

[root@ip135 mha4mysql-node-0.58]# perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Can.pm line 5.
BEGIN failed--compilation aborted at inc/Module/Install/Can.pm line 5.
Compilation failed in require at inc/Module/Install.pm line 307.
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Makefile.pm line 4.
BEGIN failed--compilation aborted at inc/Module/Install/Makefile.pm line 4.
Compilation failed in require at inc/Module/Install.pm line 307.
Can't locate ExtUtils/MM_Unix.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/Install/Metadata.pm line 322.


[root@ip135 mha4mysql-node-0.58]# perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
*** Module::AutoInstall version 1.06
*** Checking for Perl dependencies...
Can't locate CPAN.pm in @INC (@INC contains: inc /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at inc/Module/AutoInstall.pm line 304.

原因:缺少 perl-ExtUtils-MakeMaker 依赖包和 perl-CPAN 依赖包。

解决方法:安装依赖包

yum install perl-ExtUtils-MakeMaker
yum -y install perl-CPAN

编译成功

[root@ip135 mha4mysql-node-0.58]# perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
*** Module::AutoInstall version 1.06
*** Checking for Perl dependencies...
[Core Features]
- DBI        ...loaded. (1.627)
- DBD::mysql ...loaded. (4.023)
*** Module::AutoInstall configuration finished.
Checking if your kit is complete...
Looks good
Writing Makefile for mha4mysql::node

2) 安装

make && make install

安装成功

[root@ip135 mha4mysql-node-0.58]# make && make install
cp lib/MHA/BinlogManager.pm blib/lib/MHA/BinlogManager.pm
cp lib/MHA/BinlogPosFindManager.pm blib/lib/MHA/BinlogPosFindManager.pm
cp lib/MHA/BinlogPosFinderXid.pm blib/lib/MHA/BinlogPosFinderXid.pm
cp lib/MHA/BinlogHeaderParser.pm blib/lib/MHA/BinlogHeaderParser.pm
cp lib/MHA/BinlogPosFinder.pm blib/lib/MHA/BinlogPosFinder.pm
cp lib/MHA/BinlogPosFinderElp.pm blib/lib/MHA/BinlogPosFinderElp.pm
cp lib/MHA/NodeUtil.pm blib/lib/MHA/NodeUtil.pm
cp lib/MHA/SlaveUtil.pm blib/lib/MHA/SlaveUtil.pm
cp lib/MHA/NodeConst.pm blib/lib/MHA/NodeConst.pm
cp bin/filter_mysqlbinlog blib/script/filter_mysqlbinlog
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/filter_mysqlbinlog
cp bin/apply_diff_relay_logs blib/script/apply_diff_relay_logs
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/apply_diff_relay_logs
cp bin/purge_relay_logs blib/script/purge_relay_logs
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/purge_relay_logs
cp bin/save_binary_logs blib/script/save_binary_logs
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/save_binary_logs
Manifying blib/man1/filter_mysqlbinlog.1
Manifying blib/man1/apply_diff_relay_logs.1
Manifying blib/man1/purge_relay_logs.1
Manifying blib/man1/save_binary_logs.1
Installing /home/mysql/mha_soft/lib/perl5/MHA/BinlogManager.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/BinlogPosFindManager.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/BinlogPosFinderXid.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/BinlogHeaderParser.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/BinlogPosFinder.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/BinlogPosFinderElp.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/NodeUtil.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/SlaveUtil.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/NodeConst.pm
Installing /home/mysql/mha_soft/man/man1/filter_mysqlbinlog.1
Installing /home/mysql/mha_soft/man/man1/apply_diff_relay_logs.1
Installing /home/mysql/mha_soft/man/man1/purge_relay_logs.1
Installing /home/mysql/mha_soft/man/man1/save_binary_logs.1
Installing /home/mysql/mha_soft/bin/filter_mysqlbinlog
Installing /home/mysql/mha_soft/bin/apply_diff_relay_logs
Installing /home/mysql/mha_soft/bin/purge_relay_logs
Installing /home/mysql/mha_soft/bin/save_binary_logs
Appending installation info to /home/mysql/mha_soft/lib/perl5/x86_64-linux-thread-multi/perllocal.pod
2、安装 MHA Manager (manager 节点安装即可)

1) 编译

tar -zxvf mha4mysql-manager-0.58.tar.gz

cd mha4mysql-manager-0.58
# INSTALL_BASE 指定安装路径
perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft

问题 1

[root@ip135 mha4mysql-manager-0.58]# perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
Can't locate inc/Module/Install.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 1.
BEGIN failed--compilation aborted at Makefile.PL line 1.

原因:缺少 perl-Module-Install 依赖包

解决方法:安装依赖包

yum -y install perl-Module-Install

问题 2

[root@ip135 mha4mysql-manager-0.58]# perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
include /root/tmp/mha4mysql-manager-0.58/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/Makefile.pm
include inc/Module/Install/Scripts.pm
include inc/Module/Install/AutoInstall.pm
include inc/Module/Install/Include.pm
include inc/Module/AutoInstall.pm
*** Module::AutoInstall version 1.06
*** Checking for Perl dependencies...
[Core Features]
- DBI                   ...loaded. (1.627)
- DBD::mysql            ...loaded. (4.023)
- Time::HiRes           ...loaded. (1.9725)
- Config::Tiny          ...loaded. (2.14)
- Log::Dispatch         ...loaded. (2.41)
- Parallel::ForkManager ...loaded. (1.18)
- MHA::NodeConst        ...missing.
==> Auto-install the 1 mandatory module(s) from CPAN? [y] y
*** Dependencies will be installed the next time you type 'make'.
*** Module::AutoInstall configuration finished.
include inc/Module/Install/WriteAll.pm
include inc/Module/Install/Win32.pm
include inc/Module/Install/Can.pm
include inc/Module/Install/Fetch.pm
Checking if your kit is complete...
Warning: the following files are missing in your kit:
        META.yml
Please inform the author.
Warning: prerequisite MHA::NodeConst 0 not found.
Writing Makefile for mha4mysql::manager
Writing MYMETA.yml and MYMETA.json
Writing META.yml

原因:- MHA::NodeConst …missing. 找不到 node

解决方法 :将node包的安装路径加入到root的环境变量下面

#添加的环境变量如下:
export PERL5LIB=$PERL5LIB:/home/mysql/mha_soft/lib/perl5/

编译成功

[root@ip135 mha4mysql-manager-0.58]# perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
include /root/tmp/mha4mysql-manager-0.58/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/Makefile.pm
include inc/Module/Install/Scripts.pm
include inc/Module/Install/AutoInstall.pm
include inc/Module/Install/Include.pm
include inc/Module/AutoInstall.pm
*** Module::AutoInstall version 1.06
*** Checking for Perl dependencies...
[Core Features]
- DBI                   ...loaded. (1.627)
- DBD::mysql            ...loaded. (4.023)
- Time::HiRes           ...loaded. (1.9725)
- Config::Tiny          ...loaded. (2.14)
- Log::Dispatch         ...loaded. (2.41)
- Parallel::ForkManager ...loaded. (1.18)
- MHA::NodeConst        ...loaded. (0.58)
*** Module::AutoInstall configuration finished.
include inc/Module/Install/WriteAll.pm
include inc/Module/Install/Win32.pm
include inc/Module/Install/Can.pm
include inc/Module/Install/Fetch.pm
Writing Makefile for mha4mysql::manager
Writing MYMETA.yml and MYMETA.json
Writing META.yml

2) 安装

make && make install

安装成功

[root@ip135 mha4mysql-manager-0.58]# make && make install
/usr/bin/perl "-Iinc" Makefile.PL --config= --installdeps=MHA::NodeConst,0
include /root/tmp/mha4mysql-manager-0.58/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/Makefile.pm
include inc/Module/Install/Scripts.pm
include inc/Module/Install/AutoInstall.pm
include inc/Module/Install/Include.pm
include inc/Module/AutoInstall.pm
cp lib/MHA/ManagerUtil.pm blib/lib/MHA/ManagerUtil.pm
cp lib/MHA/Config.pm blib/lib/MHA/Config.pm
cp lib/MHA/HealthCheck.pm blib/lib/MHA/HealthCheck.pm
cp lib/MHA/ManagerConst.pm blib/lib/MHA/ManagerConst.pm
cp lib/MHA/ServerManager.pm blib/lib/MHA/ServerManager.pm
cp lib/MHA/FileStatus.pm blib/lib/MHA/FileStatus.pm
cp lib/MHA/ManagerAdmin.pm blib/lib/MHA/ManagerAdmin.pm
cp lib/MHA/ManagerAdminWrapper.pm blib/lib/MHA/ManagerAdminWrapper.pm
cp lib/MHA/MasterFailover.pm blib/lib/MHA/MasterFailover.pm
cp lib/MHA/MasterMonitor.pm blib/lib/MHA/MasterMonitor.pm
cp lib/MHA/MasterRotate.pm blib/lib/MHA/MasterRotate.pm
cp lib/MHA/SSHCheck.pm blib/lib/MHA/SSHCheck.pm
cp lib/MHA/Server.pm blib/lib/MHA/Server.pm
cp lib/MHA/DBHelper.pm blib/lib/MHA/DBHelper.pm
cp bin/masterha_stop blib/script/masterha_stop
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_stop
cp bin/masterha_conf_host blib/script/masterha_conf_host
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_conf_host
cp bin/masterha_check_repl blib/script/masterha_check_repl
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_check_repl
cp bin/masterha_check_status blib/script/masterha_check_status
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_check_status
cp bin/masterha_master_monitor blib/script/masterha_master_monitor
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_master_monitor
cp bin/masterha_check_ssh blib/script/masterha_check_ssh
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_check_ssh
cp bin/masterha_master_switch blib/script/masterha_master_switch
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_master_switch
cp bin/masterha_secondary_check blib/script/masterha_secondary_check
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_secondary_check
cp bin/masterha_manager blib/script/masterha_manager
/usr/bin/perl "-Iinc" -MExtUtils::MY -e 'MY->fixin(shift)' -- blib/script/masterha_manager
Manifying blib/man1/masterha_stop.1
Manifying blib/man1/masterha_conf_host.1
Manifying blib/man1/masterha_check_repl.1
Manifying blib/man1/masterha_check_status.1
Manifying blib/man1/masterha_master_monitor.1
Manifying blib/man1/masterha_check_ssh.1
Manifying blib/man1/masterha_master_switch.1
Manifying blib/man1/masterha_secondary_check.1
Manifying blib/man1/masterha_manager.1
/usr/bin/perl "-Iinc" Makefile.PL --config= --installdeps=MHA::NodeConst,0
include /root/tmp/mha4mysql-manager-0.58/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/Makefile.pm
include inc/Module/Install/Scripts.pm
include inc/Module/Install/AutoInstall.pm
include inc/Module/Install/Include.pm
include inc/Module/AutoInstall.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/ManagerUtil.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/Config.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/HealthCheck.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/ManagerConst.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/ServerManager.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/FileStatus.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/ManagerAdmin.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/ManagerAdminWrapper.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/MasterFailover.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/MasterMonitor.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/MasterRotate.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/SSHCheck.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/Server.pm
Installing /home/mysql/mha_soft/lib/perl5/MHA/DBHelper.pm
Installing /home/mysql/mha_soft/man/man1/masterha_stop.1
Installing /home/mysql/mha_soft/man/man1/masterha_conf_host.1
Installing /home/mysql/mha_soft/man/man1/masterha_check_repl.1
Installing /home/mysql/mha_soft/man/man1/masterha_check_status.1
Installing /home/mysql/mha_soft/man/man1/masterha_master_monitor.1
Installing /home/mysql/mha_soft/man/man1/masterha_check_ssh.1
Installing /home/mysql/mha_soft/man/man1/masterha_master_switch.1
Installing /home/mysql/mha_soft/man/man1/masterha_secondary_check.1
Installing /home/mysql/mha_soft/man/man1/masterha_manager.1
Installing /home/mysql/mha_soft/bin/masterha_stop
Installing /home/mysql/mha_soft/bin/masterha_conf_host
Installing /home/mysql/mha_soft/bin/masterha_check_repl
Installing /home/mysql/mha_soft/bin/masterha_check_status
Installing /home/mysql/mha_soft/bin/masterha_master_monitor
Installing /home/mysql/mha_soft/bin/masterha_check_ssh
Installing /home/mysql/mha_soft/bin/masterha_master_switch
Installing /home/mysql/mha_soft/bin/masterha_secondary_check
Installing /home/mysql/mha_soft/bin/masterha_manager
Appending installation info to /home/mysql/mha_soft/lib/perl5/x86_64-linux-thread-multi/perllocal.pod
总结

1) 安装

#安装 MHA Node (所有节点都安装)
tar -zxvf mha4mysql-node-0.58.tar.gz
cd mha4mysql-node-0.58
yum -y install perl-ExtUtils-MakeMaker
yum -y install perl-CPAN
perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
make && make install


#安装 MHA Manager (manager 节点安装即可)
tar -zxvf mha4mysql-manager-0.58.tar.gz
cd mha4mysql-manager-0.58
yum -y install perl-Module-Install
#添加的环境变量如下:
export PERL5LIB=$PERL5LIB:/home/mysql/mha_soft/lib/perl5/



perl Makefile.PL INSTALL_BASE=/home/mysql/mha_soft
make && make install

2) 安装目录有如下文件则成功

[root@ip135 mha4mysql-manager-0.58]# ls -lrt /home/mysql/mha_soft/bin/
total 88
-r-xr-xr-x. 1 root root  7525 Jun 13 03:42 save_binary_logs
-r-xr-xr-x. 1 root root  8337 Jun 13 03:42 purge_relay_logs
-r-xr-xr-x. 1 root root  4807 Jun 13 03:42 filter_mysqlbinlog
-r-xr-xr-x. 1 root root 17639 Jun 13 03:42 apply_diff_relay_logs
-r-xr-xr-x. 1 root root  1739 Jun 13 03:48 masterha_stop
-r-xr-xr-x. 1 root root  2165 Jun 13 03:48 masterha_master_monitor
-r-xr-xr-x. 1 root root  3201 Jun 13 03:48 masterha_conf_host
-r-xr-xr-x. 1 root root  1865 Jun 13 03:48 masterha_check_status
-r-xr-xr-x. 1 root root  1995 Jun 13 03:48 masterha_check_repl
-r-xr-xr-x. 1 root root  5172 Jun 13 03:48 masterha_secondary_check
-r-xr-xr-x. 1 root root  2373 Jun 13 03:48 masterha_master_switch
-r-xr-xr-x. 1 root root  2517 Jun 13 03:48 masterha_manager
-r-xr-xr-x. 1 root root  1779 Jun 13 03:48 masterha_check_ssh
六、搭建主从复制环境
1、在master上备份数据
mysqldump -uroot -p -S /home/mysql/mysql.sock --master-data=2 --single-transaction --default-character-set=utf8 -R --triggers -A > /home/mysql/tmp/dump/all.sql

参数说明

--master-data=2 代表备份时刻记录 master 的 BINLOG 位置和 Position;
--single-transaction 表示获取一致性快照;
-R 表示备份相关的存储过程
--triggers 表示备份触发器相关信息;
-A 表示备份所有 schema
2、在master上创建复制账号和 MHA 监控账号
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.136.%' IDENTIFIED BY 'repl';
grant all privileges on *.* to 'rootmha'@'192.168.136.%' IDENTIFIED BY 'rootmha';
3、将备份传送到slave机器
scp all.sql mysql@192.168.136.135:/home/mysql/tmp/dump/
scp all.sql mysql@192.168.136.137:/home/mysql/tmp/dump/
4、在 slave 上搭建备库

注意:对于GTID的数据库在恢复前reset master,或恢复后reset master在重设GTID

1) 在 slave 进行恢复

reset master;

/usr/local/mysql/bin/mysql -uroot -p -S /home/mysql/mysql.sock -f --default-character-set=utf8 < /home/mysql/tmp/dump/all.sql

2) 查看当前的gtid或 BINLOG的名称和位置

[mysql@localhost dump]$ head -n 50 /home/mysql/tmp/dump/all.sql | grep -i "CHANGE MASTER TO"
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-binlog.000005', MASTER_LOG_POS=194;



[mysql@localhost dump]$ head -n 50 all.sql | grep -iC 3 "SET @@GLOBAL.GTID_PURGED"
-- GTID state at the beginning of the backup
--

SET @@GLOBAL.GTID_PURGED='94395d02-5e37-11ea-b2e9-005056337049:1-4,
ea916fa5-6697-11ea-98b5-00505632439f:1-21';

--

3) 从库同步主库

CHANGE MASTER TO
MASTER_HOST='192.168.136.136',
MASTER_USER='repl',
MASTER_PASSWORD='repl',
MASTER_AUTO_POSITION=1;
start slave;

注意 : MySQL每台的 uuid、server_id 必须不一样,否则主从同步失败。

4) 查看从库状态

mysql> show slave status \G;
...
 Slave_IO_Running: Yes
 Slave_SQL_Running: Yes
...

5) slave 服务器设置 read_only

set global read_only=on;


mysql> show global variables like '%read_only%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_read_only      | OFF   |
| read_only             | ON    |
| super_read_only       | OFF   |
| transaction_read_only | OFF   |
| tx_read_only          | OFF   |
+-----------------------+-------+
七、配置 MHA
1、设置 Relay Log 清除方式

在每个 slave 上,使用 GTID 模式,将 relay_log_purge=1 ;使用 binlog 的名称和位置将 relay_log_purge=0,因为从库的恢复过程中可能需要 Relay Log

# GTID 模式
set global relay_log_purge=1;
# binlog 的名称和位置模式
set global relay_log_purge=0;

/usr/local/bin/purge_relay_logs --user=rootmha --password=rootmha --host=192.168.136.135 -disable_relay_log_purge --port=3306 --workdir=/home/mysql/mysqldata/
2、配置 mysqlbinlog 环境

设置 mysqlbinlog(在每个slave上),编辑 ~/.bashr 或者 /etc/bashrc 文件,添加

vi ~/.bashr

PATH=$PATH:/home/mysql/mysql/bin
export PATH

source ~/.bashr

注释:MHA 在切换过程中会直接调用 mysqlbinlog 命令,故需要在环境中指定 mysqlbinlog 的具体路径

3、app1.cnf

masterha_default.cnf 全局变量(一个manager管理多个MHA集群时配置此文件方便管理),可不配置。

[server default]
manager_workdir=/root/masterha
manager_log=/root/masterha/mhalog/manager.log
master_ip_failover_script=/root/masterha/bin/master_ip_failover
master_ip_online_change_script=/root/masterha/bin/master_ip_online_change
user=rootmha
password=rootmha
ping_interval=1
ping_type=connect
remote_workdir=/tmp/mhabinlog
repl_user=repl
repl_password=repl
report_script=/root/masterha/bin/send_report
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.136.137 -s 192.168.136.136 -s 192.168.136.135 --user=root --master_host=ip136 --master_ip=192.168.136.136 --master_port=22
shutdown_script=""
ssh_user=root
ssh_port=22

[server1]
hostname=192.168.136.135
master_binlog_dir=/home/mysql/mysqllog/binlog
port=3306
no_master=1

[server2]
hostname=192.168.136.136
master_binlog_dir=/home/mysql/mysqllog/binlog
port=3306


[server3]
hostname=192.168.136.137
master_binlog_dir=/home/mysql/mysqllog/binlog
port=3306

参数说明

[server default]
manager_workdir=/root/masterha																								//设置manager的工作目录
manager_log=/root/masterha/manager.log																				//设置manager的日志
master_ip_failover_script=/root/masterha/bin/master_ip_failover								//设置自动failover时候的切换脚本
master_ip_online_change_script=/root/masterha/bin/master_ip_online_change			//设置手动切换时候的切换脚本
user=rootmha																																	//设置切换执行的用户( mysql中具有 super 权限的用户名)
password=rootmha																															//设置切换用户密码
ping_interval=1																																//设置监控主库,发送检测命令的时间间隔,默认 3s ,尝试 3 次没有回应的时候进行自动 failover
ping_type=connect																															//设置检测方式,也可以选择 select 、insert 方式
remote_workdir=/tmp/mhabinlog																									//设置远端 mysql 在发生切换时保存 binlog 的具体位置
repl_user=repl																																//设置复制用户
repl_password=repl																														//设置复制用户密码
report_script=/root/masterha/bin/send_report																	//设置发生切换后发送报警的脚本
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.136.137 --user=root --master_host=ip136 --master_ip=192.168.136.136 --master_port=22			//一旦 MHA 到 ip136 的监控之间网络出现问题, MHA Manager 将会尝试从 ip137 登陆到 ip136
shutdown_script=""																														//设置故障发生后关闭故障主机脚本(该脚本主要作用是关闭主机防止发生脑裂)
ssh_user=root																																	//设置 ssh 的登陆用户名
ssh_port=22																																		//设置 ssh 使用的端口

[server1]
hostname=192.168.136.136
master_binlog_dir=/home/mysql/mysqllog/binlog																	//设置 MySQL 实例的 binlog 存储目录
port=3306


[server2]
hostname=192.168.136.137
master_binlog_dir=/home/mysql/mysqllog/binlog																	//设置 MySQL 实例的 binlog 存储目录
port=3306
candidate_master=1																														//设置为候选 master ,如果设置该参数后,发生主从切换后将会将此从库提升为主,即使这个库不是集群中最新的 slave
check_repl_delay=0																														//默认情况下如果一个 slave 落后 master 100M 的relay logs 的话,MHA 将不会选择该 slave 作为一个新的 master ,因为对于这个 slave 的恢复需要花费很长时间,通过设置 check_repl_delay=0,MHA 触发切换在选择一个新的 master 的时候将会忽略复制延迟,这个参数对于设置 candidate_master=1 的主机非常有用,因为它保证了这个候选主在切换过程中一定是新的 master

[server3]
hostname=192.168.136.135
master_binlog_dir=/home/mysql/mysqllog/binlog																	//设置 MySQL 实例的 binlog 存储目录
port=3306
no_master=1																																		//表示没有机会成为master
八、通过脚本管理 VIP 配置

注意:使用脚本绑定VIP前,先在master上绑定vip,(只需要在master绑定这一次,以后会自动切换)

#绑定
/usr/sbin/ifconfig ens33:1 192.168.136.130/24
#解绑
/usr/sbin/ifconfig ens33:1 down

#或
# ip addr add 192.168.136.130/24 dev ens33
# ip addr del 192.168.136.130/24 dev ens33


1、master_ip_failover

master 故障时,VIP 切换脚本

#!/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
);

#定义VIP变量
my $vip = '192.168.136.130/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
##ip addr add 192.168.136.130/24 dev ens33
##ip addr del 192.168.136.130/24 dev ens33
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip dev ens33";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip dev ens33";


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";
}
2、master_ip_online_change

手工切换主从时,vip切换脚本

#!/bin/bash
source /root/.bash_profile

vip=`echo '192.168.136.130/24'`  #设置VIP
key=`echo '1'`

command=`echo "$1" | awk -F = '{print $2}'`
orig_master_host=`echo "$2" | awk -F = '{print $2}'`
new_master_host=`echo "$7" | awk -F = '{print $2}'`
orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`
new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`

#要求服务的网卡识别名一样,都为ens33(这里是)
stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ifconfig ens33:$key down"`
start_vip=`echo "ssh root@$new_master_host /usr/sbin/ifconfig ens33:$key $vip"`
##ssh root@192.168.136.132 /usr/sbin/ip addr del 192.168.136.130/24 dev ens33
##ssh root@192.168.136.133 /usr/sbin/ip addr add 192.168.136.130/24 dev ens33
#stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ip addr del $vip dev ens33"`
#start_vip=`echo "ssh root@$new_master_host /usr/sbin/ip addr add $vip dev ens33"`

if [ $command = 'stop' ]
  then
    echo -e "\n\n\n****************************\n"
    echo -e "Disabled thi VIP - $vip on old master: $orig_master_host \n"
    $stop_vip
    if [ $? -eq 0 ]
      then
    echo "Disabled the VIP successfully"
      else
    echo "Disabled the VIP failed"
    fi
    echo -e "***************************\n\n\n"
  fi

if [ $command = 'start' -o $command = 'status' ]
  then
    echo -e "\n\n\n*************************\n"
    echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"
    $start_vip
    if [ $? -eq 0 ]
      then
    echo "Enabled the VIP successfully"
      else
    echo "Enabled the VIP failed"
    fi
    echo -e "***************************\n\n\n"
fi
九、keepalived 管理 VIP 配置
1、 keepalived 安装配置

1) 安装 keepalived

tar -zxvf keepalived-2.0.15.tar.gz
cd keepalived-2.0.15

#编译安装
./configure --prefix=/usr/local/keepalived
make && make install

2) 配置 keepalived

chown mysql:mysql /usr/local/keepalived/etc/keepalived/keepalived.conf

vi /usr/local/keepalived/etc/keepalived/keepalived.conf

① MASTER 配置

vrrp_instance VI_1 {
    interface ens33
    virtual_router_id 130
    state BACKUP
    nopreempt
    priority 150
    advert_int 1
    unicast_src_ip 192.168.136.136
    unicast_peer {
    192.168.136.137
    }
    authentication {
        auth_type PASS
        auth_pass 1116
    }
    virtual_ipaddress {
        192.168.136.130
    }
}

② BACKUP 配置

vrrp_instance VI_1 {
    interface ens33
    virtual_router_id 130
    state BACKUP
    nopreempt
    priority 120
    advert_int 1
    unicast_src_ip 192.168.136.137
    unicast_peer {
    192.168.136.136
    }
    authentication {
        auth_type PASS
        auth_pass 1116
    }
    virtual_ipaddress {
        192.168.136.130
    }
}

③参数详解

vrrp_instance VI_1 {
    interface ens33												#绑定的网卡
    virtual_router_id 130									#虚拟路由标识,同一个vrrp_instance的MASTER和BACKUP的vitrual_router_id 是一致的。
    state BACKUP													# keepalived 的角色,MASTER表示此主机是主服务器,BACKUP表示此主机是备用服务器。如果设置了nopreempt,那么state的这个值不起作用,主备靠priority决定。
    nopreempt															#设置为不抢占
    priority 150													#服务器优先级(默认为100)
    advert_int 1													# MASTER 与 BACKUP 负载均衡器之间同步检查的时间间隔,单位是秒
    unicast_src_ip 192.168.136.136				#配置单播的源地址
    unicast_peer {
    192.168.136.137												#配置单播的目标地址
    }
    authentication {
        auth_type PASS										#设置验证类型,主要有PASS和AH两种
        auth_pass 1116										#设置验证密码,同一个vrrp_instance下,MASTER和BACKUP的密码必须一致才能正常通信
    }
    virtual_ipaddress {
        192.168.136.130										#设置虚拟IP地址,可以设置多个虚拟IP地址,每行一个
    }
}

3) 启停 keepalived

#启动 keepalived
/usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf &

#停 keepalived
pkill keepalived
2、脚本配置方法一

1) master_ip_failover

#!/usr/bin/env perl

use strict;
use warnings FATAL => 'all';

use Getopt::Long;
use MHA::DBHelper;
use MHA::NodeUtil;
use Time::HiRes qw( sleep gettimeofday tv_interval );
use Data::Dumper;

my (
  $command,        $ssh_user,         $orig_master_host,
  $orig_master_ip, $orig_master_port, $new_master_host,
  $orig_master_password,$orig_master_ssh_user,
  $new_master_ip,  $new_master_port,  $new_master_user,
  $new_master_password, $new_master_ssh_user, 
);


##start and stop vip variables 
my $ssh_start_vip="/usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf";
my $ssh_stop_vip="pkill keepalived";
my $show_vip="ip addr";
my $show_vip_proc="ps -ef | grep keepalived | grep -v grep";
my $vip = '192.168.136.130';  # Virtual IP

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,
  'new_master_user=s'     => \$new_master_user,
  'new_master_password=s' => \$new_master_password,
);

#set unescape_password
#$orig_master_password = MHA::NodeUtil::unescape_for_shell($orig_master_password);
#print "########### $orig_master_password \n\n";
if ($new_master_password){
        $new_master_password = MHA::NodeUtil::unescape_for_shell($new_master_password);
}
#print "########### $new_master_password \n\n";

exit &main();

sub current_time_us {
  my ( $sec, $microsec ) = gettimeofday();
  my $curdate = localtime($sec);
  return $curdate . " " . sprintf( "%06d", $microsec );
}

# A simple system call that enable the VIP on the new master
sub start_vip() {
        print current_time_us() . " begin starting vip..\n\n";
        `ssh $new_master_host \" $ssh_start_vip \"`;
#        system("ssh $new_master_host \" $ssh_start_vip \"");
        system("ssh $new_master_host \" $show_vip\ ; $show_vip_proc \"");
        print "\n" . current_time_us() . " end started vip.. \n";
}

# A simple system call that disable the VIP on the old_master
sub stop_vip() {
        print current_time_us() . " begin stoping vip..\n";
        `ssh $orig_master_host \" $ssh_stop_vip \"`;
#        system("ssh $orig_master_host \" $ssh_stop_vip \"");
        system("ssh $orig_master_host \" $show_vip\ ; $show_vip_proc \"");
        print "\n" . current_time_us() . " end stoped vip.. \n";
}

sub main {
  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 {
      ## stop old master VIP
      print current_time_us() . " stop vip on the orig master for kill all app user connection..\n";
      eval {
            print "\n***********************************************************************************\n";
            print current_time_us() . " Disabling the VIP - $vip on old master: $orig_master_host\n";
            print "***********************************************************************************\n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            ##exit $exit_code;
        }
      
      # updating global catalog, etc
      $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";
            print current_time_us() . " Enabling the VIP - $vip on new master: $new_master_host \n";
            print "***********************************************************************************\n";
            &start_vip();
        };
    
    eval {
      my $new_master_handler = new MHA::DBHelper();

      # args: hostname, port, user, password, raise_error_or_not
      $new_master_handler->connect( $new_master_ip, $new_master_port,
        $new_master_user, $new_master_password, 1 );

      ## Set read_only=0 on the new master
      $new_master_handler->disable_log_bin_local();
      print "Set read_only=0 on the new master.\n";
      $new_master_handler->disable_read_only();

      ## Creating an app user on the new master
      ##print "Creating app user on the new master..\n";
      ##FIXME_xxx_create_user( $new_master_handler->{dbh} );
      ##$new_master_handler->enable_log_bin_local();
      ##$new_master_handler->disconnect();

      ## Update master ip on the catalog database, etc
      ## FIXME_xxx;

      $exit_code = 0;
    };
    
    if ($@) {
      warn $@;

      # If you want to continue failover, exit 10.
      exit $exit_code;
    }
    
    exit $exit_code;
  }
  elsif ( $command eq "status" ) {

    # do nothing
    print current_time_us() . "do nothing\n" ;
    exit 0;
  }
  else {
    &usage();
    exit 1;
  }
}

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";
}

2) master_ip_online_change

#!/usr/bin/env perl


use strict;
use warnings FATAL => 'all';

use Getopt::Long;
use MHA::DBHelper;
use MHA::NodeUtil;
use Time::HiRes qw( sleep gettimeofday tv_interval );
use Data::Dumper;

my $_tstart;
my $_running_interval = 0.1;
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,
);
##start and stop vip variables 
my $ssh_start_vip="/usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf";
my $ssh_stop_vip="pkill keepalived";
my $show_vip="ip addr";
my $show_vip_proc="ps -ef | grep keepalived | grep -v grep";
my $vip = '192.168.136.130';  # Virtual IP

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,
);

#set unescape_password
$orig_master_password = MHA::NodeUtil::unescape_for_shell($orig_master_password);
#print "########### $orig_master_password \n\n";
$new_master_password = MHA::NodeUtil::unescape_for_shell($new_master_password);
#print "########### $new_master_password \n\n";
 
exit &main();

sub current_time_us {
  my ( $sec, $microsec ) = gettimeofday();
  my $curdate = localtime($sec);
  return $curdate . " " . sprintf( "%06d", $microsec );
}

sub sleep_until {
  my $elapsed = tv_interval($_tstart);
  if ( $_running_interval > $elapsed ) {
    sleep( $_running_interval - $elapsed );
  }
}

sub get_threads_util {
  my $dbh                    = shift;
  my $my_connection_id       = shift;
  my $running_time_threshold = shift;
  my $type                   = shift;
  $running_time_threshold = 0 unless ($running_time_threshold);
  $type                   = 0 unless ($type);
  my @threads;

  my $sth = $dbh->prepare("SHOW PROCESSLIST");
  $sth->execute();

  while ( my $ref = $sth->fetchrow_hashref() ) {
    my $id         = $ref->{Id};
    my $user       = $ref->{User};
    my $host       = $ref->{Host};
    my $command    = $ref->{Command};
    my $state      = $ref->{State};
    my $query_time = $ref->{Time};
    my $info       = $ref->{Info};
    $info =~ s/^\s*(.*?)\s*$/$1/ if defined($info);
    next if ( $my_connection_id == $id );
    next if ( defined($query_time) && $query_time < $running_time_threshold );
    next if ( defined($command)    && $command eq "Binlog Dump" );
    next if ( defined($command)    && $command eq "Binlog Dump GTID" );
    next if ( defined($user)       && $user eq "system user" );
    next
      if ( defined($command)
      && $command eq "Sleep"
      && defined($query_time)
      && $query_time >= 1 );

    if ( $type >= 1 ) {
      next if ( defined($command) && $command eq "Sleep" );
      next if ( defined($command) && $command eq "Connect" );
    }

    if ( $type >= 2 ) {
      next if ( defined($info) && $info =~ m/^select/i );
      next if ( defined($info) && $info =~ m/^show/i );
    }

    push @threads, $ref;
  }
  return @threads;
}

# A simple system call that enable the VIP on the new master
sub start_vip() {
        print current_time_us() . " begin starting vip..\n\n";
        `ssh $new_master_ssh_user\@$new_master_host \" $ssh_start_vip \"`;
        system("ssh $new_master_ssh_user\@$new_master_host \" $show_vip\ ; $show_vip_proc \"");
        print "\n" . current_time_us() . " end started vip.. \n";
}

# A simple system call that disable the VIP on the old_master
sub stop_vip() {
        print current_time_us() . " begin stoping vip..\n";
        `ssh $orig_master_ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
        system("ssh $orig_master_ssh_user\@$orig_master_host \" $show_vip\ ; $show_vip_proc \"");
        print "\n" . current_time_us() . " end stoped vip.. \n";
}

sub main {
  if ( $command eq "stop" ) {
    ## Gracefully killing connections on the current master
    # 1. Set read_only= 1 on the new master
    # 2. DROP USER so that no app user can establish new connections
    # 3. Set read_only= 1 on the current master
    # 4. Kill current queries
    # * Any database access failure will result in script die.
    my $exit_code = 1;
    eval {
      ## Setting read_only=1 on the new master (to avoid accident)
      
      # args: hostname, port, user, password, raise_error(die_on_error)_or_not
      print current_time_us() . "begin to connect new master database: new_master_ip = $new_master_ip new_master_port = $new_master_port new_master_user = $new_master_user new_master_password = $new_master_password\n";
      my $new_master_handler = new MHA::DBHelper();
      $new_master_handler->connect( $new_master_ip, $new_master_port, $new_master_user, $new_master_password, 1 );
      print current_time_us() . " begin to set read_only = 1 on the new master..\n";
      $new_master_handler->enable_read_only();
      if ( $new_master_handler->is_read_only() ) {
        print current_time_us() . " end to set read_only = 1 on the new master..done!\n";
      }
      else {
        die current_time_us() . " end to set read_only on the new master..failed!\n";
      }
      $new_master_handler->disconnect();
      print current_time_us() . " disconnect to the new master database..\n"; 
      
      # Connecting to the orig master, die if any database error happens
      print current_time_us() . " begin to connect orig master database: orig_master_ip = $orig_master_ip orig_master_port = $orig_master_port orig_master_user = $orig_master_user orig_master_password = $orig_master_password\n";
      my $orig_master_handler = new MHA::DBHelper();
      $orig_master_handler->connect( $orig_master_ip, $orig_master_port, $orig_master_user, $orig_master_password, 1 );

      ## Drop application user so that nobody can connect. Disabling per-session binlog beforehand
      ##$orig_master_handler->disable_log_bin_local();
      ##print current_time_us() . " Drpping app user on the orig master..\n";
      ##FIXME_xxx_drop_app_user($orig_master_handler);
      print current_time_us() . " stop vip on the orig master for kill all app user connection..\n";
      eval {
            print "\n***********************************************************************************\n";
            print current_time_us() . " Disabling the VIP - $vip on old master: $orig_master_host\n";
            print "***********************************************************************************\n";
            &stop_vip();
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            ##exit $exit_code;
        }

      ## Waiting for N * 100 milliseconds so that current connections can exit
      my $time_until_read_only = 15;
      print current_time_us() . " waiting for $time_until_read_only * 100 milliseconds so that orig master connections can exit\n";  
      $_tstart = [gettimeofday];
      my @threads = get_threads_util( $orig_master_handler->{dbh}, $orig_master_handler->{connection_id} );
      while ( $time_until_read_only > 0 && $#threads >= 0 ) {
        if ( $time_until_read_only % 5 == 0 ) {
          printf "%s Waiting all running %d threads are disconnected.. (max %d milliseconds)\n",
            current_time_us(), $#threads + 1, $time_until_read_only * 100;
          if ( $#threads < 5 ) {
            print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"
              foreach (@threads);
          }
        }
        sleep_until();
        $_tstart = [gettimeofday];
        $time_until_read_only--;
        @threads = get_threads_util( $orig_master_handler->{dbh}, $orig_master_handler->{connection_id} );
      }

      ## Setting read_only=1 on the current master so that nobody(except SUPER) can write
      print current_time_us() . " begin to set read_only = 1 on the orig master.. \n";
      $orig_master_handler->enable_read_only();
      if ( $orig_master_handler->is_read_only() ) {
        print current_time_us() . " end to set read_only = 1 on the orig master.. done!\n";
      }
      else {
        die current_time_us() . " end to set read_only=1 on the orig master.. failed!\n";
      }

      ## Waiting for M * 100 milliseconds so that current update queries can complete  
   
      my $time_until_kill_threads = 5;
      print current_time_us() . " Waiting for  $time_until_kill_threads * 100 milliseconds so that orig master update queries can complete\n"; 
      @threads = get_threads_util( $orig_master_handler->{dbh},
        $orig_master_handler->{connection_id} );
      while ( $time_until_kill_threads > 0 && $#threads >= 0 ) {
        if ( $time_until_kill_threads % 5 == 0 ) {
          printf "%s Waiting all running %d queries are disconnected.. (max %d milliseconds)\n",
            current_time_us(), $#threads + 1, $time_until_kill_threads * 100;
          if ( $#threads < 5 ) {
            print Data::Dumper->new( [$_] )->Indent(0)->Terse(1)->Dump . "\n"
              foreach (@threads);
          }
        }
        sleep_until();
        $_tstart = [gettimeofday];
        $time_until_kill_threads--;
        @threads = get_threads_util( $orig_master_handler->{dbh},
          $orig_master_handler->{connection_id} );
      }

      ## Terminating all threads
      print current_time_us() . " begin to kill all application threads on the orig master database..\n";
      $orig_master_handler->kill_threads(@threads) if ( $#threads >= 0 );
      print current_time_us() . " end to kill all applincation threads..done.\n";
      $orig_master_handler->enable_log_bin_local();
      $orig_master_handler->disconnect();

      ## After finishing the script, MHA executes FLUSH TABLES WITH READ LOCK
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
  elsif ( $command eq "start" ) {
    ## Activating master ip on the new master
    # 1. Create app user with write privileges
    # 2. Moving backup script if needed
    # 3. Register new master's ip to the catalog database

# We don't return error even though activating updatable accounts/ip failed so that we don't interrupt slaves' recovery.
# If exit code is 0 or 10, MHA does not abort
    my $exit_code = 10;
          eval {
            print "\n***********************************************************************************\n";
            print current_time_us() . " Enabling the VIP - $vip on new master: $new_master_host \n";
            print "***********************************************************************************\n";
            &start_vip();
        };
    eval {
      my $new_master_handler = new MHA::DBHelper();

      # args: hostname, port, user, password, raise_error_or_not 
      print current_time_us() . "begin to connect new master database: new_master_ip = $new_master_ip new_master_port = $new_master_port new_master_user = $new_master_user new_master_password = $new_master_password\n"; 
      $new_master_handler->connect( $new_master_ip, $new_master_port,
        $new_master_user, $new_master_password, 1 );

      ## Set read_only=0 on the new master
      $new_master_handler->disable_log_bin_local();
      print current_time_us() . " Set read_only = 0 on the new master..begin\n";
      $new_master_handler->disable_read_only();
      print current_time_us() . " Set read_only = 0 on the new master..end\n";

      ## Creating an app user on the new master
      ##print current_time_us() . " Creating app user on the new master..\n";
      ##FIXME_xxx_create_app_user($new_master_handler);
      print current_time_us() . " enable new master database log_bin..begin\n" ;
      $new_master_handler->enable_log_bin_local();
      print current_time_us() . " enable new master database log_bin..end\n" ;
      print current_time_us() . " disconnect new master database\n" ;
      $new_master_handler->disconnect();

      ## Update master ip on the catalog database, etc
      $exit_code = 0;
    };
    if ($@) {
      warn "Got Error: $@\n";
      exit $exit_code;
    }
    exit $exit_code;
  }
  elsif ( $command eq "status" ) {
    # do nothing
    print current_time_us() . "do nothing\n" ;
    exit 0;
  }
  else {
    &usage();
    exit 1;
  }
}

sub usage {
  print
"Usage: master_ip_online_change --command=start|stop|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";
  die;
}
3、脚本配置方法二

1) master_ip_failover

#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
use MHA::DBHelper;


#启停 keepalived
my $stop_vip="/root/lvs-admin stop";
my $start_vip="/root/lvs-admin start";


my (
    $command,   $ssh_user,  $orig_master_host,
    $orig_master_ip,$orig_master_port, $new_master_host, $new_master_ip,$new_master_port,
    $new_master_user,$new_master_password
);


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,
    'new_master_user=s' => \$new_master_user,
    'new_master_password=s' => \$new_master_password,
);

exit &main();

sub main {
    if ( $command eq "stop" || $command eq "stopssh" ) {
        my $exit_code = 1;
        eval {
            $exit_code = 0;
        };
        if ($@) {
            warn "Got Error: $@\n";
            exit $exit_code;
        }
        exit $exit_code;
    }

    elsif ( $command eq "start" ) {
    my $exit_code = 10;
    eval {
        my $new_master_handler = new MHA::DBHelper();
        $new_master_handler->connect( $new_master_ip, $new_master_port,
        	$new_master_user, $new_master_password, 1 );
        print "Set read_only=0 on the new master.\n";
        $new_master_handler->disable_read_only();
        $new_master_handler->disconnect();
        &stop_vip();
        #$cmd = `ssh '.$ssh_user.'@'.$orig_master_ip.' \'/root/masterha/bin/lvs-admin stop\'`;
        #system($cmd);
        $exit_code = 0;
    };

    if ($@) {
        warn $@;
        exit $exit_code;
        }
    	exit $exit_code;
    }

    elsif ( $command eq "status" ) {
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}
sub stop_vip() {
    return 0 unless ($ssh_user);
    #`ssh $ssh_user\@$orig_master_host \" /root/masterha/bin/lvs-admin stop \"`;
    `ssh $ssh_user\@$orig_master_host \" $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";
}

2) master_ip_online_change

#!/bin/bash
source /root/.bash_profile

command=`echo "$1" | awk -F = '{print $2}'`
orig_master_host=`echo "$2" | awk -F = '{print $2}'`
new_master_host=`echo "$7" | awk -F = '{print $2}'`
orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`
new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`

#启停 keepalived
stop_vip=`echo "ssh root@$orig_master_host /root/lvs-admin stop"`
start_orig_vip=`echo "ssh root@$orig_master_host /root/lvs-admin start"`
start_vip=`echo "ssh root@$new_master_host /root/lvs-admin start"`

#start_vip=`echo "ssh $ssh_user@$new_master_host /root/lvs-admin start"`


if [ $command = 'stop' ]
  then
    echo -e "\n\n\n****************************\n"
    echo -e "Disabled thi VIP - $vip on old master: $orig_master_host \n"
    $stop_vip
    if [ $? -eq 0 ]
      then
    echo "Disabled the VIP successfully"
      else
    echo "Disabled the VIP failed"
    fi
    echo -e "***************************\n\n\n"
  fi

if [ $command = 'start' -o $command = 'status' ]
  then
    echo -e "\n\n\n*************************\n"
    echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"
    $start_vip
    if [ $? -eq 0 ]
      then
    echo "Enabled the VIP successfully"
      else
    echo "Enabled the VIP failed"
    fi
    echo -e "***************************\n\n\n"
    
    sleep 3
    echo -e "\n\n\n*************************\n"
    echo -e "Enabling the keepalived on old master: $orig_master_host \n"
    $start_orig_vip
    if [ $? -eq 0 ]
      then
    echo "Enabled the keepalived successfully"
      else
    echo "Enabled the keepalived failed"
    fi
    echo -e "***************************\n\n\n"
    
    
fi

3) lvs-admin

case "$1" in
	"stop")
	echo;
	echo "stop keepalived......";
	pkill keepalived
	;;
	"start")
	echo;
	echo "start keepalived......";
	/usr/local/keepalived/sbin/keepalived -f /usr/local/keepalived/etc/keepalived/keepalived.conf &
	;;
esac
十、测试
1、检查 SSH 的配置
/usr/bin/masterha_check_ssh --conf=/root/masterha/app1.cnf

输出:All SSH connection tests passed successfully. 则为正常

[root@ip135 masterha]# /home/mysql/mha_soft/manager/bin/masterha_check_ssh --conf=/home/mysql/mha_soft/masterha/app1.cnf
Sun Jun 14 08:23:00 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Jun 14 08:23:00 2020 - [info] Reading application default configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 08:23:00 2020 - [info] Reading server configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 08:23:00 2020 - [info] Starting SSH connection tests..
Sun Jun 14 08:23:03 2020 - [debug]
Sun Jun 14 08:23:01 2020 - [debug]  Connecting via SSH from root@192.168.136.136(192.168.136.136:22) to root@192.168.136.135(192.168.136.135:22)..
Sun Jun 14 08:23:02 2020 - [debug]   ok.
Sun Jun 14 08:23:02 2020 - [debug]  Connecting via SSH from root@192.168.136.136(192.168.136.136:22) to root@192.168.136.137(192.168.136.137:22)..
Sun Jun 14 08:23:03 2020 - [debug]   ok.
Sun Jun 14 08:23:03 2020 - [debug]
Sun Jun 14 08:23:00 2020 - [debug]  Connecting via SSH from root@192.168.136.135(192.168.136.135:22) to root@192.168.136.136(192.168.136.136:22)..
Sun Jun 14 08:23:01 2020 - [debug]   ok.
Sun Jun 14 08:23:01 2020 - [debug]  Connecting via SSH from root@192.168.136.135(192.168.136.135:22) to root@192.168.136.137(192.168.136.137:22)..
Sun Jun 14 08:23:02 2020 - [debug]   ok.
Sun Jun 14 08:23:04 2020 - [debug]
Sun Jun 14 08:23:01 2020 - [debug]  Connecting via SSH from root@192.168.136.137(192.168.136.137:22) to root@192.168.136.135(192.168.136.135:22)..
Sun Jun 14 08:23:03 2020 - [debug]   ok.
Sun Jun 14 08:23:03 2020 - [debug]  Connecting via SSH from root@192.168.136.137(192.168.136.137:22) to root@192.168.136.136(192.168.136.136:22)..
Sun Jun 14 08:23:04 2020 - [debug]   ok.
Sun Jun 14 08:23:04 2020 - [info] All SSH connection tests passed successfully.
2、检查整个复制环境状况
/usr/bin/masterha_check_repl --conf=/root/masterha/app1.cnf

输出:MySQL Replication Health is OK. 则为正常

[root@ip135 bin]# /home/mysql/mha_soft/manager/bin/masterha_check_repl --conf=/home/mysql/mha_soft/masterha/app1.cnf
Sun Jun 14 08:29:17 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Jun 14 08:29:17 2020 - [info] Reading application default configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 08:29:17 2020 - [info] Reading server configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 08:29:17 2020 - [info] MHA::MasterMonitor version 0.58.
Sun Jun 14 08:29:19 2020 - [info] GTID failover mode = 1
Sun Jun 14 08:29:19 2020 - [info] Dead Servers:
Sun Jun 14 08:29:19 2020 - [info] Alive Servers:
Sun Jun 14 08:29:19 2020 - [info]   192.168.136.135(192.168.136.135:3306)
Sun Jun 14 08:29:19 2020 - [info]   192.168.136.136(192.168.136.136:3306)
Sun Jun 14 08:29:19 2020 - [info]   192.168.136.137(192.168.136.137:3306)
Sun Jun 14 08:29:19 2020 - [info] Alive Slaves:
Sun Jun 14 08:29:19 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 08:29:19 2020 - [info]     GTID ON
Sun Jun 14 08:29:19 2020 - [info]     Replicating from 192.168.136.136(192.168.136.136:3306)
Sun Jun 14 08:29:19 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 08:29:19 2020 - [info]   192.168.136.137(192.168.136.137:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 08:29:19 2020 - [info]     GTID ON
Sun Jun 14 08:29:19 2020 - [info]     Replicating from 192.168.136.136(192.168.136.136:3306)
Sun Jun 14 08:29:19 2020 - [info] Current Alive Master: 192.168.136.136(192.168.136.136:3306)
Sun Jun 14 08:29:19 2020 - [info] Checking slave configurations..
Sun Jun 14 08:29:19 2020 - [info]  read_only=1 is not set on slave 192.168.136.135(192.168.136.135:3306).
Sun Jun 14 08:29:19 2020 - [info]  read_only=1 is not set on slave 192.168.136.137(192.168.136.137:3306).
Sun Jun 14 08:29:19 2020 - [info] Checking replication filtering settings..
Sun Jun 14 08:29:19 2020 - [info]  binlog_do_db= , binlog_ignore_db=
Sun Jun 14 08:29:19 2020 - [info]  Replication filtering check ok.
Sun Jun 14 08:29:19 2020 - [info] GTID (with auto-pos) is supported. Skipping all SSH and Node package checking.
Sun Jun 14 08:29:19 2020 - [info] Checking SSH publickey authentication settings on the current master..
Sun Jun 14 08:29:19 2020 - [info] HealthCheck: SSH to 192.168.136.136 is reachable.
Sun Jun 14 08:29:19 2020 - [info]
192.168.136.136(192.168.136.136:3306) (current master)
 +--192.168.136.135(192.168.136.135:3306)
 +--192.168.136.137(192.168.136.137:3306)

Sun Jun 14 08:29:19 2020 - [info] Checking replication health on 192.168.136.135..
Sun Jun 14 08:29:19 2020 - [info]  ok.
Sun Jun 14 08:29:19 2020 - [info] Checking replication health on 192.168.136.137..
Sun Jun 14 08:29:19 2020 - [info]  ok.
Sun Jun 14 08:29:19 2020 - [info] Checking master_ip_failover_script status:
Sun Jun 14 08:29:19 2020 - [info]   /home/mysql/mha_soft/masterha/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.136.136 --orig_master_ip=192.168.136.136 --orig_master_port=3306


IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.136.130/24===

Checking the Status of the script.. OK
Sun Jun 14 08:29:19 2020 - [info]  OK.
Sun Jun 14 08:29:19 2020 - [warning] shutdown_script is not defined.
Sun Jun 14 08:29:19 2020 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.
3、启动 MHA
nohup /usr/bin/masterha_manager --conf=/root/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /root/masterha/manager.log 2>&1 &

日志打印: Ping(CONNECT) succeeded, waiting until MySQL doesn’t respond… 则成功启动

启动日志

[root@ip135 masterha]# cat /home/mysql/mha_soft/masterha/mhalog/manager.log
Sun Jun 14 10:00:25 2020 - [info] MHA::MasterMonitor version 0.58.
Sun Jun 14 10:00:26 2020 - [info] GTID failover mode = 1
Sun Jun 14 10:00:26 2020 - [info] Dead Servers:
Sun Jun 14 10:00:26 2020 - [info] Alive Servers:
Sun Jun 14 10:00:26 2020 - [info]   192.168.136.135(192.168.136.135:3306)
Sun Jun 14 10:00:26 2020 - [info]   192.168.136.136(192.168.136.136:3306)
Sun Jun 14 10:00:26 2020 - [info]   192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:00:26 2020 - [info] Alive Slaves:
Sun Jun 14 10:00:26 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:00:26 2020 - [info]     GTID ON
Sun Jun 14 10:00:26 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:00:26 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 10:00:26 2020 - [info]   192.168.136.136(192.168.136.136:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:00:26 2020 - [info]     GTID ON
Sun Jun 14 10:00:26 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:00:26 2020 - [info] Current Alive Master: 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:00:26 2020 - [info] Checking slave configurations..
Sun Jun 14 10:00:26 2020 - [info]  read_only=1 is not set on slave 192.168.136.135(192.168.136.135:3306).
Sun Jun 14 10:00:26 2020 - [info] Checking replication filtering settings..
Sun Jun 14 10:00:26 2020 - [info]  binlog_do_db= , binlog_ignore_db=
Sun Jun 14 10:00:26 2020 - [info]  Replication filtering check ok.
Sun Jun 14 10:00:26 2020 - [info] GTID (with auto-pos) is supported. Skipping all SSH and Node package checking.
Sun Jun 14 10:00:26 2020 - [info] Checking SSH publickey authentication settings on the current master..
Sun Jun 14 10:00:26 2020 - [info] HealthCheck: SSH to 192.168.136.137 is reachable.
Sun Jun 14 10:00:26 2020 - [info]
192.168.136.137(192.168.136.137:3306) (current master)
 +--192.168.136.135(192.168.136.135:3306)
 +--192.168.136.136(192.168.136.136:3306)

Sun Jun 14 10:00:26 2020 - [info] Checking master_ip_failover_script status:
Sun Jun 14 10:00:26 2020 - [info]   /home/mysql/mha_soft/masterha/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.136.137 --orig_master_ip=192.168.136.137 --orig_master_port=3306


IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.136.130/24===

Checking the Status of the script.. OK
Sun Jun 14 10:00:26 2020 - [info]  OK.
Sun Jun 14 10:00:26 2020 - [warning] shutdown_script is not defined.
Sun Jun 14 10:00:26 2020 - [info] Set master ping interval 1 seconds.
Sun Jun 14 10:00:26 2020 - [info] Set secondary check script: /home/mysql/mha_soft/manager/bin/masterha_secondary_check -s 192.168.136.137 -s 192.168.136.136 -s 192.168.136.135 --user=root --master_host=ip137 --master_ip=192.168.136.137 --master_port=22
Sun Jun 14 10:00:26 2020 - [info] Starting ping health check on 192.168.136.137(192.168.136.137:3306)..
Sun Jun 14 10:00:26 2020 - [info] Ping(CONNECT) succeeded, waiting until MySQL doesn't respond..
4、在线切换测试
(1)停止 MHA Manager 监控
/usr/bin/masterha_stop --conf=/root/masterha/app1.cnf

(2)进行在线切换
/usr/bin/masterha_master_switch --master_state=alive --conf=/root/masterha/app1.cnf --new_master_host=192.168.136.137 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=100
注释:--orig_master_is_new_slave 将原 master 变换成 slave,默认情况下 MHA 下不做操作
--running_updates_limit=100  故障切换时,候选master如果有延迟的话, mha 切换不能成功,加上此参数表示延迟在此时间范围内都可切换(单位为s),但是切换的时间长短是由recover 时relay 日志的大小决定

输出:Switching master to 192.168.136.137(192.168.136.137:3306) completed successfully. 则切换成功

[root@ip135 masterha]# /usr/bin/masterha_master_switch --master_state=alive --conf=/home/mysql/mha_soft/masterha/app1.cnf --new_master_host=192.168.136.137 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=100
Sun Jun 14 09:51:22 2020 - [info] MHA::MasterRotate version 0.58.
Sun Jun 14 09:51:22 2020 - [info] Starting online master switch..
Sun Jun 14 09:51:22 2020 - [info]
Sun Jun 14 09:51:22 2020 - [info] * Phase 1: Configuration Check Phase..
Sun Jun 14 09:51:22 2020 - [info]
Sun Jun 14 09:51:22 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Jun 14 09:51:22 2020 - [info] Reading application default configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 09:51:22 2020 - [info] Reading server configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 09:51:23 2020 - [info] GTID failover mode = 1
Sun Jun 14 09:51:23 2020 - [info] Current Alive Master: 192.168.136.136(192.168.136.136:3306)
Sun Jun 14 09:51:23 2020 - [info] Alive Slaves:
Sun Jun 14 09:51:23 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 09:51:23 2020 - [info]     GTID ON
Sun Jun 14 09:51:23 2020 - [info]     Replicating from 192.168.136.136(192.168.136.136:3306)
Sun Jun 14 09:51:23 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 09:51:23 2020 - [info]   192.168.136.137(192.168.136.137:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 09:51:23 2020 - [info]     GTID ON
Sun Jun 14 09:51:23 2020 - [info]     Replicating from 192.168.136.136(192.168.136.136:3306)

It is better to execute FLUSH NO_WRITE_TO_BINLOG TABLES on the master before switching. Is it ok to execute on 192.168.136.136(192.168.136.136:3306)? (YES/no): YES
Sun Jun 14 09:51:30 2020 - [info] Executing FLUSH NO_WRITE_TO_BINLOG TABLES. This may take long time..
Sun Jun 14 09:51:30 2020 - [info]  ok.
Sun Jun 14 09:51:30 2020 - [info] Checking MHA is not monitoring or doing failover..
Sun Jun 14 09:51:30 2020 - [info] Checking replication health on 192.168.136.135..
Sun Jun 14 09:51:30 2020 - [info]  ok.
Sun Jun 14 09:51:30 2020 - [info] Checking replication health on 192.168.136.137..
Sun Jun 14 09:51:30 2020 - [info]  ok.
Sun Jun 14 09:51:30 2020 - [info] 192.168.136.137 can be new master.
Sun Jun 14 09:51:30 2020 - [info]
From:
192.168.136.136(192.168.136.136:3306) (current master)
 +--192.168.136.135(192.168.136.135:3306)
 +--192.168.136.137(192.168.136.137:3306)

To:
192.168.136.137(192.168.136.137:3306) (new master)
 +--192.168.136.135(192.168.136.135:3306)
 +--192.168.136.136(192.168.136.136:3306)

Starting master switch from 192.168.136.136(192.168.136.136:3306) to 192.168.136.137(192.168.136.137:3306)? (yes/NO): yes
Sun Jun 14 09:51:33 2020 - [info] Checking whether 192.168.136.137(192.168.136.137:3306) is ok for the new master..
Sun Jun 14 09:51:33 2020 - [info]  ok.
Sun Jun 14 09:51:33 2020 - [info] 192.168.136.136(192.168.136.136:3306): SHOW SLAVE STATUS returned empty result. To check replication filtering rules, temporarily executing CHANGE MASTER to a dummy host.
Sun Jun 14 09:51:33 2020 - [info] 192.168.136.136(192.168.136.136:3306): Resetting slave pointing to the dummy host.
Sun Jun 14 09:51:33 2020 - [info] ** Phase 1: Configuration Check Phase completed.
Sun Jun 14 09:51:33 2020 - [info]
Sun Jun 14 09:51:33 2020 - [info] * Phase 2: Rejecting updates Phase..
Sun Jun 14 09:51:33 2020 - [info]
Sun Jun 14 09:51:33 2020 - [info] Executing master ip online change script to disable write on the current master:
Sun Jun 14 09:51:33 2020 - [info]   /home/mysql/mha_soft/masterha/bin/master_ip_online_change --command=stop --orig_master_host=192.168.136.136 --orig_master_ip=192.168.136.136 --orig_master_port=3306 --orig_master_user='rootmha' --new_master_host=192.168.136.137 --new_master_ip=192.168.136.137 --new_master_port=3306 --new_master_user='rootmha' --orig_master_ssh_user=root --new_master_ssh_user=root   --orig_master_is_new_slave --orig_master_password=xxx --new_master_password=xxx



****************************

Disabled thi VIP - 192.168.136.130/24 on old master: 192.168.136.136

Disabled the VIP successfully
***************************



Sun Jun 14 09:51:34 2020 - [info]  ok.
Sun Jun 14 09:51:34 2020 - [info] Locking all tables on the orig master to reject updates from everybody (including root):
Sun Jun 14 09:51:34 2020 - [info] Executing FLUSH TABLES WITH READ LOCK..
Sun Jun 14 09:51:34 2020 - [info]  ok.
Sun Jun 14 09:51:34 2020 - [info] Orig master binlog:pos is mysql-binlog.000006:784.
Sun Jun 14 09:51:34 2020 - [info]  Waiting to execute all relay logs on 192.168.136.137(192.168.136.137:3306)..
Sun Jun 14 09:51:34 2020 - [info]  master_pos_wait(mysql-binlog.000006:784) completed on 192.168.136.137(192.168.136.137:3306). Executed 0 events.
Sun Jun 14 09:51:34 2020 - [info]   done.
Sun Jun 14 09:51:34 2020 - [info] Getting new master's binlog name and position..
Sun Jun 14 09:51:34 2020 - [info]  mysql-binlog.000001:744
Sun Jun 14 09:51:34 2020 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.136.137', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';
Sun Jun 14 09:51:34 2020 - [info] Executing master ip online change script to allow write on the new master:
Sun Jun 14 09:51:34 2020 - [info]   /home/mysql/mha_soft/masterha/bin/master_ip_online_change --command=start --orig_master_host=192.168.136.136 --orig_master_ip=192.168.136.136 --orig_master_port=3306 --orig_master_user='rootmha' --new_master_host=192.168.136.137 --new_master_ip=192.168.136.137 --new_master_port=3306 --new_master_user='rootmha' --orig_master_ssh_user=root --new_master_ssh_user=root   --orig_master_is_new_slave --orig_master_password=xxx --new_master_password=xxx



*************************

Enabling the VIP - 192.168.136.130/24 on new master: 192.168.136.137

Enabled the VIP successfully
***************************



Sun Jun 14 09:51:34 2020 - [info]  ok.
Sun Jun 14 09:51:34 2020 - [info]
Sun Jun 14 09:51:34 2020 - [info] * Switching slaves in parallel..
Sun Jun 14 09:51:34 2020 - [info]
Sun Jun 14 09:51:34 2020 - [info] -- Slave switch on host 192.168.136.135(192.168.136.135:3306) started, pid: 7681
Sun Jun 14 09:51:34 2020 - [info]
Sun Jun 14 09:51:35 2020 - [info] Log messages from 192.168.136.135 ...
Sun Jun 14 09:51:35 2020 - [info]
Sun Jun 14 09:51:34 2020 - [info]  Waiting to execute all relay logs on 192.168.136.135(192.168.136.135:3306)..
Sun Jun 14 09:51:34 2020 - [info]  master_pos_wait(mysql-binlog.000006:784) completed on 192.168.136.135(192.168.136.135:3306). Executed 0 events.
Sun Jun 14 09:51:34 2020 - [info]   done.
Sun Jun 14 09:51:34 2020 - [info]  Resetting slave 192.168.136.135(192.168.136.135:3306) and starting replication from the new master 192.168.136.137(192.168.136.137:3306)..
Sun Jun 14 09:51:34 2020 - [info]  Executed CHANGE MASTER.
Sun Jun 14 09:51:34 2020 - [info]  Slave started.
Sun Jun 14 09:51:35 2020 - [info] End of log messages from 192.168.136.135 ...
Sun Jun 14 09:51:35 2020 - [info]
Sun Jun 14 09:51:35 2020 - [info] -- Slave switch on host 192.168.136.135(192.168.136.135:3306) succeeded.
Sun Jun 14 09:51:35 2020 - [info] Unlocking all tables on the orig master:
Sun Jun 14 09:51:35 2020 - [info] Executing UNLOCK TABLES..
Sun Jun 14 09:51:35 2020 - [info]  ok.
Sun Jun 14 09:51:35 2020 - [info] Starting orig master as a new slave..
Sun Jun 14 09:51:35 2020 - [info]  Resetting slave 192.168.136.136(192.168.136.136:3306) and starting replication from the new master 192.168.136.137(192.168.136.137:3306)..
Sun Jun 14 09:51:35 2020 - [info]  Executed CHANGE MASTER.
Sun Jun 14 09:51:35 2020 - [info]  Slave started.
Sun Jun 14 09:51:35 2020 - [info] All new slave servers switched successfully.
Sun Jun 14 09:51:35 2020 - [info]
Sun Jun 14 09:51:35 2020 - [info] * Phase 5: New master cleanup phase..
Sun Jun 14 09:51:35 2020 - [info]
Sun Jun 14 09:51:35 2020 - [info]  192.168.136.137: Resetting slave info succeeded.
Sun Jun 14 09:51:35 2020 - [info] Switching master to 192.168.136.137(192.168.136.137:3306) completed successfully.
5、Master 异常宕机
#模拟主库异常宕机
ps -ef | grep mysqld | grep -v grep | awk '{print $2}' | xargs kill -9

日志打印:Master failover to 192.168.136.136(192.168.136.136:3306) completed successfully. 则成功宕机切换

宕机切换日志

[root@ip135 masterha]# tail -f /home/mysql/mha_soft/masterha/mhalog/manager.log
Sun Jun 14 10:04:13 2020 - [warning] Got error on MySQL connect ping: DBI connect(';host=192.168.136.137;port=3306;mysql_connect_timeout=1','rootmha',...) failed: Can't connect to MySQL server on '192.168.136.137' (111) at /home/mysql/mha_soft/manager/lib/perl5//MHA/HealthCheck.pm line 98.
2003 (Can't connect to MySQL server on '192.168.136.137' (111))
Sun Jun 14 10:04:13 2020 - [info] Executing secondary network check script: /home/mysql/mha_soft/manager/bin/masterha_secondary_check -s 192.168.136.137 -s 192.168.136.136 -s 192.168.136.135 --user=root --master_host=ip137 --master_ip=192.168.136.137 --master_port=22  --user=root  --master_host=192.168.136.137  --master_ip=192.168.136.137  --master_port=3306 --master_user=rootmha --master_password=rootmha --ping_type=CONNECT
Sun Jun 14 10:04:13 2020 - [info] Executing SSH check script: exit 0
Sun Jun 14 10:04:13 2020 - [info] HealthCheck: SSH to 192.168.136.137 is reachable.
Monitoring server 192.168.136.137 is reachable, Master is not reachable from 192.168.136.137. OK.
Sun Jun 14 10:04:14 2020 - [warning] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '192.168.136.137' (111))
Sun Jun 14 10:04:14 2020 - [warning] Connection failed 2 time(s)..
Monitoring server 192.168.136.136 is reachable, Master is not reachable from 192.168.136.136. OK.
Monitoring server 192.168.136.135 is reachable, Master is not reachable from 192.168.136.135. OK.
Sun Jun 14 10:04:14 2020 - [info] Master is not reachable from all other monitoring servers. Failover should start.
Sun Jun 14 10:04:15 2020 - [warning] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '192.168.136.137' (111))
Sun Jun 14 10:04:15 2020 - [warning] Connection failed 3 time(s)..
Sun Jun 14 10:04:16 2020 - [warning] Got error on MySQL connect: 2003 (Can't connect to MySQL server on '192.168.136.137' (111))
Sun Jun 14 10:04:16 2020 - [warning] Connection failed 4 time(s)..
Sun Jun 14 10:04:16 2020 - [warning] Master is not reachable from health checker!
Sun Jun 14 10:04:16 2020 - [warning] Master 192.168.136.137(192.168.136.137:3306) is not reachable!
Sun Jun 14 10:04:16 2020 - [warning] SSH is reachable.
Sun Jun 14 10:04:16 2020 - [info] Connecting to a master server failed. Reading configuration file /etc/masterha_default.cnf and /home/mysql/mha_soft/masterha/app1.cnf again, and trying to connect to all servers to check server status..
Sun Jun 14 10:04:16 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Jun 14 10:04:16 2020 - [info] Reading application default configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 10:04:16 2020 - [info] Reading server configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 10:04:17 2020 - [info] GTID failover mode = 1
Sun Jun 14 10:04:17 2020 - [info] Dead Servers:
Sun Jun 14 10:04:17 2020 - [info]   192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:17 2020 - [info] Alive Servers:
Sun Jun 14 10:04:17 2020 - [info]   192.168.136.135(192.168.136.135:3306)
Sun Jun 14 10:04:17 2020 - [info]   192.168.136.136(192.168.136.136:3306)
Sun Jun 14 10:04:17 2020 - [info] Alive Slaves:
Sun Jun 14 10:04:17 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:17 2020 - [info]     GTID ON
Sun Jun 14 10:04:17 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:17 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 10:04:17 2020 - [info]   192.168.136.136(192.168.136.136:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:17 2020 - [info]     GTID ON
Sun Jun 14 10:04:17 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:17 2020 - [info] Checking slave configurations..
Sun Jun 14 10:04:17 2020 - [info]  read_only=1 is not set on slave 192.168.136.135(192.168.136.135:3306).
Sun Jun 14 10:04:17 2020 - [info] Checking replication filtering settings..
Sun Jun 14 10:04:17 2020 - [info]  Replication filtering check ok.
Sun Jun 14 10:04:17 2020 - [info] Master is down!
Sun Jun 14 10:04:17 2020 - [info] Terminating monitoring script.
Sun Jun 14 10:04:17 2020 - [info] Got exit code 20 (Master dead).
Sun Jun 14 10:04:17 2020 - [info] MHA::MasterFailover version 0.58.
Sun Jun 14 10:04:17 2020 - [info] Starting master failover.
Sun Jun 14 10:04:17 2020 - [info]
Sun Jun 14 10:04:17 2020 - [info] * Phase 1: Configuration Check Phase..
Sun Jun 14 10:04:17 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] GTID failover mode = 1
Sun Jun 14 10:04:18 2020 - [info] Dead Servers:
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info] Checking master reachability via MySQL(double check)...
Sun Jun 14 10:04:18 2020 - [info]  ok.
Sun Jun 14 10:04:18 2020 - [info] Alive Servers:
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.135(192.168.136.135:3306)
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.136(192.168.136.136:3306)
Sun Jun 14 10:04:18 2020 - [info] Alive Slaves:
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.136(192.168.136.136:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info] Starting GTID based failover.
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] ** Phase 1: Configuration Check Phase completed.
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] * Phase 2: Dead Master Shutdown Phase..
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] Forcing shutdown so that applications never connect to the current master..
Sun Jun 14 10:04:18 2020 - [info] Executing master IP deactivation script:
Sun Jun 14 10:04:18 2020 - [info]   /home/mysql/mha_soft/masterha/bin/master_ip_failover --orig_master_host=192.168.136.137 --orig_master_ip=192.168.136.137 --orig_master_port=3306 --command=stopssh --ssh_user=root


IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.136.130/24===

Disabling the VIP on old master: 192.168.136.137
Sun Jun 14 10:04:18 2020 - [info]  done.
Sun Jun 14 10:04:18 2020 - [warning] shutdown_script is not set. Skipping explicit shutting down of the dead master.
Sun Jun 14 10:04:18 2020 - [info] * Phase 2: Dead Master Shutdown Phase completed.
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] * Phase 3: Master Recovery Phase..
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] * Phase 3.1: Getting Latest Slaves Phase..
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] The latest binary log file/position on all slaves is mysql-binlog.000001:744
Sun Jun 14 10:04:18 2020 - [info] Latest slaves (Slaves that received relay log files to the latest):
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.136(192.168.136.136:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info] The oldest binary log file/position on all slaves is mysql-binlog.000001:744
Sun Jun 14 10:04:18 2020 - [info] Oldest slaves:
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.136(192.168.136.136:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] * Phase 3.3: Determining New Master Phase..
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] Searching new master from slaves..
Sun Jun 14 10:04:18 2020 - [info]  Candidate masters from the configuration file:
Sun Jun 14 10:04:18 2020 - [info]  Non-candidate masters:
Sun Jun 14 10:04:18 2020 - [info]   192.168.136.135(192.168.136.135:3306)  Version=5.7.30-log (oldest major version between slaves) log-bin:enabled
Sun Jun 14 10:04:18 2020 - [info]     GTID ON
Sun Jun 14 10:04:18 2020 - [info]     Replicating from 192.168.136.137(192.168.136.137:3306)
Sun Jun 14 10:04:18 2020 - [info]     Not candidate for the new Master (no_master is set)
Sun Jun 14 10:04:18 2020 - [info]  Searching from all slaves which have received the latest relay log events..
Sun Jun 14 10:04:18 2020 - [info] New master is 192.168.136.136(192.168.136.136:3306)
Sun Jun 14 10:04:18 2020 - [info] Starting master failover..
Sun Jun 14 10:04:18 2020 - [info]
From:
192.168.136.137(192.168.136.137:3306) (current master)
 +--192.168.136.135(192.168.136.135:3306)
 +--192.168.136.136(192.168.136.136:3306)

To:
192.168.136.136(192.168.136.136:3306) (new master)
 +--192.168.136.135(192.168.136.135:3306)
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info] * Phase 3.3: New Master Recovery Phase..
Sun Jun 14 10:04:18 2020 - [info]
Sun Jun 14 10:04:18 2020 - [info]  Waiting all logs to be applied..
Sun Jun 14 10:04:18 2020 - [info]   done.
Sun Jun 14 10:04:19 2020 - [info]  Replicating from the latest slave 192.168.136.135(192.168.136.135:3306) and waiting to apply..
Sun Jun 14 10:04:19 2020 - [info]  Waiting all logs to be applied on the latest slave..
Sun Jun 14 10:04:19 2020 - [info]  Resetting slave 192.168.136.136(192.168.136.136:3306) and starting replication from the new master 192.168.136.135(192.168.136.135:3306)..
Sun Jun 14 10:04:19 2020 - [info]  Executed CHANGE MASTER.
Sun Jun 14 10:04:19 2020 - [info]  Slave started.
Sun Jun 14 10:04:19 2020 - [info]  Waiting to execute all relay logs on 192.168.136.136(192.168.136.136:3306)..
Sun Jun 14 10:04:19 2020 - [info]  master_pos_wait(mysql-binlog.000002:194) completed on 192.168.136.136(192.168.136.136:3306). Executed 2 events.
Sun Jun 14 10:04:19 2020 - [info]   done.
Sun Jun 14 10:04:19 2020 - [info]   done.
Sun Jun 14 10:04:19 2020 - [info] Getting new master's binlog name and position..
Sun Jun 14 10:04:19 2020 - [info]  mysql-binlog.000006:784
Sun Jun 14 10:04:19 2020 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.136.136', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';
Sun Jun 14 10:04:19 2020 - [info] Master Recovery succeeded. File:Pos:Exec_Gtid_Set: mysql-binlog.000006, 784, 839d3796-a8a1-11ea-b1db-00505636b68c:1-2,
e741120b-a7e9-11ea-9af7-0050563bbd20:1-2
Sun Jun 14 10:04:19 2020 - [info] Executing master IP activate script:
Sun Jun 14 10:04:19 2020 - [info]   /home/mysql/mha_soft/masterha/bin/master_ip_failover --command=start --ssh_user=root --orig_master_host=192.168.136.137 --orig_master_ip=192.168.136.137 --orig_master_port=3306 --new_master_host=192.168.136.136 --new_master_ip=192.168.136.136 --new_master_port=3306 --new_master_user='rootmha'   --new_master_password=xxx
Unknown option: new_master_user
Unknown option: new_master_password


IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.136.130/24===

Enabling the VIP - 192.168.136.130/24 on the new master - 192.168.136.136
Sun Jun 14 10:04:19 2020 - [info]  OK.
Sun Jun 14 10:04:19 2020 - [info] Setting read_only=0 on 192.168.136.136(192.168.136.136:3306)..
Sun Jun 14 10:04:19 2020 - [info]  ok.
Sun Jun 14 10:04:19 2020 - [info] ** Finished master recovery successfully.
Sun Jun 14 10:04:19 2020 - [info] * Phase 3: Master Recovery Phase completed.
Sun Jun 14 10:04:19 2020 - [info]
Sun Jun 14 10:04:19 2020 - [info] * Phase 4: Slaves Recovery Phase..
Sun Jun 14 10:04:19 2020 - [info]
Sun Jun 14 10:04:19 2020 - [info]
Sun Jun 14 10:04:19 2020 - [info] * Phase 4.1: Starting Slaves in parallel..
Sun Jun 14 10:04:19 2020 - [info]
Sun Jun 14 10:04:19 2020 - [info] -- Slave recovery on host 192.168.136.135(192.168.136.135:3306) started, pid: 8005. Check tmp log /home/mysql/mha_soft/masterha/192.168.136.135_3306_20200614100417.log if it takes time..
Sun Jun 14 10:04:20 2020 - [info]
Sun Jun 14 10:04:20 2020 - [info] Log messages from 192.168.136.135 ...
Sun Jun 14 10:04:20 2020 - [info]
Sun Jun 14 10:04:19 2020 - [info]  Resetting slave 192.168.136.135(192.168.136.135:3306) and starting replication from the new master 192.168.136.136(192.168.136.136:3306)..
Sun Jun 14 10:04:19 2020 - [info]  Executed CHANGE MASTER.
Sun Jun 14 10:04:19 2020 - [info]  Slave started.
Sun Jun 14 10:04:19 2020 - [info]  gtid_wait(839d3796-a8a1-11ea-b1db-00505636b68c:1-2,
e741120b-a7e9-11ea-9af7-0050563bbd20:1-2) completed on 192.168.136.135(192.168.136.135:3306). Executed 0 events.
Sun Jun 14 10:04:20 2020 - [info] End of log messages from 192.168.136.135.
Sun Jun 14 10:04:20 2020 - [info] -- Slave on host 192.168.136.135(192.168.136.135:3306) started.
Sun Jun 14 10:04:20 2020 - [info] All new slave servers recovered successfully.
Sun Jun 14 10:04:20 2020 - [info]
Sun Jun 14 10:04:20 2020 - [info] * Phase 5: New master cleanup phase..
Sun Jun 14 10:04:20 2020 - [info]
Sun Jun 14 10:04:20 2020 - [info] Resetting slave info on the new master..
Sun Jun 14 10:04:20 2020 - [info]  192.168.136.136: Resetting slave info succeeded.
Sun Jun 14 10:04:20 2020 - [info] Master failover to 192.168.136.136(192.168.136.136:3306) completed successfully.
Sun Jun 14 10:04:20 2020 - [info] Deleted server3 entry from /home/mysql/mha_soft/masterha/app1.cnf .
Sun Jun 14 10:04:20 2020 - [info]

----- Failover Report -----

app1: MySQL Master failover 192.168.136.137(192.168.136.137:3306) to 192.168.136.136(192.168.136.136:3306) succeeded

Master 192.168.136.137(192.168.136.137:3306) is down!

Check MHA Manager logs at ip135:/home/mysql/mha_soft/masterha/mhalog/manager.log for details.

Started automated(non-interactive) failover.
Invalidated master IP address on 192.168.136.137(192.168.136.137:3306)
Selected 192.168.136.136(192.168.136.136:3306) as a new master.
192.168.136.136(192.168.136.136:3306): OK: Applying all logs succeeded.
192.168.136.136(192.168.136.136:3306): OK: Activated master IP address.
192.168.136.135(192.168.136.135:3306): OK: Slave started, replicating from 192.168.136.136(192.168.136.136:3306)
192.168.136.136(192.168.136.136:3306): Resetting slave info succeeded.
Master failover to 192.168.136.136(192.168.136.136:3306) completed successfully.
Sun Jun 14 10:04:20 2020 - [info] Sending mail..
sh: /home/mysql/mha_soft/masterha/bin/send_report: No such file or directory
Sun Jun 14 10:04:20 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/MasterFailover.pm, ln2089] Failed to send mail with return code 127:0
6、宕机恢复

修复宕掉的 Master 然后作为一个新的 slave 节点, 从 manager 日志中获取同步信息

[root@ip135 masterha]# cat  mhalog/manager.log | grep -i "All other slaves should start replication"
Sun Jun 14 10:27:27 2020 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.136.137', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';
7、模拟网络故障
#禁止 manager(192.168.136.135) 通过 22 端口访问本地
firewall-cmd --permanent --add-rich-rule="rule family="ipv4" source address="192.168.136.135" port protocol="tcp" port="22" reject"

#删除 rich-rule
firewall-cmd --remove-rich-rule 'rule family="ipv4" source address="192.168.136.135" port port="22" protocol="tcp" reject' --permanent

#重载
firewall-cmd --reload

#查看详情
firewall-cmd --list-all

因为能通过其他节点到达主库,所以切换不会发生( At least one of monitoring servers is not reachable from this script. This is likely a network problem. Failover should not happen.)

日志打印

[root@ip135 masterha]# tail -f /home/mysql/mha_soft/masterha/mhalog/manager.log
Sun Jun 14 10:45:39 2020 - [warning] Got timeout on MySQL Ping(CONNECT) child process and killed it! at /home/mysql/mha_soft/manager/lib/perl5//MHA/HealthCheck.pm line 432.
Sun Jun 14 10:45:39 2020 - [info] Executing secondary network check script: /home/mysql/mha_soft/manager/bin/masterha_secondary_check -s 192.168.136.137 -s 192.168.136.136 -s 192.168.136.135 --user=root --master_host=ip137 --master_ip=192.168.136.137 --master_port=22  --user=root  --master_host=192.168.136.137  --master_ip=192.168.136.137  --master_port=3306 --master_user=rootmha --master_password=rootmha --ping_type=CONNECT
Sun Jun 14 10:45:39 2020 - [info] Executing SSH check script: exit 0
Sun Jun 14 10:45:39 2020 - [warning] HealthCheck: SSH to 192.168.136.137 is NOT reachable.
Sun Jun 14 10:45:39 2020 - [info] Ping(CONNECT) succeeded, waiting until MySQL doesn't respond..
ssh: connect to host 192.168.136.137 port 22: Connection refused
Monitoring server 192.168.136.137 is NOT reachable!
Sun Jun 14 10:45:39 2020 - [warning] At least one of monitoring servers is not reachable from this script. This is likely a network problem. Failover should not happen.

1) 使用 masterha_secondary_check 脚本进行检查

[root@ip135 mhalog]# /usr/bin/masterha_secondary_check -s 192.168.136.135 -s 192.168.136.136 -s 192.168.136.137 --user=root --master_host=ip137 --master_ip=192.168.136.137 --master_port=22
Monitoring server 192.168.136.135 is reachable, Master is not reachable from 192.168.136.135. OK.
Master is reachable from 192.168.136.136!

2) 使用 masterha_check_ssh 脚本进行检查

[root@ip135 mhalog]# /usr/bin/masterha_check_ssh --conf=/root/masterha/app1.cnf
Tue Jun  9 13:33:31 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Tue Jun  9 13:33:31 2020 - [info] Reading application default configuration from /root/masterha/app1.cnf..
Tue Jun  9 13:33:31 2020 - [info] Reading server configuration from /root/masterha/app1.cnf..
Tue Jun  9 13:33:31 2020 - [info] Starting SSH connection tests..
Tue Jun  9 13:33:32 2020 - [error][/usr/share/perl5/vendor_perl/MHA/SSHCheck.pm, ln63]
Tue Jun  9 13:33:31 2020 - [debug]  Connecting via SSH from root@192.168.136.135(192.168.136.135:22) to root@192.168.136.136(192.168.136.136:22)..
Tue Jun  9 13:33:32 2020 - [debug]   ok.
Tue Jun  9 13:33:32 2020 - [debug]  Connecting via SSH from root@192.168.136.135(192.168.136.135:22) to root@192.168.136.137(192.168.136.137:22)..
ssh: connect to host 192.168.136.137 port 22: Connection refused
Tue Jun  9 13:33:32 2020 - [error][/usr/share/perl5/vendor_perl/MHA/SSHCheck.pm, ln111] SSH connection from root@192.168.136.135(192.168.136.135:22) to root@192.168.136.137(192.168.136.137:22) failed!
Tue Jun  9 13:33:32 2020 - [error][/usr/share/perl5/vendor_perl/MHA/SSHCheck.pm, ln63]
Tue Jun  9 13:33:32 2020 - [debug]  Connecting via SSH from root@192.168.136.137(192.168.136.137:22) to root@192.168.136.135(192.168.136.135:22)..
ssh: connect to host 192.168.136.137 port 22: Connection refused
Tue Jun  9 13:33:32 2020 - [error][/usr/share/perl5/vendor_perl/MHA/SSHCheck.pm, ln111] SSH connection from root@192.168.136.137(192.168.136.137:22) to root@192.168.136.135(192.168.136.135:22) failed!
Tue Jun  9 13:33:33 2020 - [debug]
Tue Jun  9 13:33:31 2020 - [debug]  Connecting via SSH from root@192.168.136.136(192.168.136.136:22) to root@192.168.136.135(192.168.136.135:22)..
Tue Jun  9 13:33:32 2020 - [debug]   ok.
Tue Jun  9 13:33:32 2020 - [debug]  Connecting via SSH from root@192.168.136.136(192.168.136.136:22) to root@192.168.136.137(192.168.136.137:22)..
Tue Jun  9 13:33:33 2020 - [debug]   ok.
Bizarre copy of ARRAY in scalar assignment at /usr/share/perl5/vendor_perl/Carp.pm line 182.
总结
#检查 SSH 的配置
/usr/bin/masterha_check_ssh --conf=/root/masterha/app1.cnf

#检查整个复制环境状况
/usr/bin/masterha_check_repl --conf=/root/masterha/app1.cnf

#检查 MHA Manager 的状态
/usr/bin/masterha_check_status --conf=/root/masterha/app1.cnf

#启 MHA Manager 监控
nohup /usr/bin/masterha_manager --conf=/root/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /root/masterha/manager.log 2>&1 &

#关闭 MHA Manager 监控
/usr/bin/masterha_stop --conf=/root/masterha/app1.cnf


#在线进行切换
(1)停止 MHA Manager 监控
/usr/bin/masterha_stop --conf=/root/masterha/app1.cnf

(2)进行在线切换
/usr/bin/masterha_master_switch --master_state=alive --conf=/root/masterha/app1.cnf --new_master_host=192.168.136.137 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=100
十一、常见报错
1、检查 SSH 的配置时报错

Can’t locate MHA/SSHCheck.pm

[root@ip135 mha_soft]# /home/mysql/mha_soft/manager/bin/masterha_check_ssh --conf=/home/mysql/mha_soft/masterha/app1.cnf
Can't locate MHA/SSHCheck.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /home/mysql/mha_soft/manager/bin/masterha_check_ssh line 25.
BEGIN failed--compilation aborted at /home/mysql/mha_soft/manager/bin/masterha_check_ssh line 25.

解决方法:编辑 ~/.bashrc 或者 /etc/bashrc 文件,将 $MHAHOMQE/lib/perl5/ 添加到环境变量中

vi ~/.bashrc

PERL5LIB=/home/mysql/mha_soft/node/lib/perl5/:/home/mysql/mha_soft/manager/lib/perl5/
export PERL5LIB


source ~/.bashrc
2、检查整个复制环境状况报错

Can’t exec “apply_diff_relay_logs”: No such file or directory at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 116.

[root@ip135 mha_soft]# /home/mysql/mha_soft/manager/bin/masterha_check_repl --conf=/home/mysql/mha_soft/masterha/app1.cnf
Sun Jun 14 08:46:26 2020 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Sun Jun 14 08:46:26 2020 - [info] Reading application default configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 08:46:26 2020 - [info] Reading server configuration from /home/mysql/mha_soft/masterha/app1.cnf..
Sun Jun 14 08:46:26 2020 - [info] MHA::MasterMonitor version 0.58.
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm, ln150] Can't exec "apply_diff_relay_logs": No such file or directory at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 116.
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/MasterMonitor.pm, ln427] Error happened on checking configurations. Can't exec "apply_diff_relay_logs": No such file or directory at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 116.
        ...propagated at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 151.
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Sun Jun 14 08:46:26 2020 - [info] Got exit code 1 (Not master dead).
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm, ln122] Got error when getting node version. Error:
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm, ln123]

MySQL Replication Health is NOT OK!
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm, ln150] Use of uninitialized value $host in concatenation (.) or string at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 139.
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/MasterMonitor.pm, ln427] Error happened on checking configurations. Use of uninitialized value $host in concatenation (.) or string at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 139.
        ...propagated at /home/mysql/mha_soft/manager/lib/perl5//MHA/ManagerUtil.pm line 151.
Sun Jun 14 08:46:26 2020 - [error][/home/mysql/mha_soft/manager/lib/perl5//MHA/MasterMonitor.pm, ln525] Error happened on monitoring servers.
Sun Jun 14 08:46:26 2020 - [info] Got exit code 1 (Not master dead).

MySQL Replication Health is NOT OK!

解决方法:将 $MHAHOMQE/bin 软连接到 /usr/bin/

ln -s /home/mysql/mha_soft/node/bin/* /usr/bin/
ln -s /home/mysql/mha_soft/manager/bin/* /usr/bin/