在中小规模 MySQL 高可用架构中,InnoDB ReplicaSet 凭借其轻量、易配置、原生适配 MySQL 的特性,成为替代传统主从复制的优选方案。它基于 GTID(全局事务标识符)实现数据同步,支持手动 / 自动故障转移,无需依赖外部组件(如 MHA),大幅降低运维复杂度。本文将以 MySQL 8.0.32 版本为例,从环境准备、前置配置、ReplicaSet 搭建,到手动切换与状态验证,提供一套可落地的完整操作流程。
一、InnoDB ReplicaSet 核心价值与环境说明
1. 为何选择 InnoDB ReplicaSet?
相较于传统主从复制,InnoDB ReplicaSet 具备三大核心优势:
- 原生集成:无需额外部署第三方工具,通过 MySQL Shell 即可完成配置与管理,降低技术栈复杂度;
- GTID 原生支持:基于 GTID 同步事务,避免传统复制中 "binlog 文件 + 位置" 的定位难题,切换主从更可靠;
- 轻量高可用:支持 1 主多从架构,可手动触发主从切换,满足中小业务的高可用需求(若需自动故障转移,可搭配 MySQL Router)。
2. 实验环境准备
本次配置基于两台 CentOS 7.9 服务器,MySQL 版本统一为 8.0.32(需确保主从版本一致,避免兼容性问题),具体信息如下:
节点角色 | 服务器 IP | 主机名 | MySQL 版本 | 核心功能 |
---|---|---|---|---|
初始主库 | 192.168.137.4 | mytest3 | 8.0.32 | 写入数据、作为 ReplicaSet 初始 PRIMARY |
初始从库 | 192.168.137.5 | mytest4 | 8.0.32 | 同步主库数据、作为 ReplicaSet SECONDARY |
前置依赖:
- 两台服务器已安装 MySQL 8.0.32(推荐通过官方 YUM 源安装,确保组件完整);
- 关闭防火墙或开放 MySQL 端口(3306)与 MySQL Shell 通信端口(默认无特殊端口,依赖 TCP 连接);
- 主从服务器之间可通过 IP 互通(建议配置主机名解析,避免 IP 直接依赖);
- 准备具备
SUPER
、REPLICATION SLAVE
权限的 MySQL 账号(本文使用 root 账号,生产环境建议创建专用运维账号)。
二、前置配置:主从库基础参数调整
InnoDB ReplicaSet 依赖 GTID 与 binlog 实现同步,需先调整主从库的 MySQL 配置文件(默认路径 /etc/my.cnf
或 /etc/mysql/my.cnf
),确保核心参数一致。
1. 主库(mytest3,192.168.137.4)配置
编辑配置文件,添加或修改以下参数:
[mysqld]
# 唯一标识,主从库必须不同(建议用 IP 后段,如 4、5)
server-id = 4
# 开启 binlog,指定存储路径(需确保目录存在且有写入权限)
log_bin = /var/lib/mysql/mysql-bin
# binlog 格式为 ROW(ReplicaSet 推荐,支持细粒度数据同步)
binlog_format = ROW
# 开启 GTID(核心,确保事务可追溯)
gtid_mode = ON
# 强制 GTID 一致性(避免非 GTID 事务干扰同步)
enforce_gtid_consistency = ON
# 保留 binlog 天数(根据需求调整,避免磁盘占满,建议 7 天)
expire_logs_days = 7
# 开启从库只读(主库无需设置,从库需开启)
# read_only = ON # 主库暂不开启,从库配置时添加
2. 从库(mytest4,192.168.137.5)配置
与主库配置类似,仅需修改 server-id
并添加 read_only
参数:
[mysqld]
server-id = 5 # 必须与主库不同
log_bin = /var/lib/mysql/mysql-bin
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
expire_logs_days = 7
read_only = ON # 从库开启只读,避免直接写入
3. 生效配置
修改参数后,重启主从库的 MySQL 服务,确保配置生效:
# 主库与从库均执行
systemctl restart mysqld
# 验证服务状态(确保 active (running))
systemctl status mysqld
4. 验证核心参数
登录 MySQL 终端,验证 GTID 与 binlog 是否正常开启:
-- 主库与从库均执行
show variables like '%server_id%'; # 主库应显示 4,从库显示 5
show variables like '%gtid_mode%'; # 结果应为 ON
show variables like '%log_bin%'; # 结果应为 ON
三、InnoDB ReplicaSet 搭建:基于 MySQL Shell
MySQL Shell 是管理 InnoDB ReplicaSet 的核心工具,需先确保主从库已安装(MySQL 8.0 系列默认自带,若缺失可通过 yum install mysql-shell
补充安装)。
1. 登录主库并初始化 ReplicaSet
步骤 1:启动 MySQL Shell 并连接主库
在任意一台服务器(建议在主库本地)启动 MySQL Shell,通过 root 账号连接主库:
# 格式:mysqlsh 用户名@主库IP --password
mysqlsh root@192.168.137.4 --password
输入 root 密码后,若提示 MySQL 8.0.32
版本信息且进入 JS >
交互模式,说明连接成功。
步骤 2:创建 ReplicaSet
在 MySQL Shell 中,通过 dba.createReplicaSet()
初始化 ReplicaSet,指定集群名称(本文为 mytest_rs
):
// 创建 ReplicaSet,名称自定义(建议包含业务标识)
var rs = dba.createReplicaSet('mytest_rs')
执行后,系统会自动将当前连接的主库(192.168.137.4)设为 PRIMARY
节点,并初始化 GTID 同步配置。若提示 ReplicaSet object successfully created
,说明初始化成功。
步骤 3:验证主库状态
通过 rs.status()
查看 ReplicaSet 初始状态,重点关注 primary
与 members
字段:
rs.status()
正常输出应包含:
primary: "root@192.168.137.4:3306"
(主库角色确认);members
列表中仅包含主库,状态为ONLINE
。
2. 添加从库到 ReplicaSet
步骤 1:连接并验证从库
在 MySQL Shell 中,保持主库连接状态,执行 rs.addInstance()
添加从库(192.168.137.5):
javascript
// 添加从库,格式:rs.addInstance('用户名@从库IP')
rs.addInstance('root@192.168.137.5')
执行后,系统会提示:
- 确认从库是否为 "新实例"(首次加入 ReplicaSet,选择
y
); - 输入从库 root 密码(确保与主库密码一致或已授权)。
步骤 2:自动同步初始化
系统会自动完成以下操作:
- 检查从库的
server-id
、GTID 配置是否符合要求; - 基于主库的 GTID 自动定位同步起点,无需手动指定 binlog 文件与位置;
- 启动从库的同步线程(IO Thread + SQL Thread)。
若提示 Instance 'root@192.168.137.5:3306' successfully added to the ReplicaSet
,说明从库添加成功。
步骤 3:验证 ReplicaSet 完整状态
再次执行 rs.status()
,此时 members
列表应包含两台节点:
- 主库(192.168.137.4):角色
PRIMARY
,状态ONLINE
; - 从库(192.168.137.5):角色
SECONDARY
,状态ONLINE
,且replicationState
为SYNCED
(同步正常)。
四、手动切换主从:核心操作与验证
InnoDB ReplicaSet 支持手动将 SECONDARY
节点切换为 PRIMARY
,适用于主库维护、故障转移等场景,操作零数据丢失(基于 GTID 同步)。
1. 切换前准备
步骤 1:确认同步状态
切换前需确保从库已同步主库所有事务,避免数据不一致:
// 查看从库同步详情
rs.status().members.forEach(m => {
if (m.host === '192.168.137.5:3306') {
console.log('从库同步状态:', m.replicationState)
console.log('已同步 GTID:', m.gtidExecuted)
}
})
需确保 replicationState
为 SYNCED
,且 gtidExecuted
与主库的 gtidExecuted
一致(可通过主库 show master status
查看)。
步骤 2:停止主库写入(可选,生产环境建议)
若为计划性切换(如主库升级),建议先停止业务写入,避免切换过程中产生新事务:
-- 在主库执行,设置为只读(仅影响业务,不影响同步)
set global super_read_only = ON;
2. 执行手动切换
通过 rs.setPrimaryInstance()
指定新主库(从库 IP),触发切换:
// 格式:rs.setPrimaryInstance('新主库IP或连接串')
rs.setPrimaryInstance('192.168.137.5')
系统会自动完成:
- 停止原主库的
PRIMARY
角色,将其设为SECONDARY
; - 提升从库为
PRIMARY
,并开启写入权限(自动关闭read_only
); - 重新建立同步关系(原主库同步新主库数据)。
若提示 Instance 'root@192.168.137.5:3306' successfully promoted to PRIMARY
,说明切换成功。
3. 切换后验证
步骤 1:确认角色变更
执行 rs.status()
,验证新角色:
primary: "root@192.168.137.5:3306"
(从库已成为新主库);- 原主库(192.168.137.4)角色变为
SECONDARY
,状态ONLINE
,同步状态SYNCED
。
步骤 2:数据一致性验证
在新主库(192.168.137.5)写入测试数据:
-- 新主库执行
create database if not exists test_rs;
use test_rs;
create table t1 (id int primary key auto_increment, name varchar(20));
insert into t1 (name) values ('replica_test');
在原主库(192.168.137.4)查询数据,确认同步正常:
-- 原主库执行
use test_rs;
select * from t1; # 应返回 (1, 'replica_test')
步骤 3:业务接入验证(生产环境必做)
若已部署 MySQL Router,需确认 Router 已自动识别新主库;若直接连接数据库,需将业务连接地址切换为新主库 IP(192.168.137.5),测试写入与查询正常。
五、常见问题排查与注意事项
1. 从库添加失败:"server-id 重复"
报错信息:The server id of the instance is the same as another member
原因:主从库 server-id
相同,违反 ReplicaSet 唯一性要求。
解决方案:修改从库 my.cnf
中的 server-id
(确保与主库不同),重启 MySQL 服务后重新添加。
2. 同步状态异常:"replicationState: ERROR"
报错信息:Error connecting to source 'root@192.168.137.4:3306'
原因:主从库网络不通、root 账号无复制权限,或 binlog 日志损坏。
解决方案:
- 检查防火墙:
firewall-cmd --list-ports
,确保 3306 端口开放; - 验证主库账号权限:
grant replication slave on *.* to 'root'@'%';
; - 重置从库同步:
rs.resetInstance('root@192.168.137.5')
,重新添加。
3. 切换失败:"instance is not a SECONDARY"
报错信息:Cannot promote instance 'root@192.168.137.5:3306' as it is not a SECONDARY
原因:从库未完成初始化,或当前角色不是 SECONDARY
。
解决方案:等待从库状态变为 ONLINE
且 replicationState: SYNCED
,再执行切换。
六、总结
InnoDB ReplicaSet 为 MySQL 8.0 提供了轻量级、易维护的高可用方案,相比传统主从复制,它简化了同步配置与主从切换流程,且原生支持 GTID,数据一致性更有保障。本文通过 "环境准备→参数配置→ReplicaSet 搭建→手动切换" 的完整流程,可满足中小业务的高可用需求。