1 mysql路由器
重新开启虚拟机,集群已失效

恢复主节点server25
bash
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

恢复备节点server22和server23
bash
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;
集群恢复

在server26上部署 MySQL Router,为应用层提供统一的数据库访问入口
bash
[root@server26 ~]# rpm -ivh mysql-router-community-8.0.46-1.el7.x86_64.rpm
[root@server26 ~]# cd /etc/mysqlrouter/
[root@server26 mysqlrouter]# vim mysqlrouter.conf
[root@server26 mysqlrouter]# systemctl enable --now mysqlrouter.service
[root@server26 mysqlrouter]# netstat -antlp|grep :7001
[root@server26 mysqlrouter]# netstat -antlp|grep :7002
【静态手动路由模式】,不是自动对接 MGR 集群模式。Router 不会自动探测主从切换,节点宕机不会自动剔除,7001端口只读,7002端口读写


主节点server25添加用户zxl,用于测试机server26远程访问mysql
bash
mysql> create user 'zxl'@'%' identified by '123456';
mysql> grant all on test.* to 'zxl'@'%';
给server26安装mysql
从server25复制
bash
[root@server25 ~]# systemctl stop mysqld.service
[root@server25 ~]# cd /usr/local
[root@server25 local]# scp -rp mysql server26:/usr/local/
server26
bash
[root@server26 mysqlrouter]# groupadd -g 1005 mysql
[root@server26 mysqlrouter]# useradd -u 1004 -g mysql -M -d /usr/local/mysql/ -s /sbin/nologin mysql
[root@server26 mysqlrouter]# mkdir -p /data/mysql
[root@server26 mysqlrouter]# mkdir /etc/mysql
[root@server26 mysqlrouter]# chown -R mysql.mysql /data/mysql
[root@server26 mysqlrouter]# vim ~/.bash_profile
[root@server26 mysqlrouter]# source ~/.bash_profile
[root@server26 mysqlrouter]# which mysql
/usr/local/mysql/bin/mysql
至此mysql已安装好,server26可以访问集群中的数据
bash
[root@server26 mysqlrouter]# mysql -h 192.168.40.146 -u zxl -P 7001 -p123456
mysql> show databases;
mysql> select * from test.t1;

启动组复制,查询集群成员状态
bash
[root@server25 local]# mysql -p123456
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;
集群中的机器均安装lsof服务,用于验证 MySQL Router 是否成功工作
bash
yum install -y lsof
在 server26 本机上,通过 MySQL Router 的 7001 端口,连接到后端的 MySQL 数据库集群
bash
[root@server26 mysqlrouter]# mysql -h 192.168.40.146 -u zxl -P 7001 -p123456
server26 上的 MySQL Router 收到了连接请求,并且它成功地将该请求转发到了后端的 server22 这个数据库节点。连接状态为 ESTABLISHED,说明连接已经建立,可以进行数据交互

同理,可以访问 7002 端口
bash
[root@server26 mysqlrouter]# mysql -h 192.168.40.146 -u zxl -P 7002 -p123456

2 InnoDB Cluster
InnoDB Cluster 是 MySQL 官方提供的一套完整的高可用解决方案。它通过将多个 MySQL 服务器实例组合成一个集群,提供自动故障转移、数据复制和读写分离等功能。
InnoDB Cluster 主要由以下三个核心组件构成:
-
MySQL 服务器 (MySQL Server):
这是集群的基础,至少需要 3 个 MySQL 服务器实例。
通常采用
单主模式,即一个实例作为主节点(Primary) 处理读写请求,其余作为从节点(Secondary) 处理只读请求,并复制主节点的数据。也可以配置为多主模式,所有实例均可读写。
-
MySQL Group Replication:
这是 InnoDB Cluster 的核心技术引擎。
它基于共识算法(如 Paxos)提供数据复制、自动成员资格管理和自动故障转移功能。
当主节点发生故障时,集群会自动从从节点中选举一个新的主节点,对应用透明。
-
MySQL Router:
这是一个轻量级的中间件,作为应用程序和数据库集群之间的"路由器"。
它了解集群的拓扑结构,并自动将读写请求路由到当前的主节点,将只读请求分发到从节点。
当主节点发生故障切换时,Router 能自动感知并将请求路由到新的主节点,从而实现应用层的无缝切换。
优势
-
高可用性 (High Availability):通过自动故障转移和容错机制,确保服务持续可用。
-
易用性 (Ease of Use):通过 MySQL Shell 的 AdminAPI 可以轻松部署和管理,避免复杂的手动配置。
-
透明路由 (Transparent Routing):MySQL Router 让应用程序无需感知后端集群的复杂拓扑和变化。
-
读写分离 (Read/Write Splitting):将读和写操作分发到不同的实例,提升整体性能。
2.1 配置mgr单主模式
修改配置文件,切换单主模式
bash
[root@server25 ~]# vim /etc/mysql/my.cnf
[root@server25 ~]# systemctl restart mysqld.service

用引导模式"强行"建立一个新组,使主节点恢复为 primary
bash
[root@server25 ~]# mysql -p123456
mysql> SELECT * FROM performance_schema.replication_group_members;
#此时看到集群已经失效
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
mysql> SELECT * FROM performance_schema.replication_group_members;

server22和server23重新启动集群即可,恢复为secondary
bash
[root@server22 ~]# mysql -p123456
mysql> START GROUP_REPLICATION;
mysql> SELECT * FROM performance_schema.replication_group_members;
此时已经改为单主模式

2.2 mysql shell
MySQL Shell(mysqlsh)是官方推出的新一代高级命令行客户端和代码编辑器,可以看作是传统 mysql 命令的增强版。
核心能力
-
多语言编程支持:可以在同一个工具中使用 SQL、JavaScript 和 Python 编写脚本,非常适合编写复杂的自动化运维任务。
-
强大的 AdminAPI:通过 AdminAPI,你可以使用简单的 JavaScript 或 Python 命令来创建、配置和管理 InnoDB Cluster、InnoDB ClusterSet 和 InnoDB ReplicaSet,大大简化了高可用集群的运维工作。
-
现代化的交互体验:提供更友好的命令行界面,包括语法高亮、智能的 TAB 键自动补全以及历史命令记录(\history),能显著提升工作效率。
安装
bash
[root@server26 ~]# yum install -y mysql-shell-8.0.46-1.el7.x86_64.rpm
在primary节点创建集群管理员
bash
mysql> CREATE USER icadmin@'%' IDENTIFIED BY '123456';
mysql> GRANT ALL PRIVILEGES ON *.* TO icadmin@'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
接管现有mgr集群
bash
[root@server26 ~]# mysqlsh icadmin@192.168.40.145:3306
var cluster = dba.createCluster("mgr_single_cluster", {adoptFromGR:true, force:true});
cluster.status(); #验证集群状态
CTRL+D退出

2.3 mysql router
自动生成配置
bash
[root@server26 ~]# mysqlrouter --bootstrap icadmin@192.168.40.145:3306 --user=mysqlrouter
[root@server26 ~]# systemctl restart mysqlrouter.service
[root@server26 ~]# mysql -h 192.168.40.146 -u zxl -P 6446 -p123456
连接 6446 端口 时,Router 会将其路由到 InnoDB Cluster 的 主库(Primary) ,可以读写。
连接 6447 端口 时,Router 会将其路由到 从库(Secondary),只读。
主节点查看

此时停掉主节点server25的服务,备节点仍可工作,并推选出一个新的主节点server22,恢复服务,原来的主节点变为备节点


2.4 mysql router 高可用与横向扩容
可以搭配keepalived、lvs 实现mysqlrouter 高可用与横向扩容
新加入四台虚拟机
server26、server27做路由器
server28、server29做LVS
分别将七台机器的IP都加入解析文件
第一层均衡 :LVS(server28 & server29)
作用:提供 VIP(虚拟IP) 和 负载均衡。
将客户端发往 VIP 的连接,按照轮询(rr)算法,分发到后端的多个 MySQL Router 实例(server26 和 server27),实际就是对路由器实现负载均衡。
实现 Router 层的高可用和负载分担。如果 server26 宕机,LVS 会自动将流量全部切到 server27;同时,两个 Router 共同承担连接压力。
第二层路由 :MySQL Router(server26 & server27)
作用:读写分离和故障感知。
发往 7001 端口的连接,Router 会全部路由到当前 MGR 集群的 primary 节点(server25)。
发往 7002 端口的连接,Router 会根据负载均衡策略将连接分发到多个 secondary 节点(server22、server23)。这里实现了读请求的负载均衡。
7001(读写端口):保证写入一致性,所有写操作必须由主库处理。
7002(只读端口):将查询压力分散到多个从库,提升整体吞吐量。
第三层数据层 :MGR(server25、22、23)------ 保障"数据一致性"
作用:数据存储和高可用。
目的:主库故障时,从库自动升级为主库,保证数据不丢失,服务可持续。
2.4.1 路由器部署
bash
[root@server27 ~]# yum install -y mysql-router-community-8.0.46-1.el7.x86_64.rpm
时间同步
bash
systemctl restart chronyd
安装mysql或mariadb进行测试
bash
[root@server26 ~]# scp -rp /usr/local/mysql server27:/usr/local/
bash
[root@server27 ~]# vim .bash_profile #将mysql路径写入
[root@server27 ~]# source .bash_profile
[root@server27 ~]# which mysql
[root@server27 ~]# mysqlrouter --bootstrap icadmin@192.168.40.142:3306 --user=mysqlrouter
[root@server27 ~]# systemctl restart mysqlrouter.service
[root@server27 ~]# mysql -h 192.168.40.146 -P 6446 -u zxl -p123456

测试:可以远程访问数据库

2.4.2 LVS部署
server28、server29
bash
yum install -y install keepalived.x86_64
yum install -y ipvsadm
主节点部署
bash
[root@server28 ~]# vim /etc/keepalived/keepalived.conf
[root@server28 ~]# systemctl enable --now keepalived.service


自动绑定VIP

备节点部署
配置文件拷贝到备节点
bash
[root@server28 ~]# scp /etc/keepalived/keepalived.conf server29:/etc/keepalived/
设置为备用节点,优先级低于主节点,不会自动接管VIP
bash
[root@server29 ~]# vim /etc/keepalived/keepalived.conf
[root@server29 ~]# systemctl enable --now keepalived.service

查看当前生效的负载均衡规则表
bash
ipvsadm -ln


在 MySQL Router 节点上,通过 arptables 实现 LVS DR 模式的 ARP 抑制和 VIP 绑定
server26
bash
[root@server26 ~]# yum install -y arptables
[root@server26 ~]# ip a a 192.168.40.100/24 dev eth0
[root@server26 ~]# arptables -A INPUT -d 192.168.40.100 -j DROP
[root@server26 ~]# arptables -A OUTPUT -s 192.168.40.100 -j mangle --mangle-ip-s 192.168.40.176
[root@server26 ~]# arptables-save > /etc/sysconfig/arptables
[root@server26 ~]# systemctl restart arptables.service

server27
bash
[root@server27 ~]# ip a a 192.168.40.100/24 dev eth0
[root@server27 ~]# arptables -A INPUT -d 192.168.40.100 -j DROP
[root@server27 ~]# arptables -A OUTPUT -s 192.168.40.100 -j mangle --mangle-ip-s 192.168.40.177
[root@server27 ~]# arptables-save > /etc/sysconfig/arptables
[root@server27 ~]# systemctl restart arptables.service

在server29测试:可通过VIP访问数据库
bash
[root@server29 ~]# yum install -y mariadb
[root@server29 ~]# mysql -h 192.168.40.100 -P 6446 -u zxl -p123456

测试
- 测试 Keepalived 的 VIP 漂移机制
server28停止keepalived服务,VIP自动从server28解绑,绑定到server29


恢复server28,VIP自动切换回server28


- 测试 MySQL Router 层的高可用和自动故障恢复机制,以及 LVS(或 Router 内部)对故障节点的剔除与恢复策略
- 访问6446端口,指向主库
可以在除了LVS的主节点以外的机器上执行,从 Master 节点访问 VIP,请求不一定经过 LVS,可能会直接由本机处理
bash
mysql -h 192.168.40.100 -P 6446 -u zxl -p123456
server25与主备路由器都建立

server22和server23无连接

停掉26的mysqlrouter再访问
bash
[root@server26 ~]# systemctl stop mysqlrouter.service
server25只与server27有连接

恢复服务,重新与server26建立连接,但是建立的 TCP 连接是持久的,已有的连接不会立即切回,保持连接到 server27

过一段时间,没有持续的新连接请求产生,且已有的短连接执行完毕后自然关闭

再次访问
bash
mysql -h 192.168.40.100 -P 6446 -u zxl -p123456
有新的连接,由于负载均衡的配置,此次连接上server26

此时查看调度器,26有一条新的TCP连接

- 访问6447端口,指向从库
bash
mysql -h 192.168.40.100 -P 6447 -u zxl -p123456
此时主库server25无连接

从库server22和server23连接均衡


若遇以下问题:Router 多次握手 / 连接异常,超过 MySQL 参数 max_connect_errors 阈值,数据库直接拉黑 Router 的 IP,拒绝它继续发起连接。

可在集群的三个节点中执行以下语句临时解锁
bash
mysqladmin -u root -p flush-hosts
3 MHA高可用
MHA高可用和 InnoDB Cluster(基于 MGR)是两种不同的高可用实现路径。
MHA 本身并不改变 MySQL 主从复制的架构,而是作为一套管理工具,运行在主从集群之上。它通过 SSH 连接到各个数据库节点,执行一系列脚本来实现高可用。
核心组件:
-
MHA Manager(管理节点):通常部署在一台独立服务器上,是集群的"大脑",负责监控主库、发起和执行故障切换。
-
MHA Node(数据节点):部署在每台 MySQL 服务器上,接收 Manager 的指令并执行具体操作,比如保存日志、应用差异数据等。
工作原理:当主库宕机时
-
监控与发现:Manager 节点会持续监控主库的健康状态。一旦发现主库无法连接(例如连续几次心跳失败),就判定主库发生故障。
-
尽力抢救数据:MHA 会尝试通过 SSH 登录到故障的主库,尽力把主库上最新的二进制日志(binlog)复制出来,以防数据丢失。
-
选举新主库:Manager 会检查所有从库,根据数据更新的程度(哪个从库的 Exec_Master_Log_Pos 最大),选举出数据最新的从库作为新主库的候选者。
-
数据补齐与切换:如果上一步成功抢救了主库的 binlog,MHA 会把这些日志应用到候选新主库上,确保其数据是最新的。接着,MHA 会让其他从库与这个新主库建立复制关系。最后,通过脚本或与 Keepalived 等工具配合,将虚拟 IP(VIP)漂移到新的主库上,对上层应用屏蔽切换过程。
3.1 创建一主两从集群
3.1.1 master配置
清理数据
bash
[root@server25 ~]# systemctl stop mysqld.service
[root@server25 ~]# cd /data/mysql/
[root@server25 mysql]# rm -fr *
修改配置
bash
[root@server25 mysql]# vim /etc/mysql/my.cnf
注意:这里要保证集群里每个节点的server_id不同

初始化并启动服务
bash
[root@server25 mysql]# mysqld --defaults-file=/etc/mysql/my.cnf --initialize
[root@server25 mysql]# grep temporary mysql-error.log
[root@server25 mysql]# systemctl start mysqld.service
配置master
bash
[root@server25 mysql]# mysql -p
mysql> alter user root@localhost identified by '123456';
mysql> CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
mysql> show master status;

3.1.2 slave配置
server22
bash
[root@server22 ~]# systemctl stop mysqld.service
[root@server22 ~]# cd /data/mysql/
[root@server22 mysql]# rm -fr *
[root@server22 mysql]# vim /etc/mysql/my.cnf

bash
[root@server22 mysql]# mysqld --defaults-file=/etc/mysql/my.cnf --initialize
[root@server22 mysql]# grep temporary mysql-error.log
[root@server22 mysql]# systemctl start mysqld.service
[root@server22 mysql]# mysql -p
mysql> alter user root@localhost identified by '123456';
mysql> CHANGE MASTER TO MASTER_HOST='192.168.40.145', MASTER_USER='repl', MASTER_PASSWORD='123456', MASTER_AUTO_POSITION = 1;
mysql> start slave;
mysql> show slave status\G;

server23
bash
[root@server23 ~]# systemctl stop mysqld.service
[root@server23 ~]# cd /data/mysql/
[root@server23 mysql]# rm -fr *
[root@server23 mysql]# vim /etc/mysql/my.cnf

bash
[root@server23 mysql]# mysqld --defaults-file=/etc/mysql/my.cnf --initialize
[root@server23 mysql]# grep temporary mysql-error.log
[root@server23 mysql]# systemctl start mysqld.service
[root@server23 mysql]# mysql -p
mysql> alter user root@localhost identified by '123456';
mysql> CHANGE MASTER TO MASTER_HOST='192.168.40.145', MASTER_USER='repl', MASTER_PASSWORD='123456', MASTER_AUTO_POSITION = 1;
mysql> start slave;
mysql> show slave status\G;

3.2 MHA部署
server26做管理端
删除server26下所有文件,将如下四个rpm包放在/root下

复制客户端软件并安装
bash
[root@server26 ~]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server25:
[root@server26 ~]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server22:
[root@server26 ~]# scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm server23:
bash
[root@server25 ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
bash
[root@server22 ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
bash
[root@server23 ~]# yum install -y mha4mysql-node-0.58-0.el7.centos.noarch.rpm
server26安装管理端软件
bash
[root@server26 ~]# yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm mha4mysql-node-0.58-0.el7.centos.noarch.rpm
缺少四个依赖模块

bash
[root@server26 ~]# wget -O /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
[root@server26 ~]# yum install -y mha4mysql-manager-0.58-0.el7.centos.noarch.rpm mha4mysql-node-0.58-0.el7.centos.noarch.rpm
MHA配置
bash
[root@server26 ~]# mkdir /etc/masterha
[root@server26 ~]# vim /etc/masterha/app1.cnf

在master上设置mysql 管理员权限,slave节点会自动同步
bash
[root@server25 ~]# mysql -p123456
mysql> CREATE USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
mysql> GRANT ALL PRIVILEGES ON *.* TO root@'%' WITH GRANT OPTION;
管理端配置ssh免密
bash
[root@server26 ~]# ssh-keygen
[root@server26 ~]# ssh-copy-id server26
[root@server26 ~]# scp -r .ssh/ server25:
[root@server26 ~]# scp -r .ssh/ server22:
[root@server26 ~]# scp -r .ssh/ server23:
检测各节点ssh免密连接
bash
[root@server26 ~]# masterha_check_ssh --conf=/etc/masterha/app1.cnf

检测主从复制集群状态
bash
[root@server26 ~]# masterha_check_repl --conf=/etc/masterha/app1.cnf

3.3 故障切换
3.3.1 手动切换正常节点
当前主节点在server25,状态正常,手动切换到server22
bash
[root@server26 ~]# masterha_master_switch --conf=/etc/masterha/app1.cnf --master_state=alive --new_master_host=192.168.40.142 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000

server22变成主库

server25和server23是从库


3.3.2 手动切换故障节点
此时主节点为server22
手动停止master节点上的msql服务,模拟故障
bash
[root@server22 ~]# systemctl stop mysqld.service
将server25切换为主库
bash
[root@server26 ~]# masterha_master_switch --master_state=dead --conf=/etc/masterha/app1.cnf --dead_master_host=192.168.40.142 --dead_master_port=3306 --new_master_host=192.168.40.145 --new_master_port=3306 --ignore_last_failover

查看主库状态

查看正常的从库状态

手动恢复故障节点
bash
[root@server22 ~]# systemctl start mysqld.service
[root@server22 ~]# mysql -p123456
mysql> change master to master_host='192.168.40.145', master_user='repl', master_password='123456', master_auto_position=1;
mysql> start slave;
mysql> show slave status\G;

3.3.3 自动切换
故障切换后会生成lock文件,需要手动删除
bash
[root@server26 ~]# cd /etc/masterha/
[root@server26 masterha]# cd app1/
[root@server26 app1]# ls
app1.failover.complete
[root@server26 app1]# rm -f app1.failover.complete
在进行自动切换之前,必须保证主从集群正常,一主两从
加入故障切换脚本
bash
[root@server26 app1]# cd
[root@server26 ~]# vim /etc/masterha/app1.cnf

编辑项目开始前加入的脚本
master_ip_failover 是 MHA 在故障切换过程中调用的关键脚本之一,其核心功能是管理 VIP 的漂移
bash
[root@server26 ~]# mv master_ip_* /etc/masterha/
[root@server26 ~]# cd /etc/masterha/
[root@server26 masterha]# chmod +x master_ip_*
[root@server26 masterha]# vim master_ip_failover

master_ip_online_change 是 MHA 用于在线手动切换的脚本,也将VIP写入
bash
[root@server26 masterha]# vim master_ip_online_change

启动manger程序,并打入后台运行
bash
[root@server26 masterha]# masterha_manager --conf=/etc/masterha/app1.cnf &
[root@server26 masterha]# ps aux | grep masterha_manager

查看

测试:
停掉主节点的mysql服务模拟故障
bash
[root@server25 ~]# systemctl stop mysqld.service
自动切换主节点到server22


完成切换任务后manager进程会自动退出,防止二次切换

查看故障切换日志
