MySQL8.0.27高可用

文章目录

一、MySQL安装(8.0.27)

1.二进制安装

powershell 复制代码
# 临时关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 临时关闭SELinux
setenforce 0
# 永久关闭SELinux(需重启生效)
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

#安装相关包
yum -y install libaio numactl-libs ncurses-compat-libs tar wget

#用户和组
groupadd mysql
useradd -r -s /sbin/nologin -g mysql mysql

#准备程序文件
wget https://mirrors.aliyun.com/mysql/MySQL-8.0/mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz
tar -xvf mysql-8.0.27-linux-glibc2.12-x86_64.tar.xz -C /usr/local
cd /usr/local
ln -s mysql-8.0.27-linux-glibc2.12-x86_64/ mysql
chown -R root.root /usr/local/mysql

#准备环境变量
echo 'PATH=/usr/local/mysql/bin:$PATH' > /etc/profile.d/mysql.sh
. /etc/profile.d/mysql.sh

#准备配置文件
vim /etc/my.cnf
[mysqld]
[mysqld]
log-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]
socket=/data/mysql/mysql.sock
default-character-set = utf8mb4

#修改配置文件权限
chown mysql:mysql /etc/my.cnf
chmod 644 /etc/my.cnf

#初始化数据库文件并提取root密码 (在/data/mysql 会自动生成,但是/data/必须事先存在)
生成随机密码:
mysqld --initialize --user=mysql --datadir=/data/mysql

awk '/temporary password/{print $NF}' /data/mysql/mysql.log
LufavlMka6,!

#创建system启动服务
vim /usr/lib/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql
Type=notify
TimeoutSec=0
PermissionsStartOnly=true
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf $MYSQLD_OPTS
LimitNOFILE = 5000
Restart=on-failure
RestartPreventExitStatus=1
Environment=MYSQLD_PARENT_PID=1
PrivateTmp=false

# 重新加载systemd配置
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld

# 查看服务状态(显示active(running)即启动成功)
systemctl status mysqld

#登录 MySQL(使用第一步获取的临时密码)
mysql -uroot -p'LufavlMka6,!'

#修改MySQL密码
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'root@123456';

二、MySQL集群Cluster

1.主从复制

Cluster Role System IP Hostname
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 复制代码
#配置文件
[root@MySQL-master ~]# vim /etc/my.cnf  
[mysqld]
server-id=1          #唯一标识ID,非零的整数;区分主从节点;开启log-bin的必要条件,
log-bin=/data/mysql/logbin/mysql-bin    #开启并制定binlog日志路径
read_only=off
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]
port=3306
user=root            #测试环境,用户名、密码写入配置文件方便测试
password=root@123456
socket=/data/mysql/mysql.sock
default-character-set=utf8mb4

[client]
socket=/data/mysql/mysql.sock


#创建logbin目录
[root@MySQL-master ~]# mkdir -p /data/mysql/logbin
[root@MySQL-master ~]# chown -R mysql.mysql /data/mysql/logbin

#重启生效
[root@MySQL-master ~]# systemctl deamon-relod
[root@MySQL-master ~]# systemctl restart mysqld

#创建从节点连接的用户,并授予权限
[root@MySQL-master ~]#mysql
mysql> create user repluser@"10.0.0.%" identified by "123456";
Query OK, 0 rows affected (0.01 sec)                 #创建远程连接用户名密码

mysql> ALTER USER 'repluser'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY '123456'; 
Query OK, 0 rows affected (0.03 sec)                 #MySQL8.0版本必须要使用mysql_native_password密码插件

mysql> grant replication slave on *.* to repluser@"10.0.0.%";        
Query OK, 0 rows affected (0.01 sec)                 #用户权限限制

mysql> FLUSH PRIVILEGES;                             #刷新权限配置
Query OK, 0 rows affected (0.01 sec)

mysql> show master status;                           #查看最新log-bin日志位置
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      157 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

#完全备份
[root@MySQL-master ~]# mysqldump -u -proot@123456 -A -F --master-data=1 --single-transaction > /data/all.sql  #生产中输入密码一定要使用交互式

#将完全备份拷贝到从节点
[root@MySQL-master ~]# scp /data/all.sql 10.0.0.18:/data                                                         
[root@MySQL-master ~]# scp /data/all.sql 10.0.0.28:/data

(2)从节点配置(以MySQL-slave01为例)

powershell 复制代码
#配置文件
[root@MySQL-slave01 ~]# vim /etc/my.cnf 
[mysqld]
server-id = 2
read_only = on                             #从节点开启只读模式,只能查询
log-bin=/data/mysql/logbin/mysql-bin       #log-bin 从节点一般不开启;关闭 =off即可
relay_log=/data/mysql/relay-log/relay-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

#创建logbin目录
[root@MySQL-slave01 ~]# mkdir -p /data/mysql/logbin
[root@MySQL-slave01 ~]# chown -R mysql.mysql /data/mysql/logbin
[root@MySQL-slave01 ~]# mkdir -p /data/mysql/relay-log  
[root@MySQL-slave01 ~]# chown -R mysql.mysql /data/mysql/relay-log


#重启生效
[root@MySQL-slave01 ~]# systemctl deamon-relod
[root@MySQL-slave01 ~]# systemctl restart mysqld

#设置同步规则
[root@MySQL-slave01 ~]# vim /data/all.sql
-- Position to start replication or point-in-time recovery from

CHANGE MASTER TO
MASTER_HOST='10.0.0.8',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=157;
--
-- Current Database: `mysql`

#导入规则并启动
[root@MySQL-slave01 ~]# mysql
mysql> set sql_log_bin=0;                            #临时关闭log-bin日志
Query OK, 0 rows affected (0.00 sec)

mysql> source /data/all.sql        #读取指定路径的 SQL 文件,并逐行执行文件中的所有 SQL 语句。

mysql> set sql_log_bin=1;                            #开启log-bin日志
Query OK, 0 rows affected (0.00 sec)

mysql> start slave;                                  #启动复制进程,若之前就是从库source之前需要stop slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show slave status\G                           #查看Slave_IO_Running 和 Slave_SQL_Running 是否为 Yes,确认配置生效。
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.0.0.8
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 157
               Relay_Log_File: rocky8-relay-bin.000002
                Relay_Log_Pos: 1174
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes               #IO和SQL线程全是yes
            Slave_SQL_Running: Yes   
                  ...省略...     
1 row in set, 1 warning (0.00 sec)

#在主节点查看从节点
[root@MySQL-master ~]# mysql
mysql> SHOW SLAVE HOSTS;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3306 |         1 | 4eff1fe4-f1e8-11f0-a914-000c295a819b |
+-----------+------+------+-----------+--------------------------------------+

(3)测试是否同步

powershell 复制代码
#测试sql脚本,批量生成数据
[root@MySQL-master ~]# vim /data/testlog.sql 
create table testlog (id int auto_increment primary key,name char(10),salary int default 20);

delimiter $$

create procedure  sp_testlog() 
begin  
declare i int;
set i = 1; 
while i <= 100000 
do  insert into testlog(name,salary) values (concat('wang',FLOOR(RAND() * 100000)),FLOOR(RAND() * 1000000)); 
set i = i +1; 
end while; 
end$$

delimiter ;

#执行脚本
[root@MySQL-master ~]# mysql
mysql> source /data/testlog.sql;                #执行脚本,创建存储过程sp_testlog()
Query OK, 0 rows affected (0.04 sec)

mysql> call sp_testlog();                       #调用存储过程sp_testlog(),执行插入10万条数据的逻辑
Query OK, 1 row affected (3 min 47.46 sec)

mysql> SELECT COUNT(*) FROM test.testlog;
+----------+
| COUNT(*) |
+----------+
|   100000 |
+----------+
1 row in set (0.02 sec)

#同时观察Slave01、Slave02节点同步情况
[root@MySQL-slave01 ~]# mysql
mysql> SELECT COUNT(*) FROM test.testlog;
+----------+
| COUNT(*) |
+----------+
|    60036 |
+----------+
1 row in set (0.01 sec)

[root@MySQL-slave02 ~]# mysql
mysql> SELECT COUNT(*) FROM test.testlog;
+----------+
| COUNT(*) |
+----------+
|    56204 |
+----------+
1 row in set (0.39 sec)

(4)实例:当master服务器宕机,提升一个slave成为新的master

powershell 复制代码
#解析最新时间的中继日志看是否有没执行完的SQL语句,若有手动执行SQL语句,确保数据完整    (这种情况是在中继日志完全同步了主节点的log_bin)
[root@MySQL-slave01 ~]# mysqlbinlog /data/mysql/relay-log/relay-bin.000025 | tail -500   

#修改配置文件
[root@MySQL-slave01 ~]# vim /etc/my.cnf 
[mysqld]
server-id = 2
read_only = off                            #关闭只读
log-bin=/data/mysql/logbin/mysql-bin       #开启log-bin日志 
relay_log=/data/mysql/relay-log/relay-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

#清除旧的master复制信息
[root@MySQL-slave01 ~]# mysql
mysql> show variables like 'read_only';                    
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| read_only     | ON    |
+---------------+-------+
1 row in set (0.70 sec)

mysql> set global read_only=off;                        #临时生效,手动关闭只读模式read_only
Query OK, 0 rows affected (0.02 sec)

mysql> show variables like 'log_bin';                   #确认log_bin是否已经打开,ON 开启、OFF 关闭
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin       | ON    |
+---------------+-------+
1 row in set (0.01 sec)

mysql> stop slave;                                       #停止slave复制线程
Query OK, 0 rows affected, 1 warning (0.70 sec)

mysql> reset slave all;                                  #刷新slave
Query OK, 0 rows affected, 1 warning (0.14 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |      156 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.04 sec)

#在新的master上完全备份
[root@MySQL-slave01 ~]# mysqldump -uroot -p -A -F --single-transaction --source-data=1 > /data/all.sql
Enter password: 
[root@MySQL-slave01 ~]# ls /data/
all.sql  mysql
[root@MySQL-slave01 ~]# scp /data/all.sql 10.0.0.28:/data
all.sql                                                                                                  100% 3793KB  31.0MB/s   00:00    

#其他的slave重新还原数据库,指向新的master
[root@MySQL-slave02 ~]# vim /data/all.sql 

CHANGE MASTER TO
MASTER_HOST='10.0.0.18',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT='3306',
MASTER_LOG_FILE='mysql-bin.000004',
MASTER_LOG_POS=156;

#同步数据
[root@MySQL-slave02 ~]# mysql
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.01 sec)

mysql> source /data/all.sql;

mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.0.0.28
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 156
               Relay_Log_File: rocky8-relay-bin.000002
                Relay_Log_Pos: 326
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
                         ...省略...

2.级联复制

Cluster Role System IP Hostname
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 复制代码
#修改配置文件
[root@MySQL-master ~]# vim /etc/my.cnf
[mysqld]
server-id=1
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

#创建log-bin存放目录
[root@MySQL-master ~]# mkdir -p /data/mysql/logbin
[root@MySQL-master ~]# chown -R mysql.mysql /data/mysql/logbin

#重启生效
[root@MySQL-master ~]# systemctl daemon-reload
[root@MySQL-master ~]# systemctl restart mysqld
[root@MySQL-master ~]# systemctl status mysqld

#创建远程连接用户
[root@MySQL-master ~]# mysql
mysql> create user repluser@"10.0.0.%" identified by "123456";
Query OK, 0 rows affected (2.54 sec)

mysql> ALTER USER 'repluser'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.12 sec)

mysql> grant replication slave on *.* to repluser@"10.0.0.%";
Query OK, 0 rows affected (0.08 sec)

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |     1003 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.04 sec)

#完全备份并同步到节点slave01、slave02
[root@MySQL-master ~]# mysqldump -uroot -p -A -F --source-data=1 --single-transaction > /data/all.sql
[root@MySQL-master ~]# scp /data/all.sql 10.0.0.18:/data
[root@MySQL-master ~]# scp /data/all.sql 10.0.0.28:/data

(2)级联节点配置

powershell 复制代码
#修改配置文件
[root@MySQL-slave01 ~]# vim /etc/my.cnf 
[mysqld]
server-id=2
read-only = on                                    #开启只读模式
log-bin = /data/mysql/logbin/mysql-bin            #必须开启log-bin日志
log_slave_updates = on                            #让从库把从主库同步过来的事务,也写入自己的 binlog 日志中
relay_log = /data/mysql/relay-log/relay-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 ~]# mkdir -p /data/mysql/logbin
[root@MySQL-slave01 ~]# chown -R mysql.mysql /data/mysql/logbin
[root@MySQL-slave01 ~]# mkdir -p /data/mysql/relay-log  
[root@MySQL-slave01 ~]# chown -R mysql.mysql /data/mysql/relay-log

#重启生效
[root@MySQL-slave01 ~]# systemctl daemon-reload
[root@MySQL-slave01 ~]# systemctl restart mysqld


#同步数据
root@MySQL-slave01 ~]# vim /data/all.sql 
CHANGE MASTER TO
MASTER_HOST='10.0.0.8',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002', MASTER_LOG_POS= 1003;

[root@MySQL-slave01 ~]# mysql
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> source /data/all.sql
Query OK, 0 rows affected (0.00 sec)

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.09 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.0.0.8
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000002
          Read_Master_Log_Pos: 1003
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

mysql> show master logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       179 | No        |
| mysql-bin.000002 |       156 | No        |
+------------------+-----------+-----------+
2 rows in set (0.00 sec)

#在级联节点slave01刷新一下用户权限
mysql> SELECT user, host FROM user WHERE user = 'repluser';
+----------+----------+
| user     | host     |
+----------+----------+
| repluser | 10.0.0.% |
+----------+----------+
1 row in set (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.08 sec)

mysql> SHOW GRANTS FOR 'repluser'@'10.0.0.%';
+---------------------------------------------------------+
| Grants for repluser@10.0.0.%                            |
+---------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO `repluser`@`10.0.0.%` |
+---------------------------------------------------------+
1 row in set (0.03 sec)

(3)从节点配置

powershell 复制代码
#修改配置文件
[root@MySQL-slave02 ~]# more /etc/my.cnf 
[mysqld]
server-id = 3                                    
read-only = on                                       #开启只读模式
relay_log = /data/mysql/relay-log/relay-bin          #中继 日志路径
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-slave02 ~]# mkdir -p /data/mysql/logbin
[root@MySQL-slave02 ~]# chown -R mysql.mysql /data/mysql/logbin
[root@MySQL-slave02 ~]# mkdir -p /data/mysql/relay-log
[root@MySQL-slave02 ~]# chown -R mysql.mysql /data/mysql/relay-log

#重启生效
[root@MySQL-slave02 ~]# systemctl daemon-reload
[root@MySQL-slave02 ~]# systemctl restart mysql

#同步数据
[root@MySQL-slave02 ~]# vim /data/all.sql 
CHANGE MASTER TO
MASTER_HOST='10.0.0.38',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000002',
MASTER_LOG_POS=156;

[root@MySQL-slave02 ~]# mysql
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> source /data/all.sql;
Query OK, 0 rows affected (0.00 sec)

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.04 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.000002
          Read_Master_Log_Pos: 156
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 496
        Relay_Master_Log_File: mysql-bin.000002
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

#在主节点查看级联节点信息
[root@MySQL-master ~]# mysql
mysql> SHOW SLAVE HOSTS;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         2 |      | 3306 |         1 | 4eff1fe4-f1e8-11f0-a914-000c295a819b |
+-----------+------+------+-----------+--------------------------------------+

#在级联节点查看从节点信息
[root@MySQL-slave01 ~]# mysql
mysql> SHOW SLAVE HOSTS;
+-----------+------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID                           |
+-----------+------+------+-----------+--------------------------------------+
|         3 |      | 3306 |         2 | 6ab6b4a8-f274-11f0-b756-000c29a62e45 |
+-----------+------+------+-----------+--------------------------------------+

3.主主复制

Cluster Role System IP Hostname
Master Rocky8.10 1010.0.0.8 MySQL-master01
Master Rocky8.10 10.0.0.18 MySQL-master02

(1)主节点master01配置

powershell 复制代码
#修改配置文件
[root@MySQL-master01 ~]# vim /etc/my.cnf 
[mysqld]
server-id=1
log-bin=/data/mysql/logbin/mysql-bin
relay_log = /data/mysql/relay-log/relay-bin                          
auto_increment_offset=1                        #自增列的步长   offset的值必须 ≤ increment的值,否则会报错
auto_increment_increment=2                     ##自增列的起始偏移量   避免双节点自增 ID 冲突
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-master01 ~]# mkdir -p /data/mysql/logbin
[root@MySQL-master01 ~]# chown -R mysql.mysql /data/mysql/logbin
[root@MySQL-master01 ~]# mkdir -p /data/mysql/relay-log
[root@MySQL-master01 ~]# chown -R mysql.mysql /data/mysql/relay-log

#重启生效
[root@MySQL-master01 ~]# systemctl daemon-reload
[root@MySQL-master01 ~]# systemctl restart mysqld

#创建连接用户并授予权限
[root@MySQL-master01 ~]# mysql
mysql> create user repluser@"10.0.0.%" identified by "123456";
Query OK, 0 rows affected (0.27 sec)

mysql> ALTER USER 'repluser'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY '123456';
Query OK, 0 rows affected (0.04 sec)

mysql> grant replication slave on *.* to repluser@"10.0.0.%";
Query OK, 0 rows affected (0.04 sec)

mysql> show master logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       203 | No        |
| mysql-bin.000002 |       179 | No        |
| mysql-bin.000003 |       156 | No        |
+------------------+-----------+-----------+
3 rows in set (0.00 sec)

#完全备份
[root@MySQL-master01 ~]# mysqldump -uroot -p -A -F --source-data=1 --single-transaction > /data/all01.sql
[root@MySQL-master01 ~]# scp /data/all01.sql 10.0.0.18:/data

(2)主节点master02配置

powershell 复制代码
[root@MySQL-master02 ~]# vim /etc/my.cnf 
[mysqld]
server-id=2
log-bin = /data/mysql/logbin/mysql-bin        
relay_log = /data/mysql/relay-log/relay-bin
auto_increment_offset=1                        #自增列的步长
auto_increment_increment=2                     #自增列的起始偏移量
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
character_set_client = utf8mb4

#创建目录并授予权限
[root@MySQL-master02 ~]# mkdir -p /data/mysql/logbin
[root@MySQL-master02 ~]# chown -R mysql.mysql /data/mysql/logbin
[root@MySQL-master02 ~]# mkdir -p /data/mysql/relay-log
[root@MySQL-master02 ~]# chown -R mysql.mysql /data/mysql/relay-log

#重启并生效
[root@MySQL-master02 ~]# systemctl daemon-reload
[root@MySQL-master02 ~]# systemctl restart mysqld

#同步数据
[root@MySQL-master02 ~]# mysql
mysql> show master logs;
+------------------+-----------+-----------+
| Log_name         | File_size | Encrypted |
+------------------+-----------+-----------+
| mysql-bin.000001 |       179 | No        |
| mysql-bin.000002 |       203 | No        |
| mysql-bin.000003 |       156 | No        |
+------------------+-----------+-----------+

#完全备份
[root@MySQL-master02 ~]# mysqldump -uroot -p -A -F --source-data=1 --single-transaction > /data/all02.sql
[root@MySQL-master02 ~]# scp /data/all02.sql 10.0.0.8:/data

(3)同步master01和master02

powershell 复制代码
#先在master02上同步数据
[root@MySQL-master02 ~]# vim /data/all01.sql 
CHANGE MASTER TO
MASTER_HOST='10.0.0.18',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=156;

[root@MySQL-master02 ~]# mysql
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> source /data/all.sql;
Query OK, 0 rows affected (0.00 sec)

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.04 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.0.0.8
                  Master_User: repluser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 156
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

#刷新权限
[root@MySQL-master02 ~]# mysql
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.07 sec)

#再在master01上同步数据
[root@MySQL-master01 ~]# vim /data/all01.sql 
CHANGE MASTER TO
MASTER_HOST='10.0.0.8',
MASTER_USER='repluser',
MASTER_PASSWORD='123456',
MASTER_PORT=3306,
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=156;

[root@MySQL-master01 ~]# mysql
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)

mysql> source /data/all.sql;
Query OK, 0 rows affected (0.00 sec)

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.04 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.000004
          Read_Master_Log_Pos: 333
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 501
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes

(4)测试是否互为主备

powershell 复制代码
#在master01上创建db1库,表t1
[root@MySQL-master01 ~]# mysql
mysql>  create database db1;
Query OK, 1 row affected (0.16 sec)

mysql> use db1;
Database changed

mysql> create table t1(id int auto_increment primary key,name char(10));
Query OK, 0 rows affected (0.22 sec)

#在master02查看数据是否同步
[root@MySQL-master02 ~]# mysql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.05 sec)

mysql> use db1;
Database changed

mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| t1            |
+---------------+
1 row in set (0.03 sec)

##在master02上创建db2库,表t2
[root@MySQL-master02 ~]# mysql
mysql>  create database db2;
Query OK, 1 row affected (0.02 sec)

mysql> use db2;
Database changed
mysql> create table t2(id int auto_increment primary key,name char(10));
Query OK, 0 rows affected (0.06 sec)

#在master01上查看数据是否同步]
[root@MySQL-master01 ~]# mysql
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| db2                |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
6 rows in set (0.00 sec)

mysql> use db2;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

mysql> show tables;
+---------------+
| Tables_in_db2 |
+---------------+
| t2            |
+---------------+
1 row in set (0.00 sec)

(5)实例:两个节点同时创建数据库,发生复制冲突,不再同步

powershell 复制代码
#两个节点同时插入数据   (禁止同时在两个节点同时插入数据,相同数据时不会出现问题,一旦数据不同)
mysql> insert t1(id,name) values(3,'yue');
Query OK, 1 row affected (0.92 sec)

mysql> select * from t1;
+----+------+
| id | name |
+----+------+
|  1 | bai  |
|  2 | fu   |
|  3 | yue  |
+----+------+
3 rows in set (0.00 sec)

#两个节点同时创建数据库,发生复制冲突,不再同步
mysql>  create database db3;
Query OK, 1 row affected (0.44 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.000004
          Read_Master_Log_Pos: 1660
               Relay_Log_File: relay-bin.000002
                Relay_Log_Pos: 920
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 1062
                   Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at master log mysql-bin.000004, end_log_pos 1442. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.

#修复冲突(不建议使用,主主同步 也要使用主从模式)
#两个节点同时停止服务 
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.08 sec)

mysql> set global sql_slave_skip_counter = 3;            #强制跳过冲突的事务恢复同步状态,但是会造成数据不同步
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.66 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.000004
          Read_Master_Log_Pos: 1660
               Relay_Log_File: relay-bin.000004
                Relay_Log_Pos: 324
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 

4.半同步复制

Cluster Role System IP Hostname
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 复制代码
#安装半同步复制主库插件
[root@MySQL-master ~]# mysql
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected, 1 warning (1.70 sec)

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS 
    -> FROM INFORMATION_SCHEMA.PLUGINS 
    -> WHERE PLUGIN_NAME LIKE '%semi%';
+----------------------+---------------+
| PLUGIN_NAME          | PLUGIN_STATUS |
+----------------------+---------------+
| rpl_semi_sync_master | ACTIVE        |
+----------------------+---------------+
1 row in set (0.00 sec)

#修改配置文件
[root@MySQL-master ~]# vim /etc/my.cnf 
[mysqld]
server-id=1
log-bin=/data/mysql/logbin/mysql-bin
plugin-load-add=rpl_semi_sync_master.so        #加载半同步复制主库插件
rpl_semi_sync_master_enabled                   #启用半同步复制
rpl_semi_sync_master_timeout=3000              #主库等待从库确认的超时时间
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 ~]# systemctl restart mysqld

(2)从节点配置(slave01、slave02)

powershell 复制代码
#安装半同步复制从库插件
[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)

(4)监控主机点和从节点

powershell 复制代码
#主节点
[root@MySQL-master ~]# tail -f /data/mysql/MySQL-master.log
2026-01-27T07:18:55.157042Z       56 Query    select 1
2026-01-27T07:19:05.156943Z       60 Query    select 1
2026-01-27T07:19:15.156810Z       62 Query    select 1
2026-01-27T07:19:25.157044Z       57 Query    select 1
2026-01-27T07:19:35.157643Z       61 Query    select 1
2026-01-27T07:19:43.810670Z       54 Field List    t1 
2026-01-27T07:19:45.157019Z       58 Query    select 1
2026-01-27T07:19:55.157649Z       55 Query    select 1
2026-01-27T07:20:04.170055Z       42 Quit    
2026-01-27T07:20:05.157508Z       53 Query    select 1
2026-01-27T07:20:15.157925Z       59 Query    select 1
2026-01-27T07:20:25.158238Z       56 Query    select 1
2026-01-27T07:20:35.157211Z       60 Query    select 1
2026-01-27T07:20:39.608703Z       62 Query    insert into t1 (name) values ('mycat_test5')
2026-01-27T07:20:45.158084Z       57 Query    select 1

#从节点
[root@MySQL-slave01 ~]# tail -f /data/mysql/MySQL-slave01.log
2026-01-27T07:18:55.174435Z       40 Query    select 1
2026-01-27T07:19:05.175096Z       41 Query    select 1
2026-01-27T07:19:15.201230Z       46 Query    select 1
2026-01-27T07:19:25.174058Z       43 Query    select 1
2026-01-27T07:19:35.175275Z       44 Query    select 1
2026-01-27T07:19:43.689707Z       45 Query    show tables
2026-01-27T07:19:45.175046Z       39 Query    select 1
2026-01-27T07:19:48.150394Z       42 Query    show tables
2026-01-27T07:19:55.175646Z       40 Query    select 1
2026-01-27T07:20:05.174974Z       41 Query    select 1
2026-01-27T07:20:15.175661Z       46 Query    select 1
2026-01-27T07:20:21.192739Z       43 Query    select * from t1
2026-01-27T07:20:25.176398Z       44 Query    select 1
2026-01-27T07:20:35.174779Z       45 Query    select 1
2026-01-27T07:20:39.849680Z       12 Query    BEGIN
2026-01-27T07:20:39.869216Z       12 Query    COMMIT /* implicit, from Xid_log_event */
2026-01-27T07:20:45.174625Z       39 Query    select 1

四、MHA

1.搭建MHA架构

(1)配置MHA manager 节点

powershell 复制代码
#安装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

(3)配置slave节点

powershell 复制代码
#安装MHA 节点包
[root@MySQL-slave01 ~]# yum -y install mha4mysql-node-0.58-0.el7.centos.noarch.rpm

#修改配置文件
[root@MySQL-slave01 ~]# vim /etc/my.cnf
[mysqld]
server-id=2
read_only
relay_log_purge=0                          #禁用 MySQL 从库中继日志(relay log)的自动清理功能
relay_log_recovery=1                       # 从库重启后,自动清理旧 relay log 并重新从主库获取
skip_name_resolve=1                        #禁止反向解析
general_log
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

(4)在MHA manager节点启动

powershell 复制代码
[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

(2)注意事项

powershell 复制代码
#如果重启出错,需要删除下面文件再执行MHA
[root@mysql-mha ~]# rm -f /data/mastermha/app1/app1.failover.error

#MHA只能漂移一次,如果多次使用必须删除以下文件,要不MHA不可重用
[root@mysql-mha ~]# rm -rf /data/mastermha/app1/       #mha_master自己的工作路径
[root@mysql-mha ~]# rm -rf /data/mastermha/app1/manager.log     #mha_master自己的日志文件
[root@MySQL-master ~]# rm -rf /data/mastermha/app1/     #每个远程主机即三个节点的的工作目录
相关推荐
weixin_307779132 小时前
C#实现两个DocumentDB实例之间同步数据
开发语言·数据库·c#·云计算
Ivanqhz8 小时前
现代异构高性能计算(HPC)集群节点架构
开发语言·人工智能·后端·算法·架构·云计算·边缘计算
福大大架构师每日一题10 小时前
agno v2.4.7发布!新增Else条件分支、AWS Bedrock重排器、HITL等重大升级全解析
javascript·云计算·aws
TG_yunshuguoji12 小时前
阿里云代理商:如何通过控制台连接ECS实例?
运维·阿里云·云计算
翼龙云_cloud12 小时前
亚马逊云渠道商:AWS RDS备份恢复实战
服务器·云计算·aws
PM老周12 小时前
2026年常用瀑布管理工具有哪些?
阿里云·云计算·团队开发·产品经理·个人开发
翼龙云_cloud12 小时前
亚马逊云渠道商:AWS RDS数据库如何应用?
数据库·云计算·aws
珠海西格电力科技1 天前
微电网系统架构设计:并网/孤岛双模式运行与控制策略
网络·人工智能·物联网·系统架构·云计算·智慧城市
主机哥哥1 天前
阿里云OpenClaw极简部署教程,打造专属AI助手!
人工智能·阿里云·云计算