MySQL Group Replication是MySQL服务器的一个插件;组中的每台服务器都需要配置和安装该插件。本文将介绍如何创建一个包含三个MySQL服务器实例的复制组,每个实例都运行在不同的主机上。
要部署多个MySQL实例,您可以使用InnoDB Cluster,它使您能够在MySQL Shell中轻松管理一组MySQL服务器实例。InnoDB Cluster将MySQL Group Replication封装在一个编程环境中,使您能够轻松部署MySQL实例集群以实现高可用性。此外,InnoDB Cluster与MySQL Router无缝对接,使您的应用程序无需编写自己的故障转移流程即可连接到集群。然而,对于不需要高可用性的类似用例,您可以使用InnoDB ReplicaSet。
1. 部署规划
本过程演示了使用多台主机部署实例,这些实例分别命名为dbserver01、dbserver02和dbserver03。假设每台主机上都已安装MySQL Serve。
实例 |
ip |
OS |
描述 |
dbserver01 |
192.168.1.10 |
CentOS Stream release 9 |
主节点 |
dbserver02 |
192.168.1.13 |
CentOS Stream release 9 |
从节点 |
dbserver03 |
192.168.1.15 |
CentOS Stream release 9 |
从节点 |
集群结构图:
2. 修改服务器配置
在三台服务器上分别修改服务器名称为dbserver01,dbserver02,dbserver03
hostnamectl set-hostname dbserver01
hostnamectl set-hostname dbserver02
hostnamectl set-hostname dbserver03
在三台服务器上修改
vi /etc/hosts
192.168.1.10 dbserver01
192.168.1.13 dbserver02
192.168.1.15 dbserver03
禁止selinux
vi /etc/sysconfig/selinux
禁止防火墙
systemctl stop firewalld
systemctl disable firewalld
3. 安装mysql
Mysql安装方法有好多种,本案为了实现MGR,采用基于RPM的Linux发行版上安装MySQL,使用下载的Oracle提供RPM包。以下步骤需要在3台服务器上执行。
(1) 首先下载mysql-9.4.0-1.el9.x86_64.rpm-bundle.tar到本地服务器。
(2) 解压安装文件
tar xvf mysql-9.4.0-1.el9.x86_64.rpm-bundle.tar
(3) 安装
yum install mysql-community-client-plugins-9.4.0-1.el9.x86_64.rpm
yum install mysql-community-client-9.4.0-1.el9.x86_64.rpm
yum install mysql-community-common-9.4.0-1.el9.x86_64.rpm
yum install mysql-community-icu-data-files-9.4.0-1.el9.x86_64.rpm
yum install mysql-community-libs-9.4.0-1.el9.x86_64.rpm
yun install mysql-community-devel-9.4.0-1.el9.x86_64.rpm
yum install mysql-community-server-9.4.0-1.el9.x86_64.rpm
启动数据库
systemctl start mysqld
4. MGR配置主节点实例
在dbserver01服务器上配置
[root@DBSERVER01 ~]# vi /etc/my.cnf
bind-address=0.0.0.0 # 打开远程连接
4.1 存储引擎配置
对于组复制,数据必须存储在InnoDB事务存储引擎中。使用其他存储引擎,包括临时内存存储引擎,可能会导致组复制中的错误。
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
4.2 复制框架
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
这些设置将服务器配置为使用唯一标识符1,启用使用全局事务标识符的复制,并仅允许执行可以使用GTID安全记录的语句。
binlog_checksum=CRC32
MySQL 9.4中的组复制支持二进制日志中存在校验和,并可以使用它们来验证某些通道上事件的完整性,因此您可以使用默认设置。MySQL 9.4默认情况下启用校验和。
4.3 Group Replication 配置
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "dbserver01:33061"
group_replication_group_seeds= "dbserver01:33061,dbserver02:33061,dbserver03:33061"
group_replication_bootstrap_group=off
- plugin_load_add将Group Replication插件添加到服务器启动时加载的插件列表中。
- group_replication_group_name 配置加入或创建的组名为“aaaaaaa-aaaaaaaa-aaaa-aaa-aaaa”。
group_replication_group_name的值必须是有效的UUID。您可以使用SELECT UUID()生成一个。此UUID是GTID的一部分,当组成员从客户端接收到的事务以及组成员内部生成的视图更改事件被写入二进制日志时,会使用GTID。
3. 将group_replication_start_on_boot变量配置为关闭会指示插件在服务器启动时不自动启动操作。这在设置组复制时很重要,因为它确保您可以在手动启动插件之前配置服务器。配置成员后,您可以将group_replication_start_on_boot设置为on,以便在服务器启动时自动启动组复制。
4. 配置group_replication_local_address设置成员用于与组中其他成员进行内部通信的网络地址和端口。组复制将此地址用于涉及组通信引擎(XCom,Paxos变体)远程实例的内部成员到成员连接。
5. 配置group_replication_group_seeds设置组成员的主机名和端口,新成员使用这些主机名和端口建立与组的连接。这些成员被称为种子成员。建立连接后,组成员资格信息将列在性能模式表replication_group_members中。通常,group_replication_group_seeds列表包含每个组成员的group_replication_local_address的hostname:port,但这不是强制性的,可以选择组成员的子集作为种子。group_replication_group_seeds中列出的hostname:port是种子成员的内部网络地址,由group_replication_local_address配置,而不是用于SQL客户端连接的hostname:port。
启动组的服务器不使用此选项,因为它是初始服务器,因此负责引导组。换句话说,引导组的服务器上的任何现有数据都将用作下一个加入成员的数据。第二个服务器加入会要求组中唯一的成员加入,第二台服务器上的任何缺失数据都会从引导成员上的供体数据中复制,然后组会扩展。第三个加入的服务器可以要求这两个服务器中的任何一个加入,数据同步到新成员,然后组再次扩展。后续服务器在加入时重复此过程。
当同时加入多个服务器时,请确保它们指向已在组中的种子成员。不要使用也作为种子加入组的成员,因为联系时他们可能还不在组中。
最好先启动引导成员,然后让它创建组。然后将其设置为其他正在加入的成员的种子成员。这确保了在加入其他成员时形成一个组。
不支持创建组并同时加入多个成员。它可能会奏效,但很可能是操作竞争,然后加入组的行为最终会出现错误或超时。
6. 配置group_replication_boottrap_group会指示插件是否引导该组。在这种情况下,即使dbserver01是组的第一个成员,也要在选项文件中将此变量设置为关闭。相反,在实例运行时配置group_replication_boottrap_group,以确保只有一个成员实际引导该组。
group_replication_boottrap_group变量在任何时候都只能在属于某个组的一个服务器实例上启用,通常是在第一次引导该组时(或者在整个组被关闭并再次恢复的情况下)。如果多次启用引导组,例如当多个服务器实例设置了此选项时,它们可以创建一个人工的大脑分裂场景,其中存在两个同名的不同组。在第一个服务器实例联机后,要始终将group_replication_boottrap_group设置为关闭。
主节点my.cnf配置:
bind-address=0.0.0.0
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "dbserver01:33061"
group_replication_group_seeds= "dbserver01:33061,dbserver02:33061,dbserver03:33061"
group_replication_bootstrap_group=off
4.4 创建用于分布式恢复的复制用户
1. 启动MySQL服务器实例,然后将客户端连接到它。
2. 禁用二进制日志记录,以便在每个实例上分别创建复制用户
mysql> SET SQL_LOG_BIN=0;
3. 创建具有以下权限的MySQL用户:
mysql> CREATE USER mgr_admin@'%' IDENTIFIED BY 'P@mgr2099';
mysql> GRANT REPLICATION SLAVE ON *.* TO mgr_admin@'%';
mysql> GRANT CONNECTION_ADMIN ON *.* TO mgr_admin@'%';
mysql> GRANT BACKUP_ADMIN ON *.* TO mgr_admin@'%';
mysql> GRANT GROUP_REPLICATION_STREAM ON *.* TO mgr_admin@'%';
mysql> FLUSH PRIVILEGES;
REPLICATION SLAVE: 复制从属,这是与主节点建立分布式恢复连接以检索数据所必需的。
CONNECTION_ADMIN: 确保在所涉及的服务器之一处于脱机模式时,组复制连接不会终止。
BACKUP_ADMIN: 如果复制组中的服务器设置为支持克隆,成员需要此特权才能在分布式恢复的克隆操作中进行。
GROUP_REPLICATION_STREAM: 如果MySQL通信栈正在用于复制组,用户帐户需要此权限才能使用MySQL通信栈建立和维护组复制的连接。
4. 如果禁用了二进制日志记录,请在创建用户后立即通过发出以下语句重新启用它。
mysql> SET SQL_LOG_BIN=1;
5. 启动组复制
(1). 确保服务器s1上安装了组复制插件,如果没有按下面语句安装。
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
(2). 查看group replication组件
mysql> show plugins;
(3). 引导组启动复制
首次启动组的过程称为自举。您可以使用group_replication_boottrap_group系统变量引导组。引导只能由一个服务器完成,即启动组的服务器,并且只能执行一次。这就是为什么group_replication_boottrap_group选项的值没有存储在实例的选项文件中的原因。如果它保存在选项文件中,则在重新启动时,服务器会自动引导第二个同名组。这将导致两个不同的组具有相同的名称。同样的道理也适用于在将此选项设置为ON的情况下停止和重新启动插件。因此,为了安全地引导组,请连接到dbserver01并发出以下语句:
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
# 如果需要提供分布式恢复的用户凭据START GROUP_REPLICATION USER='mgr_admin', PASSWORD='P@mgr2099';
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;
(4). 查看mgr的状态
mysql> SELECT * FROM performance_schema.replication_group_members;
此表中的信息确认组中有一个成员具有唯一标识符 a200e9b3-6b02-11f0-86d7-000c29dfd734,该成员处于联机状态,并且位于dbserver01,正在端口3306上侦听客户端连接。
(5). 创建一个表并向其中添加记录进行测试
mysql> CREATE DATABASE test;
mysql> USE test;
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
mysql> INSERT INTO t1 VALUES (1, 'szflower');
(6) 检查表t1和二进制日志的内容。
mysql> SELECT * FROM t1;
mysql> SHOW BINLOG EVENTS;
如上所述,创建了数据库和表对象,并将其相应的DDL语句写入二进制日志。此外,数据被插入到表中并写入二进制日志,因此可以通过从主节点的二进制日志进行状态转移来进行分布式恢复。
6. 向组中添加第二个实例(dbserver02)
(1) 配置my.cnf
[root@DBSERVER02 soft]# vi /etc/my.cnf
增加:
bind-address=0.0.0.0
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "dbserver02:33061"
group_replication_group_seeds= "dbserver01:33061,dbserver02:33061,dbserver03:33061"
group_replication_bootstrap_group= off
(2) 重启mysql服务
[root@DBSERVER02 soft]# systemctl restart mysqld
(3) 创建复制用户
与服务器s1的过程类似,使用选项文件启动服务器。然后按如下方式配置分布式恢复凭据。这些命令与设置服务器s1时使用的命令相同,因为用户在组内共享。此成员需要配置相同的复制用户。如果您依赖分布式恢复在所有成员上配置用户,则当dbserver02连接到种子dbserver01时,复制用户将被复制或克隆到dbserver01。如果在dbserver01上配置用户凭据时未启用二进制日志记录,并且未使用远程克隆操作进行状态传输,则必须在dbserver02上创建复制用户。在这种情况下,连接到dbserver02并执行:
mysql> SET SQL_LOG_BIN=0;
CREATE USER mgr_admin@'%' IDENTIFIED BY 'P@mgr2099';
GRANT REPLICATION SLAVE ON *.* TO mgr_admin@'%';
GRANT CONNECTION_ADMIN ON *.* TO mgr_admin@'%';
GRANT BACKUP_ADMIN ON *.* TO mgr_admin@'%';
GRANT GROUP_REPLICATION_STREAM ON *.* TO mgr_admin@'%';
FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
# 如果您使用CHANGE REPLICATION SOURCE TO提供用户凭据,请在之后发出以下声明:CHANGE REPLICATION SOURCE TO SOURCE_USER='mgr_admin', SOURCE_PASSWORD='P@mgr2099' FOR CHANNEL 'group_replication_recovery';
如有必要,安装组复制插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
(4) 启动组复制,dbserver02加入组。
mysql> START GROUP_REPLICATION;
# 如果您在START GROUP_REPLICATION中提供分布式恢复的用户凭据,可以这样做:
mysql> START GROUP_REPLICATION USER='mgr_admin', PASSWORD='P@mgr2099';
当组复制成功启动并且服务器加入组时,它会检查super_read_only变量。通过在成员的配置文件中将super_read_only设置为ON,可以确保在启动组复制时因任何原因失败的服务器不接受事务。如果服务器应作为读/写实例加入该组,例如作为单个主组中的主服务器或作为多主组的成员,则当super_read_only设置为ON时,它在加入该组时设置为OFF。
(5) 查看复制组状态
mysql> select * from performance_schema.replication_group_members;
或者mysql>TABLE performance_schema.replication_group_member_stats;
可以看到组中已经有两个实例存在。
- 验证dbserver02是否确实已与服务器dbserver01同步
mysql> SHOW DATABASES LIKE 'test';
一开始可能会出现数据库test没有同步过来。
日志错误:
[ERROR] [MY-010584] [Repl] Replica I/O for channel 'group_replication_recovery': Error connecting to source 'mgr_admin@DBSERVER01:3306'. This was attempt 1/1, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection. Error_code: MY-002061
2025-07-28T10:20:54.632259Z 114 [ERROR] [MY-011582] [Repl] Plugin group_replication reported: 'There was an error when connecting to the donor server. Please check that group_replication_recovery channel credentials and all MEMBER_HOST column values of performance_schema.replication_group_members table are correct and DNS resolvable.'
经排查,原因 mysql8.0之后加密规则变成 caching_sha2_password。
解决方法:在主节点打开公钥访问
mysql> set global group_replication_recovery_get_public_key=on;
然后到dbserver02去再次查询
mysql> SHOW DATABASES LIKE 'test';
此时,可以看到数据库test已经同步过来。
mysql> SELECT * FROM test.t1;
t1 表数据也正常同步过来。
mysql> SHOW BINLOG EVENTS;
7. 添加第三个实例到组中
(1) 配置my.cnf
[root@DBSERVER02 soft]# vi /etc/my.cnf
增加:
bind-address=0.0.0.0
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "dbserver03:33061"
group_replication_group_seeds= "dbserver01:33061,dbserver02:33061,dbserver03:33061"
group_replication_bootstrap_group= off
(2) 重启mysql服务
[root@DBSERVER02 soft]# systemctl restart mysqld
(3) 创建复制用户
mysql> SET SQL_LOG_BIN=0;
CREATE USER mgr_admin@'%' IDENTIFIED BY 'P@mgr2099';
GRANT REPLICATION SLAVE ON *.* TO mgr_admin@'%';
GRANT CONNECTION_ADMIN ON *.* TO mgr_admin@'%';
GRANT BACKUP_ADMIN ON *.* TO mgr_admin@'%';
GRANT GROUP_REPLICATION_STREAM ON *.* TO mgr_admin@'%';
FLUSH PRIVILEGES;
mysql> SET SQL_LOG_BIN=1;
# 如果您使用CHANGE REPLICATION SOURCE TO提供用户凭据,请在之后发出以下声明:CHANGE REPLICATION SOURCE TO SOURCE_USER='mgr_admin', SOURCE_PASSWORD='P@mgr2099' FOR CHANNEL 'group_replication_recovery';
如有必要,安装组复制插件
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
(4) 启动组复制,dbserver03加入组。
mysql> START GROUP_REPLICATION;
# 如果您在START GROUP_REPLICATION中提供分布式恢复的用户凭据,可以这样做:
mysql> START GROUP_REPLICATION USER='mgr_admin', PASSWORD='P@mgr2099';
(5) 查看集群状态
mysql> SELECT * FROM performance_schema.replication_group_members;
或者mysql>TABLE performance_schema.replication_group_member_stats;
- 验证集群同步
mysql> SHOW DATABASES LIKE 'test';
mysql> SELECT * FROM test.t1;
mysql> SHOW BINLOG EVENTS;