MySQL Group Replication(MGR)集群部署,实现自动故障切换

传统MySQL主从复制需要手动切换故障节点,无法满足高可用场景下"秒级自动恢复"的需求。MySQL Group Replication(MGR,组复制)基于Paxos协议实现多节点数据同步与自动故障切换,无需依赖Keepalived、MHA等第三方工具,是MySQL官方推荐的高可用解决方案。

一、MGR核心认知

1.1 MGR对比传统主从的优势

特性 传统主从复制 MySQL Group Replication
故障切换 手动切换 自动选举新主节点,秒级恢复
数据一致性 异步/半同步,易不一致 强一致性(基于Paxos协议)
集群管理 依赖第三方工具 原生支持集群管理,无需额外组件
节点角色 主从固定 单主/多主模式,角色自动切换
脑裂风险 低(奇数节点仲裁)

1.2 MGR核心原理

MGR集群由至少3个节点组成(奇数节点,保证投票仲裁),单主模式下:

  1. 集群选举出1个主节点(Primary) 处理所有写入操作,其余为从节点(Secondary) 只读;
  2. 主节点将事务同步到集群,所有节点通过组通信协议(XCom)达成共识后,才提交事务,保证数据一致性;
  3. 主节点故障时,集群自动检测并通过投票选举新主节点,从节点无缝接管写入,无需人工干预。

1.3 环境规划(单主模式)

节点角色 服务器IP MySQL版本 核心配置 端口说明
MGR节点1(初始主) 192.168.1.30 8.0.36 4核8G,500G硬盘 3306(MySQL服务)、33061(MGR通信)
MGR节点2 192.168.1.31 8.0.36 4核8G,500G硬盘 3306、33061
MGR节点3 192.168.1.32 8.0.36 4核8G,500G硬盘 3306、33061

1.4 前置准备

  1. 所有节点操作系统:CentOS 7.x(关闭SELinux、防火墙开放3306/33061端口);

  2. 同步系统时间:ntpdate ntp.aliyun.com

  3. 禁用AppArmor/SELinux:setenforce 0 && sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

  4. 开放端口:

    bash 复制代码
    firewall-cmd --add-port=3306/tcp --permanent
    firewall-cmd --add-port=33061/tcp --permanent
    firewall-cmd --reload

二、第一步:所有节点安装并配置MySQL 8.0

MGR对MySQL版本要求严格(推荐8.0.20+),以下步骤需在所有3个节点执行。

2.1 安装MySQL 8.0

bash 复制代码
# 1. 安装MySQL YUM源
wget https://dev.mysql.com/get/mysql80-community-release-el7-7.noarch.rpm
rpm -ivh mysql80-community-release-el7-7.noarch.rpm

# 2. 安装MySQL服务器(忽略GPG检查,避免版本兼容问题)
yum install -y mysql-community-server --nogpgcheck

# 3. 启动MySQL并设置开机自启
systemctl start mysqld
systemctl enable mysqld

# 4. 获取初始密码
initial_pass=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
echo "初始密码:$initial_pass"

2.2 初始化MySQL(修改密码、配置权限)

bash 复制代码
# 1. 登录MySQL并修改root密码(需符合复杂度:大小写+数字+特殊字符)
mysql -u root -p"$initial_pass" -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@123456'; FLUSH PRIVILEGES;"

# 2. 远程访问授权(生产环境建议限制IP,此处为测试放开)
mysql -u root -p"MySQL@123456" -e "CREATE USER 'root'@'%' IDENTIFIED BY 'MySQL@123456'; GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;"

2.3 配置MGR核心参数(修改my.cnf)

编辑/etc/my.cnf,替换原有配置为以下内容(注意替换server-id和group_replication_local_address为节点对应值):

节点1(192.168.1.30)my.cnf配置
ini 复制代码
[mysqld]
# 基础配置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
lower_case_table_names=1
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

# MGR核心配置
server-id=30  # 每个节点唯一,建议用IP最后一段
gtid_mode=ON  # 开启GTID,MGR必需
enforce_gtid_consistency=ON
master_info_repository=TABLE
relay_log_info_repository=TABLE
binlog_checksum=NONE
log_slave_updates=ON
binlog_format=ROW
transaction_write_set_extraction=XXHASH64  # MGR用于检测冲突的哈希算法
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"  # 固定UUID,所有节点一致
loose-group_replication_start_on_boot=OFF  # 不随MySQL启动自动启动MGR
loose-group_replication_local_address="192.168.1.30:33061"  # 当前节点MGR通信地址
loose-group_replication_group_seeds="192.168.1.30:33061,192.168.1.31:33061,192.168.1.32:33061"  # 所有节点通信地址
loose-group_replication_bootstrap_group=OFF  # 仅初始化集群时设为ON
loose-group_replication_single_primary_mode=ON  # 单主模式(核心:自动故障切换依赖此模式)
loose-group_replication_enforce_update_everywhere_checks=OFF  # 单主模式设为OFF
loose-group_replication_auto_increment_increment=7  # 避免主键冲突
节点2(192.168.1.31)my.cnf配置

仅修改以下2处,其余与节点1一致:

ini 复制代码
server-id=31
loose-group_replication_local_address="192.168.1.31:33061"
节点3(192.168.1.32)my.cnf配置

仅修改以下2处:

ini 复制代码
server-id=32
loose-group_replication_local_address="192.168.1.32:33061"

2.4 重启MySQL并验证配置

bash 复制代码
# 重启MySQL
systemctl restart mysqld

# 验证GTID是否开启(输出ON即正常)
mysql -u root -p"MySQL@123456" -e "SHOW VARIABLES LIKE 'gtid_mode';"

三、第二步:搭建MGR集群(单主模式)

3.1 步骤1:在所有节点创建MGR专用用户

MGR需要专用用户用于节点间通信,登录每个节点执行:

bash 复制代码
mysql -u root -p"MySQL@123456" << EOF
# 创建MGR通信用户
CREATE USER 'mgr_repl'@'%' IDENTIFIED BY 'MGR@123456';
# 授予MGR所需权限
GRANT REPLICATION SLAVE ON *.* TO 'mgr_repl'@'%';
GRANT GROUP_REPLICATION_ADMIN ON *.* TO 'mgr_repl'@'%';
FLUSH PRIVILEGES;

# 配置MGR插件使用该用户
CHANGE MASTER TO MASTER_USER='mgr_repl', MASTER_PASSWORD='MGR@123456' FOR CHANNEL 'group_replication_recovery';
EOF

3.2 步骤2:初始化MGR集群(仅节点1执行)

节点1作为初始主节点,负责引导集群创建:

bash 复制代码
mysql -u root -p"MySQL@123456" << EOF
# 加载MGR插件(8.0+默认内置,无需手动安装)
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

# 启动集群引导(仅第一次执行)
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;

# 验证集群状态(输出ON即正常)
SELECT * FROM performance_schema.replication_group_members;
EOF

执行后查看replication_group_members,节点1状态应为ONLINE,角色为PRIMARY

3.3 步骤3:节点2、3加入集群

节点2执行:
bash 复制代码
mysql -u root -p"MySQL@123456" << EOF
# 加载MGR插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

# 加入集群
START GROUP_REPLICATION;

# 验证节点状态
SELECT * FROM performance_schema.replication_group_members;
EOF
节点3执行:

与节点2命令完全一致,执行后验证节点状态。

3.4 验证集群搭建成功

在任意节点执行以下命令,查看集群成员状态:

bash 复制代码
mysql -u root -p"MySQL@123456" -e "SELECT MEMBER_HOST, MEMBER_ROLE, MEMBER_STATE FROM performance_schema.replication_group_members;"

正常输出示例

MEMBER_HOST MEMBER_ROLE MEMBER_STATE
192.168.1.30 PRIMARY ONLINE
192.168.1.31 SECONDARY ONLINE
192.168.1.32 SECONDARY ONLINE
3个节点均为ONLINE,且节点1为PRIMARY,说明集群搭建成功。

四、第三步:验证自动故障切换

4.1 前置测试:主节点写入数据

在节点1(主节点)插入测试数据,验证从节点同步:

bash 复制代码
# 节点1执行:创建测试库和表
mysql -u root -p"MySQL@123456" << EOF
CREATE DATABASE IF NOT EXISTS mgr_test;
USE mgr_test;
CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50));
INSERT INTO user (name) VALUES ('MGR测试用户1'), ('MGR测试用户2');
EOF

# 节点2/3执行:查询数据(应同步成功)
mysql -u root -p"MySQL@123456" -e "SELECT * FROM mgr_test.user;"

4.2 模拟主节点故障(停止节点1的MySQL)

bash 复制代码
# 节点1执行:停止MySQL服务,模拟故障
systemctl stop mysqld

4.3 验证自动选举新主节点

等待5~10秒(MGR故障检测默认超时约5秒),在节点2执行以下命令:

bash 复制代码
mysql -u root -p"MySQL@123456" -e "SELECT MEMBER_HOST, MEMBER_ROLE, MEMBER_STATE FROM performance_schema.replication_group_members;"

预期输出(节点2或3被选举为新主):

MEMBER_HOST MEMBER_ROLE MEMBER_STATE
192.168.1.30 UNREACHABLE OFFLINE
192.168.1.31 PRIMARY ONLINE
192.168.1.32 SECONDARY ONLINE

4.4 验证新主节点写入功能

在新主节点(如节点2)插入数据,验证写入正常:

bash 复制代码
# 节点2执行:插入数据
mysql -u root -p"MySQL@123456" << EOF
USE mgr_test;
INSERT INTO user (name) VALUES ('故障切换后写入');
EOF

# 节点3执行:查询数据(应同步新数据)
mysql -u root -p"MySQL@123456" -e "SELECT * FROM mgr_test.user;"

4.5 故障节点恢复后重新加入集群

节点1修复后,重启MySQL并重新加入集群:

bash 复制代码
# 节点1执行:重启MySQL
systemctl start mysqld

# 重新加入集群
mysql -u root -p"MySQL@123456" << EOF
START GROUP_REPLICATION;
# 验证状态(此时节点1为SECONDARY)
SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;
EOF

五、MGR集群生产环境优化

5.1 配置自动重启MGR

编辑/etc/my.cnf,添加以下配置(所有节点),确保MySQL重启后MGR自动启动:

ini 复制代码
loose-group_replication_start_on_boot=ON

5.2 监控集群状态

5.2.1 核心监控SQL
bash 复制代码
# 1. 集群成员状态
SELECT MEMBER_HOST, MEMBER_ROLE, MEMBER_STATE FROM performance_schema.replication_group_members;

# 2. MGR运行状态
SHOW STATUS LIKE 'group_replication%';

# 3. 事务冲突(生产环境需监控)
SELECT * FROM performance_schema.replication_group_conflicts;
5.2.2 结合Prometheus+Grafana监控
  1. 安装MySQL Exporter,配置监控指标;
  2. 导入MGR专用监控模板(Grafana ID:14050),重点监控:
    • 节点在线状态、角色;
    • 事务同步延迟;
    • 集群冲突数;
    • MGR通信端口连通性。

5.3 数据备份策略

MGR仅保证集群内数据一致,仍需定期备份:

  1. 开启binlog日志,设置过期时间:binlog_expire_logs_seconds=604800(7天);

  2. 每天在从节点执行全量备份:

    bash 复制代码
    mysqldump -u root -p"MySQL@123456" --all-databases --single-transaction --master-data=2 > /backup/mysql_full_$(date +%Y%m%d).sql

5.4 权限最小化(生产环境必做)

  1. MGR通信用户仅授予必要权限,取消远程全量授权:

    sql 复制代码
    REVOKE ALL PRIVILEGES ON *.* FROM 'mgr_repl'@'%';
    GRANT REPLICATION SLAVE, GROUP_REPLICATION_ADMIN ON *.* TO 'mgr_repl'@'192.168.1.%';
    FLUSH PRIVILEGES;
  2. root用户限制IP访问:CREATE USER 'root'@'192.168.1.%' IDENTIFIED BY 'MySQL@123456';

六、常见问题与解决

6.1 节点加入集群失败(MEMBER_STATE=ERROR)

  • 原因:节点server-id重复、GTID不一致、防火墙未开放33061端口;
  • 解决:
    1. 检查server-id是否唯一;
    2. 重置GTID:RESET MASTER;
    3. 验证33061端口连通性:telnet 192.168.1.30 33061

6.2 故障切换后新主节点无法写入

  • 原因:单主模式未开启、super_read_only未自动关闭;

  • 解决:

    sql 复制代码
    SET GLOBAL group_replication_single_primary_mode=ON;
    SET GLOBAL super_read_only=OFF;

6.3 集群脑裂(节点状态不一致)

  • 原因:网络分区、节点数量为偶数;
  • 解决:
    1. 保证集群节点数为奇数(3/5/7);
    2. 配置group_replication_member_expel_timeout=5(缩短节点驱逐超时)。
相关推荐
b***594316 小时前
mysql 迁移达梦数据库出现的 sql 语法问题 以及迁移方案
数据库·sql·mysql
木风小助理16 小时前
MySQL中COUNT()、COUNT(1)与COUNT
数据库
不想上班的小吕16 小时前
采购申请创建(BAPI_PR_CREATE/BAPI_REQUISITION_CREATE)
java·服务器·数据库
j***894616 小时前
MySQL官网驱动下载(jar包驱动和ODBC驱动)【详细教程】
数据库·mysql
emma羊羊16 小时前
Vulhub-Mysql靶场
数据库·mysql
橘橙黄又青17 小时前
mongodb的基本命令
数据库·mongodb
AC赳赳老秦17 小时前
量化交易脚本开发:DeepSeek生成技术指标计算与信号触发代码
数据库·elasticsearch·信息可视化·流程图·数据库架构·memcached·deepseek
何中应17 小时前
Redis的两个小错误
数据库·redis·缓存
Dovis(誓平步青云)17 小时前
《Linux 核心 IO 模型深析(中篇):探索Cmake与多路转接的高效实现poll》
linux·运维·服务器·数据库·csdn成长记录