#安装半同步复制从库插件
[root@MySQL-slave01 ~]# mysql
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected, 1 warning (0.76 sec)
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
-> FROM INFORMATION_SCHEMA.PLUGINS
-> WHERE PLUGIN_NAME LIKE '%semi%';
+---------------------+---------------+
| PLUGIN_NAME | PLUGIN_STATUS |
+---------------------+---------------+
| rpl_semi_sync_slave | ACTIVE |
+---------------------+---------------+
1 row in set (0.01 sec)
#修改配置文件
[root@MySQL-slave01 ~]# vim /etc/my.cnf
[mysqld]
server-id=3
read-only = on
plugin-load-add=rpl_semi_sync_master.so #加载半同步复制从库插件
rpl_semi_sync_slave_enabled = on #启用半同步复制
log-bin=/data/mysql/logbin/mysql-bin
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
default_storage_engine=InnoDB
character_set_server=utf8mb4
[mysql]
user=root
password=root@123456
socket=/data/mysql/mysql.sock
default-character-set = utf8mb4
[client]
socket=/data/mysql/mysql.sock
#重启生效
[root@MySQL-slave01 ~]# systemctl restart mysqld
(3)主节点状态验证
[root@MySQL-master ~]# mysql
mysql> show global status like '%semi%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 2 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 1 |
| Rpl_semi_sync_master_no_tx | 4 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+--------------------------------------------+-------+
14 rows in set (0.04 sec)
三、MySQL中间件代理服务
1.MyCat
Cluster Role
System
IP
Hostname
Client
Rocky8.10
1010.0.0.10
Client
Mycat
Rocky8.10
1010.0.0.100
Mycat
Master
Rocky8.10
1010.0.0.8
MySQL-master
Slave
Rocky8.10
10.0.0.18
MySQL-slave01
Slave
Rocky8.10
10.0.0.28
MySQL-slave02
(1)主节点配置(在主从同步的基础上)
powershell复制代码
#创建一个给mycat的用户(会同步给从节点)
[root@MySQL-master ~]# mysql
mysql> create user 'bai'@'10.0.0.%' identified by '123456';
Query OK, 0 rows affected (2.72 sec)
mysql> ALTER USER 'bai'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.14 sec)
mysql> grant all on mycat.* to 'bai'@'10.0.0.%';
Query OK, 0 rows affected (0.31 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.12 sec)
#创建一个mycat数据库和表t1
mysql> CREATE DATABASE IF NOT EXISTS mycat;
Query OK, 1 row affected (0.14 sec)
mysql> USE mycat;
Database changed
mysql> CREATE TABLE IF NOT EXISTS t1 (
-> id INT AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(20) NOT NULL
-> );
Query OK, 0 rows affected (0.71 sec)
mysql> INSERT INTO t1 (name) VALUES ('yue');
Query OK, 1 row affected (0.24 sec)
#若是自定义的mysql.log路径,需要开启通用查询日志(主节点和从节点都需要开启)
[root@MySQL-master ~]# mysql
mysql> SET GLOBAL general_log = ON;
Query OK, 0 rows affected (0.33 sec)
mysql> SHOW VARIABLES LIKE 'general_log_file';
+------------------+------------------------------+
| Variable_name | Value |
+------------------+------------------------------+
| general_log_file | /data/mysql/MySQL-master.log |
+------------------+------------------------------+
1 row in set (0.29 sec)
[root@MySQL-slave01 ~]# mysql
mysql> SET GLOBAL general_log = ON;
Query OK, 0 rows affected (0.07 sec)
mysql> SHOW VARIABLES LIKE 'general_log_file';
\+------------------+-------------------------------+
| Variable_name | Value |
+------------------+-------------------------------+
| general_log_file | /data/mysql/MySQL-slave01.log |
+------------------+-------------------------------+
1 row in set (0.35 sec)
[root@MySQL-slave02 ~]# mysql
mysql> SET GLOBAL general_log = ON;
Query OK, 0 rows affected (0.07 sec)
mysql> SHOW VARIABLES LIKE 'general_log_file';
\+------------------+-------------------------------+
| Variable_name | Value |
+------------------+-------------------------------+
| general_log_file | /data/mysql/MySQL-slave02.log |
+------------------+-------------------------------+
1 row in set (0.35 sec)
(2)配置Mycat服务器
powershell复制代码
##安装Mycat-1.6.7.6
[root@Mycat ~]# yum -y install java
[root@Mycat ~]# wget http://dl.mycat.org.cn/1.6.7.6/20210303094759/Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz
[root@Mycat ~]# mkdir /apps
[root@Mycat ~]# tar xvf Mycat-server-1.6.7.6-release-20210303094759-linux.tar.gz -C /apps
[root@Mycat ~]# chmod -R 755 /apps/mycat/
[root@Mycat ~]# chown -R root:root /apps/mycat/
#配置环境变量
[root@Mycat ~]# echo 'PATH=/apps/mycat/bin:$PATH' > /etc/profile.d/mycat.sh
[root@Mycat ~]# . /etc/profile.d/mycat.sh
[root@Mycat ~]# echo $PATH
/apps/mycat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
#启动Mycat
[root@Mycat ~]# mycat strat
#修改配置文件(可以修改Mycat的端口号和默认用户名,密码)
[root@Mycat ~]# vim /apps/mycat/conf/server.xml
...省略...
<property name="serverPort">3306</property>
...省略...
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">TESTDB</property>
<property name="defaultSchema">TESTDB</property>
[root@Mycat ~]# vim /apps/mycat/conf/schema.xml
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
</schema>
<dataNode name="dn1" dataHost="localhost1" database="mycat" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
<heartbeat>select 1</heartbeat>
<writeHost host="host1" url="10.0.0.8:3306" user="bai" password="123456">
<readHost host="host2" url="10.0.0.18:3306" user="bai" password="123456" />
<readHost host="host3" url="10.0.0.28:3306" user="bai" password="123456" />
</writeHost>
</dataHost>
</mycat:schema>
#重新启动mycat
[root@Mycat ~]# mycat stop
Stopping Mycat-server...
Mycat-server was not running.
[root@Mycat ~]# mycat start
Starting Mycat-server...
[root@Mycat ~]# tail -f /apps/mycat/logs/wrapper.log
INFO | jvm 1 | 2026/01/27 15:02:13 | at io.mycat.config.MycatConfig.<init>(MycatConfig.java:72)
INFO | jvm 1 | 2026/01/27 15:02:13 | at io.mycat.MycatServer.<init>(MycatServer.java:180)
INFO | jvm 1 | 2026/01/27 15:02:13 | at io.mycat.MycatServer.<clinit>(MycatServer.java:121)
INFO | jvm 1 | 2026/01/27 15:02:13 | ... 7 more
STATUS | wrapper | 2026/01/27 15:02:15 | <-- Wrapper Stopped
STATUS | wrapper | 2026/01/27 15:02:51 | --> Wrapper Started as Daemon
STATUS | wrapper | 2026/01/27 15:02:52 | Launching a JVM...
INFO | jvm 1 | 2026/01/27 15:02:52 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO | jvm 1 | 2026/01/27 15:02:52 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
INFO | jvm 1 | 2026/01/27 15:02:52 |
INFO | jvm 1 | 2026/01/27 15:02:55 | MyCAT Server startup successfully. see logs in logs/mycat.log
(3)在客户端测试
powershell复制代码
#需要安装mysql客户端
[root@Client ~]# mysql -uroot -p123456 -h 10.0.0.100 -P 3306
mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.00 sec)
mysql> use TESTDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+-----------------+
| Tables_in_mycat |
+-----------------+
| t1 |
+-----------------+
1 row in set (0.01 sec)
mysql> select * from t1;
+----+-------------+
| id | name |
+----+-------------+
| 1 | yue |
| 2 | mycat_test |
| 3 | mycat_test2 |
| 4 | mycat_test3 |
| 5 | mycat_test4 |
+----+-------------+
5 rows in set (0.01 sec)
mysql> insert into t1 (name) values ('mycat_test5');
Query OK, 1 row affected (0.39 sec)
#安装MHA的安装包
[root@mysql-mha ~]# yum -y install mha4mysql-node-0.58-0.el7.centos.noarch.rpm
[root@mysql-mha ~]# yum -y install mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
#在所有节点实现相互之间ssh key (每个节点上需要安装rsync软件包)
[root@mysql-mha ~]# ssh-keygen
[root@mysql-mha ~]# ssh-copy-id 127.0.0.1
[root@mysql-mha ~]# rsync -av .ssh 10.0.0.8:/root/
[root@mysql-mha ~]# rsync -av .ssh 10.0.0.18:/root/
[root@mysql-mha ~]# rsync -av .ssh 10.0.0.28:/root/
#建立配置文件
[root@mysql-mha ~]# mkdir /etc/mastermha
[root@mysql-mha ~]# vim /etc/mastermha/app1.cnf
[server default]
user=mhauser #用于远程连接MySQL所有节点的用户,需要管理员权限
password=123456
manager_workdir=/data/mastermha/app1/
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
ssh_user=root #用于实现远程ssh基于KEY的连接,访问二进制日志
repl_user=repluser #主从复制的用户信息
repl_password=123456
ping_interval=1 #健康性检查的时间间隔
secondary_check_script = masterha_secondary_check -s 10.0.0.18 -s 10.0.0.28 --user=root #主节点二次检测脚本
master_ip_failover_script=/usr/local/bin/master_ip_failover #切换VIP的perl脚本,不支持跨网络,也可用Keepalived实现
report_script=/usr/local/bin/sendmail.sh
check_repl_delay=0
#默认值为1,表示如果slave中从库落后主库relay_log超过100M,主库不会选择这个从库为新的master,
#因为这个从库进行恢复需要很长的时间。通过设置参数check_repl_delay=0,mha触发主从切换时会忽略复制的延时,
#对于设置candidata_master=1的从库非常有用,这样确保这个从库一定能成为最新的master。
master_binlog_dir=/data/mysql/logbin/
[server1]
candidate_master=1
hostname=10.0.0.8
[server2]
hostname=10.0.0.18 #控制故障转移时主节点选举优先级
candidate_master=1
[server3]
hostname=10.0.0.28
#相关脚本
[root@mysql-mha ~]# vim /usr/local/bin/sendmail.sh #确保安装failover邮件,并配置
echo "MHA is failover!" | mail -s "MHA Warning" 1953936927@qq.com
[root@mysql-mha ~]# vim /usr/local/bin/secondary_check_script
#!/bin/bash
/usr/bin/masterha_secondary_check -s 10.0.0.18 -p 22
[root@mysql-mha ~]# vim /usr/local/bin/master_ip_failover #确保所有节点安装net-tools
#!/usr/bin/env perl
# Copyright (C) 2011 DeNA Co.,Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
## Note: This is a sample script and is not complete. Modify the script based on your environment.
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
use MHA::DBHelper;
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
);
my $vip = '10.0.0.100/24';
my $key = "1";
my $ssh_start_vip = "/usr/sbin/ifconfig ens160:$key $vip";
my $ssh_stop_vip = "/usr/sbin/ifconfig ens160:$key down";
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" ) {
# $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 {
# 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 "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
&stop_vip(); #若出错,删掉
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
`ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
#授予运行权限
[root@mysql-mha ~]# chmod +x /usr/local/bin/sendmail.sh
[root@mysql-mha ~]# chmod +x /usr/local/bin/master_ip_failover
#同步给MySQL节点
[root@mysql-mha ~]# scp /usr/local/bin/master_ip_failover root@10.0.0.8:/usr/local/bin/
[root@mysql-mha ~]# scp /usr/local/bin/master_ip_failover root@10.0.0.18:/usr/local/bin/
[root@mysql-mha ~]# scp /usr/local/bin/master_ip_failover root@10.0.0.28:/usr/local/bin/
[root@mysql-mha ~]# ssh root@10.0.0.8 "chmod +x /usr/local/bin/master_ip_failover"
[root@mysql-mha ~]# ssh root@10.0.0.18 "chmod +x /usr/local/bin/master_ip_failover"
[root@mysql-mha ~]# ssh root@10.0.0.28 "chmod +x /usr/local/bin/master_ip_failover"
(2)配置master节点 (在主从复制基础上)
powershell复制代码
#安装MHA节点包
[root@MySQL-master ~]# yum -y install mha4mysql-node-0.58-0.el7.centos.noarch.rpm
#修改配置文件
[root@MySQL-master ~]# more /etc/my.cnf
[mysqld]
server-id=1
log-bin=/data/mysql/logbin/mysql-bin
skip_name_resolve = 1 #禁用 DNS 解析、仅认 IP,提升连接效率并避免 DNS 故障
general_log #观察结果,非必须项,生产无需启用
datadir=/data/mysql
socket=/data/mysql/mysql.sock
log-error=/data/mysql/mysql.log
pid-file=/data/mysql/mysql.pid
default_storage_engine=InnoDB
character_set_server=utf8mb4
[mysql]
user=root
password=root@123456
socket=/data/mysql/mysql.sock
default-character-set = utf8mb4
[client]
socket=/data/mysql/mysql.sock
#创建远程连接管理员用户
[root@MySQL-master ~]# mysql
mysql> create user mhauser@'10.0.0.%' identified by '123456';
Query OK, 0 rows affected (0.05 sec)
mysql> ALTER USER 'mhauser'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.00 sec)
mysql> grant all on *.* to mhauser@'10.0.0.%';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
#重启生效
[root@MySQL-master ~]# systemctl restart mysqld
#配置VIP
[root@mysql-mha ~]# masterha_check_ssh --conf=/etc/mastermha/app1.cnf
Fri Jan 30 10:25:50 2026 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Jan 30 10:25:50 2026 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Fri Jan 30 10:25:50 2026 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Fri Jan 30 10:25:50 2026 - [info] Starting SSH connection tests..
Fri Jan 30 10:25:51 2026 - [debug]
Fri Jan 30 10:25:50 2026 - [debug] Connecting via SSH from root@10.0.0.8(10.0.0.8:22) to root@10.0.0.18(10.0.0.18:22)..
Fri Jan 30 10:25:50 2026 - [debug] ok.
Fri Jan 30 10:25:50 2026 - [debug] Connecting via SSH from root@10.0.0.8(10.0.0.8:22) to root@10.0.0.28(10.0.0.28:22)..
Fri Jan 30 10:25:51 2026 - [debug] ok.
Fri Jan 30 10:25:53 2026 - [debug]
Fri Jan 30 10:25:51 2026 - [debug] Connecting via SSH from root@10.0.0.28(10.0.0.28:22) to root@10.0.0.8(10.0.0.8:22)..
Fri Jan 30 10:25:52 2026 - [debug] ok.
Fri Jan 30 10:25:52 2026 - [debug] Connecting via SSH from root@10.0.0.28(10.0.0.28:22) to root@10.0.0.18(10.0.0.18:22)..
Fri Jan 30 10:25:53 2026 - [debug] ok.
Fri Jan 30 10:25:53 2026 - [debug]
Fri Jan 30 10:25:50 2026 - [debug] Connecting via SSH from root@10.0.0.18(10.0.0.18:22) to root@10.0.0.8(10.0.0.8:22)..
Fri Jan 30 10:25:51 2026 - [debug] ok.
Fri Jan 30 10:25:51 2026 - [debug] Connecting via SSH from root@10.0.0.18(10.0.0.18:22) to root@10.0.0.28(10.0.0.28:22)..
Fri Jan 30 10:25:52 2026 - [debug] ok.
Fri Jan 30 10:25:53 2026 - [info] All SSH connection tests passed successfully.
[root@mysql-mha ~]# masterha_check_repl --conf=/etc/mastermha/app1.cnf
Fri Jan 30 10:26:03 2026 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Jan 30 10:26:03 2026 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Fri Jan 30 10:26:03 2026 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Fri Jan 30 10:26:03 2026 - [info] MHA::MasterMonitor version 0.58.
Fri Jan 30 10:26:05 2026 - [info] GTID failover mode = 0
Fri Jan 30 10:26:05 2026 - [info] Dead Servers:
Fri Jan 30 10:26:05 2026 - [info] Alive Servers:
Fri Jan 30 10:26:05 2026 - [info] 10.0.0.8(10.0.0.8:3306)
Fri Jan 30 10:26:05 2026 - [info] 10.0.0.18(10.0.0.18:3306)
Fri Jan 30 10:26:05 2026 - [info] 10.0.0.28(10.0.0.28:3306)
Fri Jan 30 10:26:05 2026 - [info] Alive Slaves:
Fri Jan 30 10:26:05 2026 - [info] 10.0.0.18(10.0.0.18:3306) Version=8.0.27 (oldest major version between slaves) log-bin:enabled
Fri Jan 30 10:26:05 2026 - [info] Replicating from 10.0.0.8(10.0.0.8:3306)
Fri Jan 30 10:26:05 2026 - [info] Primary candidate for the new Master (candidate_master is set)
Fri Jan 30 10:26:05 2026 - [info] 10.0.0.28(10.0.0.28:3306) Version=8.0.27 (oldest major version between slaves) log-bin:enabled
Fri Jan 30 10:26:05 2026 - [info] Replicating from 10.0.0.8(10.0.0.8:3306)
Fri Jan 30 10:26:05 2026 - [info] Current Alive Master: 10.0.0.8(10.0.0.8:3306)
Fri Jan 30 10:26:05 2026 - [info] Checking slave configurations..
Fri Jan 30 10:26:05 2026 - [info] Checking replication filtering settings..
Fri Jan 30 10:26:05 2026 - [info] binlog_do_db= , binlog_ignore_db=
Fri Jan 30 10:26:05 2026 - [info] Replication filtering check ok.
Fri Jan 30 10:26:05 2026 - [info] GTID (with auto-pos) is not supported
Fri Jan 30 10:26:05 2026 - [info] Starting SSH connection tests..
Fri Jan 30 10:26:07 2026 - [info] All SSH connection tests passed successfully.
Fri Jan 30 10:26:07 2026 - [info] Checking MHA Node version..
Fri Jan 30 10:26:08 2026 - [info] Version check ok.
Fri Jan 30 10:26:08 2026 - [info] Checking SSH publickey authentication settings on the current master..
Fri Jan 30 10:26:09 2026 - [info] HealthCheck: SSH to 10.0.0.8 is reachable.
Fri Jan 30 10:26:09 2026 - [info] Master MHA Node version is 0.58.
Fri Jan 30 10:26:09 2026 - [info] Checking recovery script configurations on 10.0.0.8(10.0.0.8:3306)..
Fri Jan 30 10:26:09 2026 - [info] Executing command: save_binary_logs --command=test --start_pos=4 --binlog_dir=/data/mysql/logbin/ --output_file=/data/mastermha/app1//save_binary_logs_test --manager_version=0.58 --start_file=mysql-bin.000007
Fri Jan 30 10:26:09 2026 - [info] Connecting to root@10.0.0.8(10.0.0.8:22)..
Creating /data/mastermha/app1 if not exists.. ok.
Checking output directory is accessible or not..
ok.
Binlog found at /data/mysql/logbin/, up to mysql-bin.000007
Fri Jan 30 10:26:09 2026 - [info] Binlog setting check done.
Fri Jan 30 10:26:09 2026 - [info] Checking SSH publickey authentication and checking recovery script configurations on all alive slave servers..
Fri Jan 30 10:26:09 2026 - [info] Executing command : apply_diff_relay_logs --command=test --slave_user='mhauser' --slave_host=10.0.0.18 --slave_ip=10.0.0.18 --slave_port=3306 --workdir=/data/mastermha/app1/ --target_version=8.0.27 --manager_version=0.58 --relay_dir=/data/mysql --current_relay_log=MySQL-slave01-relay-bin.000014 --slave_pass=xxx
Fri Jan 30 10:26:09 2026 - [info] Connecting to root@10.0.0.18(10.0.0.18:22)..
Checking slave recovery environment settings..
Relay log found at /data/mysql, up to MySQL-slave01-relay-bin.000014
Temporary relay log file is /data/mysql/MySQL-slave01-relay-bin.000014
Checking if super_read_only is defined and turned on.. not present or turned off, ignoring.
Testing mysql connection and privileges..
mysql: [Warning] Using a password on the command line interface can be insecure.
done.
Testing mysqlbinlog output.. done.
Cleaning up test file(s).. done.
Fri Jan 30 10:26:10 2026 - [info] Executing command : apply_diff_relay_logs --command=test --slave_user='mhauser' --slave_host=10.0.0.28 --slave_ip=10.0.0.28 --slave_port=3306 --workdir=/data/mastermha/app1/ --target_version=8.0.27 --manager_version=0.58 --relay_dir=/data/mysql --current_relay_log=MySQL-slave02-relay-bin.000009 --slave_pass=xxx
Fri Jan 30 10:26:10 2026 - [info] Connecting to root@10.0.0.28(10.0.0.28:22)..
Checking slave recovery environment settings..
Relay log found at /data/mysql, up to MySQL-slave02-relay-bin.000009
Temporary relay log file is /data/mysql/MySQL-slave02-relay-bin.000009
Checking if super_read_only is defined and turned on.. not present or turned off, ignoring.
Testing mysql connection and privileges..
mysql: [Warning] Using a password on the command line interface can be insecure.
done.
Testing mysqlbinlog output.. done.
Cleaning up test file(s).. done.
Fri Jan 30 10:26:12 2026 - [info] Slaves settings check done.
Fri Jan 30 10:26:12 2026 - [info]
10.0.0.8(10.0.0.8:3306) (current master)
+--10.0.0.18(10.0.0.18:3306)
+--10.0.0.28(10.0.0.28:3306)
Fri Jan 30 10:26:12 2026 - [info] Checking replication health on 10.0.0.18..
Fri Jan 30 10:26:12 2026 - [info] ok.
Fri Jan 30 10:26:12 2026 - [info] Checking replication health on 10.0.0.28..
Fri Jan 30 10:26:12 2026 - [info] ok.
Fri Jan 30 10:26:12 2026 - [info] Checking master_ip_failover_script status:
Fri Jan 30 10:26:12 2026 - [info] /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=10.0.0.8 --orig_master_ip=10.0.0.8 --orig_master_port=3306
Checking the Status of the script.. OK
Fri Jan 30 10:26:12 2026 - [info] OK.
Fri Jan 30 10:26:12 2026 - [warning] shutdown_script is not defined.
Fri Jan 30 10:26:12 2026 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.
[root@mysql-mha ~]# masterha_check_status --conf=/etc/mastermha/app1.cnf
app1 is stopped(2:NOT_RUNNING).
[root@mysql-mha ~]# nohup masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover &> /dev/null &
[1] 2639
[::]:* users:(("sshd",pid=823,fd=4))
[root@mysql-mha ~]# masterha_check_status --conf=/etc/mastermha/app1.cnf
app1 (pid:2639) is running(0:PING_OK), master:10.0.0.8
[root@mysql-mha ~]# jobs -l
[1]+ 2639 Running nohup masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover &>/dev/null &
(5)配置MHA进程开机自启
powershell复制代码
#关闭后台运行
[root@mysql-mha ~]# jobs -l
[1]+ 2639 Running nohup masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover &>/dev/null &
[root@mysql-mha ~]# masterha_stop --conf /etc/mastermha/app1.cnf
Stopped app1 successfully.
[1]+ Exit 1 nohup masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover &>/dev/null
#service启动配置文件
[root@mysql-mha ~]# vim /usr/lib/systemd/system/mha-manager.service
[Unit]
Description=MHA MySQL High Availability Manager
After=network.target mysqld.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover
ExecStop=/usr/bin/masterha_stop --conf=/etc/mastermha/app1.cnf
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
#配置生效,开机自启
[root@mysql-mha ~]# systemctl daemon-reload
[root@mysql-mha ~]# systemctl enable --now mha-manager
[root@mysql-mha ~]# systemctl status mha-manager
[root@mysql-mha ~]# masterha_check_status --conf /etc/mastermha/app1.cnf
app1 (pid:18804) is running(0:PING_OK), master:10.0.0.8
#查看MHA日志
[root@mysql-mha ~]# tail -f /data/mastermha/app1/manager.log
Fri Jan 30 14:56:11 2026 - [info] Checking master_ip_failover_script status:
Fri Jan 30 14:56:11 2026 - [info] /usr/local/bin/master_ip_failover --command=status --ssh_user=root --orig_master_host=10.0.0.8 --orig_master_ip=10.0.0.8 --orig_master_port=3306
Checking the Status of the script.. OK
Fri Jan 30 14:56:11 2026 - [info] OK.
Fri Jan 30 14:56:11 2026 - [warning] shutdown_script is not defined.
Fri Jan 30 14:56:11 2026 - [info] Set master ping interval 1 seconds.
Fri Jan 30 14:56:11 2026 - [info] Set secondary check script: /usr/local/bin/secondary_check_script
Fri Jan 30 14:56:11 2026 - [info] Starting ping health check on 10.0.0.8(10.0.0.8:3306)..
Fri Jan 30 14:56:11 2026 - [info] Ping(SELECT) succeeded, waiting until MySQL doesn't respond..
2.故障演练
(1)实例1:当主节点出现故障时
powershell复制代码
#停止主节点MySQL
[root@MySQL-master ~]# systemctl stop mysqld
[root@MySQL-master ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:e7:18:28 brd ff:ff:ff:ff:ff:ff
altname enp3s0
inet 10.0.0.8/24 brd 10.0.0.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fee7:1828/64 scope link noprefixroute
valid_lft forever preferred_lft forever
#查看从节点状态
[root@MySQL-slave01 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:5a:81:9b brd ff:ff:ff:ff:ff:ff
altname enp3s0
inet 10.0.0.18/24 brd 10.0.0.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet 10.0.0.100/24 brd 10.0.0.255 scope global secondary ens160:1 #vip漂移到了slave01 10.0.0.18上
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe5a:819b/64 scope link noprefixroute
valid_lft forever preferred_lft forever
[root@MySQL-slave02 ~]# mysql
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 10.0.0.18 #从库slave01 当选为主库
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 156
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 324
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#查看MHA状态和日志
[root@mysql-mha ~]# systemctl status mha-manager #当 master down机后,mha管理程序自动退出
● mha-manager.service - MHA MySQL High Availability Manager
Loaded: loaded (/usr/lib/systemd/system/mha-manager.service; enabled; vendor preset: disabled)
Active: inactive (dead) since Mon 2026-02-02 15:12:37 CST; 4min 8s ago
Process: 19443 ExecStop=/usr/bin/masterha_stop --conf=/etc/mastermha/app1.cnf (code=exited, status=0/SUCCESS)
Process: 19347 ExecStart=/usr/bin/masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover (code=exited, status=0/SUCCESS)
Main PID: 19347 (code=exited, status=0/SUCCESS)
Feb 02 15:12:13 mysql-mha masterha_manager[19347]: Mon Feb 2 15:12:13 2026 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Feb 02 15:12:13 mysql-mha masterha_manager[19347]: Mon Feb 2 15:12:13 2026 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Feb 02 15:12:21 mysql-mha masterha_manager[19347]: Creating /data/mastermha/app1 if not exists.. ok.
Feb 02 15:12:21 mysql-mha masterha_manager[19347]: Checking output directory is accessible or not..
Feb 02 15:12:21 mysql-mha masterha_manager[19347]: ok.
Feb 02 15:12:21 mysql-mha masterha_manager[19347]: Binlog found at /data/mysql/logbin/, up to mysql-bin.000006
Feb 02 15:12:25 mysql-mha masterha_manager[19347]: Mon Feb 2 15:12:25 2026 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Feb 02 15:12:25 mysql-mha masterha_manager[19347]: Mon Feb 2 15:12:25 2026 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Feb 02 15:12:25 mysql-mha masterha_manager[19347]: Mon Feb 2 15:12:25 2026 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
Feb 02 15:12:37 mysql-mha masterha_stop[19443]: MHA Manager is not running on app1(2:NOT_RUNNING).
[root@mysql-mha ~]# cat /data/mastermha/app1/manager.log #mha管理日志中显示的故障转移
app1: MySQL Master failover 10.0.0.8(10.0.0.8:3306) to 10.0.0.18(10.0.0.18:3306) succeeded
Master 10.0.0.8(10.0.0.8:3306) is down!
Check MHA Manager logs at mysql-mha:/data/mastermha/app1/manager.log for details.
Started automated(non-interactive) failover.
Invalidated master IP address on 10.0.0.8(10.0.0.8:3306)
The latest slave 10.0.0.18(10.0.0.18:3306) has all relay logs for recovery.
Selected 10.0.0.18(10.0.0.18:3306) as a new master.
10.0.0.18(10.0.0.18:3306): OK: Applying all logs succeeded.
10.0.0.18(10.0.0.18:3306): OK: Activated master IP address.
10.0.0.28(10.0.0.28:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
10.0.0.28(10.0.0.28:3306): OK: Applying all logs succeeded. Slave started, replicating from 10.0.0.18(10.0.0.18:3306)
10.0.0.18(10.0.0.18:3306): Resetting slave info succeeded.
Master failover to 10.0.0.18(10.0.0.18:3306) completed successfully.
#自动修改manager节点上的配置文件,将master剔除
[root@mysql-mha ~]# cat /etc/mastermha/app1.cnf
[server default]
check_repl_delay=0
manager_log=/data/mastermha/app1/manager.log
manager_workdir=/data/mastermha/app1/
master_binlog_dir=/data/mysql/logbin/
master_ip_failover_script=/usr/local/bin/master_ip_failover
password=123456
ping_interval=1
remote_workdir=/data/mastermha/app1/
repl_password=123456
repl_user=repluser
report_script=/usr/local/bin/sendmail.sh
secondary_check_script=masterha_secondary_check -s 10.0.0.18 -s 10.0.0.28 --user=root
ssh_user=root
user=mhauser
[server2]
candidate_master=1
hostname=10.0.0.18
[server3]
hostname=10.0.0.28
#重新启动10.0.0.8,使其成为10.0.0.18的从库
[root@MySQL-master ~]# systemctl start mysqld
[root@MySQL-slave01 ~]# mysqldump -uroot -p -A -F --master-data=1 --single-transaction > /data/all.sql
[root@MySQL-slave01 ~]# mysql
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000006 | 156 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.02 sec)
[root@MySQL-master ~]# vim /data/all.sq
CHANGE MASTER TO
MASTER_HOST='10.0.0.18',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000006', MASTER_LOG_POS=156;
[root@MySQL-master ~]# mysql
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
mysql> source /data/all.sql
mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.14 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 10.0.0.18
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000006
Read_Master_Log_Pos: 156
Relay_Log_File: MySQL-master-relay-bin.000002
Relay_Log_Pos: 324
Relay_Master_Log_File: mysql-bin.000006
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
#重新启动MHA-manager
[root@mysql-mha ~]# systemctl start mha-manager
[root@mysql-mha ~]# systemctl status mha-manager
● mha-manager.service - MHA MySQL High Availability Manager
Loaded: loaded (/usr/lib/systemd/system/mha-manager.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2026-02-02 15:26:11 CST; 2s ago
Process: 19443 ExecStop=/usr/bin/masterha_stop --conf=/etc/mastermha/app1.cnf (code=exited, status=0/SUCCESS)
Main PID: 19583 (perl)
CGroup: /system.slice/mha-manager.service
├─19583 perl /usr/bin/masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover
├─19590 perl /usr/bin/masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover
├─19591 sh -c ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o BatchMode=yes -o ConnectTimeout=5 -p 22 root@10.0.0.18 "ssh -o StrictHostKeyChecking=no -o PasswordAuthenticatio...
├─19592 ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o BatchMode=yes -o ConnectTimeout=5 -p 22 root@10.0.0.18 ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o...
├─19593 perl /usr/bin/masterha_manager --conf=/etc/mastermha/app1.cnf --remove_dead_master_conf --ignore_last_failover
├─19594 sh -c ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o BatchMode=yes -o ConnectTimeout=5 -p 22 root@10.0.0.28 "ssh -o StrictHostKeyChecking=no -o PasswordAuthenticatio...
└─19595 ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o BatchMode=yes -o ConnectTimeout=5 -p 22 root@10.0.0.28 ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o...
Feb 02 15:26:11 mysql-mha systemd[1]: Started MHA MySQL High Availability Manager.
Feb 02 15:26:11 mysql-mha masterha_manager[19583]: Mon Feb 2 15:26:11 2026 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Feb 02 15:26:11 mysql-mha masterha_manager[19583]: Mon Feb 2 15:26:11 2026 - [info] Reading application default configuration from /etc/mastermha/app1.cnf..
Feb 02 15:26:11 mysql-mha masterha_manager[19583]: Mon Feb 2 15:26:11 2026 - [info] Reading server configuration from /etc/mastermha/app1.cnf..
[root@mysql-mha ~]# masterha_check_status --conf /etc/mastermha/app1.cnf
app1 (pid:19583) is running(0:PING_OK), master:10.0.0.18