十七、MYSQL MGR高可用
十七、MYSQL MGR高可用
1.MGR概念
1.1 MGR 定义
MGR 全称:MySQL Group Replication
它是 MySQL 提供的一种基于组通信和事务一致性机制的高可用复制方案。
1.2 核心特征
多节点组成复制组
支持故障自动检测
支持成员自动加入和退出
支持自动选举主节点
支持单主模式和多主模式
1.3 MGR 架构组成
MGR 典型由以下部分组成:
主节点(Primary)
处理写请求
向组内广播事务
从节点(Secondary)
接收并应用事务
通常只提供只读服务
组通信层
用于节点之间交换状态
维护组成员视图
实现事务分发与确认
一致性控制机制
检测事务冲突
保证事务有序提交
1.4 MGR 模式介绍
1. 单主模式(Single-Primary Mode)⭐
组内只有一个主节点可写
其他节点只读
最常见,结构清晰,冲突少
2. 多主模式(Multi-Primary Mode)
多个节点都可写
可能发生冲突
管理复杂,对业务要求高
1.5 事务执行流程
在单主模式下,事务执行过程如下:
客户端把写请求发送给主节点
主节点接收事务并生成写集信息
主节点把事务广播给组内其他成员
其他成员进行冲突检测和确认
达到组内确认条件后,事务提交成功
事务再被应用到其他节点
核心:
主节点不是“自己写完就算成功”
提交前需要组内成员参与确认
这提高了一致性,也增强了故障切换时的数据可靠性
2.高可用机制与生产架构
2.1 故障检测与自动切换
如果主节点异常:
组内检测到主节点失联
更新成员视图
在剩余可用节点中重新选举主节点
新主节点接管写服务
2.2 多数派机制
1.多数派定义
MGR 集群要继续正常工作,必须满足多数节点在线。
例如:
3 个节点时,至少 2 个节点在线
5 个节点时,至少 3 个节点在线
2. 为什么需要多数派
为了避免脑裂问题。
3. 脑裂解释
如果网络分区后,两个子集群都认为自己是“合法主集群”, 就可能产生双主写入,导致数据严重不一致。
4. 多数派的价值
保证集群中只有一边能继续提供写服务
防止多个节点同时对外写入
提高一致性安全性
2.3 MGR 高可用原理总结
多节点组成复制组
节点间持续交换状态
事务在组内传播并确认
主节点故障后自动重新选主
多数派保证集群一致性和防脑裂
2.4 MGR 与传统主从复制对比
| 对比项 | 传统主从复制 | MGR |
|---|---|---|
| 节点关系 | 主从结构 | 组成员结构 |
| 故障切换 | 通常依赖人工或外部工具 | 支持自动选主 |
| 一致性保障 | 较弱,常为异步 | 更强,组内确认 |
| 防脑裂能力 | 较弱 | 有多数派机制 |
| 高可用能力 | 需要额外组件 | 原生支持较强 |
2.5 MGR 与代理层的关系
MGR负责的是:
数据复制
主节点选举
高可用机制
但 MGR不负责:
读写分离
SQL 路由
客户端连接切换
这些通常由:
ProxySQL
HAProxy
MySQL Router
Keepalived + VIP
来完成。
3.具体实验案例
3.1 环境准备
三台机器分别为:
192.168.202.135 mysql1
192.168.202.136 mysql2
192.168.202.137 mysql3
MGR 端口:
MySQL 端口:
3306Group Replication 端口:
33061
# 三台都执行:关闭防火墙并永久关闭 systemctl stop firewalld systemctl disable firewalld # 关闭 SELinux setenforce 0 # 修改主机名并互相解析 hostnamectl set-hostname mysql1 hostnamectl set-hostname mysql2 hostnamectl set-hostname mysql3 vi /etc/hosts 192.168.202.135 mysql1 192.168.202.136 mysql2 192.168.202.137 mysql3
# 下载依赖工具 yum install -y yum-utils # 上传并解压mysql5.7 依赖环境的rpm包: yum install -y unzip unzip mysql5720_rpms.zip # 切换到存放所有 MySQL 及依赖 RPM 包的文件夹 cd mysql5720_rpms # yum 会自动识别当前目录下所有 .rpm 文件,并处理依赖关系(若本地包已包含所有依赖,会直接安装;若缺依赖会提示) yum localinstall -y *.rpm
3.2 修改配置文件和初始密码
# 启动数据库 systemctl start mysqld # 修改配置文件: vim /etc/my.cnf [mysqld] # 其他原有配置(如datadir、socket等)保持不变,新增以下两行 validate_password_policy=LOW # 降低强度策略(仅检查长度) validate_password_length=6 # 最小密码长度设为6位 skip-ssl # 关闭ssl访问 # 重启mysqld并设置开机自启动 systemctl restart mysqld systemctl enable mysqld # 查看mysql数据库初始密码 grep password /var/log/mysqld.log
PS:如果密码内容有特殊字符,需要转义( \ )
# 进入数据库 mysql -uroot -p # 修改密码 alter user 'root'@'localhost' identified by 'abc123'; # 验证: show databases; # 验证2: exit 退出 mysql -uroot -pabc123
3.3 修改 MySQL 配置
mysql1 配置
server-id=1 log-bin=mysql-bin binlog_format=ROW gtid_mode=ON enforce_gtid_consistency=ON log_slave_updates=ON master_info_repository=TABLE relay_log_info_repository=TABLE transaction_write_set_extraction=XXHASH64 binlog_checksum=NONE loose-group_replication_group_name="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" loose-group_replication_start_on_boot=off loose-group_replication_local_address="192.168.202.135:33061" loose-group_replication_group_seeds="192.168.202.135:33061,192.168.202.136:33061,192.168.202.137:33061" loose-group_replication_bootstrap_group=off loose-group_replication_single_primary_mode=ON loose-group_replication_enforce_update_everywhere_checks=OFF
mysql2 配置
server-id=2 log-bin=mysql-bin binlog_format=ROW gtid_mode=ON enforce_gtid_consistency=ON log_slave_updates=ON master_info_repository=TABLE relay_log_info_repository=TABLE transaction_write_set_extraction=XXHASH64 binlog_checksum=NONE loose-group_replication_group_name="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" loose-group_replication_start_on_boot=off loose-group_replication_local_address="192.168.202.136:33061" loose-group_replication_group_seeds="192.168.202.135:33061,192.168.202.136:33061,192.168.202.137:33061" loose-group_replication_bootstrap_group=off loose-group_replication_single_primary_mode=ON loose-group_replication_enforce_update_everywhere_checks=OFF
mysql3 配置
server-id=3 log-bin=mysql-bin binlog_format=ROW gtid_mode=ON enforce_gtid_consistency=ON log_slave_updates=ON master_info_repository=TABLE relay_log_info_repository=TABLE transaction_write_set_extraction=XXHASH64 binlog_checksum=NONE loose-group_replication_group_name="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" loose-group_replication_start_on_boot=off loose-group_replication_local_address="192.168.202.137:33061" loose-group_replication_group_seeds="192.168.202.135:33061,192.168.202.136:33061,192.168.202.137:33061" loose-group_replication_bootstrap_group=off loose-group_replication_single_primary_mode=ON loose-group_replication_enforce_update_everywhere_checks=OFF
# 配置完后重启 systemctl restart mysqld
3.4 创建 MGR 用户
# 先在 主节点 执行后同步到其他节点,登录 MySQL: mysql -uroot -p # 创建复制用户: create user 'repl'@'%' identified by 'Repl@123456'; # 给后面安装的插件授权 grant replication slave on *.* to 'repl'@'%'; # 刷新 flush privileges;安装 Group Replication 插件
3.5 安装 Group Replication 插件
# 三台都执行: install plugin group_replication soname 'group_replication.so'; # 确认状态是 `ACTIVE`。 show plugins;
3.6 配置复制通道
# 三台都执行: change master to master_user='repl',master_password='Repl@123456' for channel 'group_replication_recovery';
3.7 启动节点
# 启动第一个节点,先在 `mysql1` 上执行: set global group_replication_bootstrap_group=ON; start group_replication; set global group_replication_bootstrap_group=OFF; # 查看状态: select * from performance_schema.replication_group_members; # 此时应该只有 `mysql1` 一个节点,状态是 `ONLINE`。
# 启动另外两个节点 # 在 `mysql2` 上执行: start group_replication; # 在 `mysql3` 上执行: start group_replication; # 然后回到任意节点查看: select * from performance_schema.replication_group_members; # 应该看到 3 个节点都在,状态都是 `ONLINE`。
3.8 测试主节点写入
# 查看当前主节点: select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member';
测试主节点写入
单主模式下,只有一个节点可以写入
# 插入测试表: create database testmgr; use testmgr; create table t1 ( id int primary key auto_increment, name varchar(50) ); insert into t1(name) values('abc'); # 然后到另外两个节点查询: select * from testmgr.t1;如果都能查到,说明同步正常。
3.9 测试高可用切换
(一)模拟主节点故障
# 当前主节点是 `mysql1`,你执行 systemctl stop mysqld # 在另外两个节点执行 select * from performance_schema.replication_group_members;
# 查看当前主节点 select variable_value from performance_schema.global_status where variable_name='group_replication_primary_member';
(二)验证写入
# 在新的主节点上执行: insert into testmgr.t1(name) values('def');
# 然后其他节点查询,看数据是否同步。 select * from testmgr.t1;4.常见问题
1. 节点启动失败
重点检查:
server-id是否唯一gtid_mode=ONbinlog_format=ROWtransaction_write_set_extraction=XXHASH6433061 端口是否放行
hostname / hosts 是否解析正常
2. 节点进不来组
看日志:
tail -f /var/log/mysqld.log
3. 不能写入
单主模式下,只有主节点能写,其他节点默认只读,这是正常的。
