MySQL8.0基于GTID的组复制分布式集群的环境部署

发布于:2025-07-11 ⋅ 阅读:(20) ⋅ 点赞:(0)

前言:

         需要清楚知道:MySQL 复制组能够以一种自动优先选择的单主模式运行,在某个时间只有一个服务器接受更新 。但是对于更高优先级的用户,组能够以多主模式部署,所有的服务器都能够接受更新,即使它们是同时发生的。组复制中存在着一种内建的组成员关系服务用来保持组的视图一致,并且在任意时间对于组中的所有的服务器都可用。MySQL 服务器能够退出或者加入组中,而且视图也会相应的更新。有时服务器可能会意外的退出组 (故障),在这种情况下失败检测机制检测这种情况并且告知复制组视图发生了变化,这所有的一切都是自动实现的。

目录

1.服务器环境部署

2.MGR组复制单主模式配置

(1)组复制第一个实例配置

①参数配置

②重启服务

③用户凭据

④组复制插件

⑤加入组复制

⑥数据测试

(2)组复制添加其他实例成员

①参数配置

②重启服务

③用户凭据

④组复制插件

⑤加入组复制

(3)数据测试

总结


1.服务器环境部署

本节实验环境部署的是mysql 8.0.42三台实例

主机名 IP Server ID OS MySQL version
node1 192.168.72.163 81 OpenEuler24.3 Mysql 8.0.42
node2 192.168.72.164 82 OpenEuler24.3 Mysql 8.0.42
node3 192.168.72.165 83 OpenEuler24.3 Mysql 8.0.42
#所有主机添加hosts解析
[root@node1 ~]# cat /etc/hosts
192.168.72.163 node1
192.168.72.164 node2
192.168.72.165 node3

2.MGR组复制单主模式配置

(本案例采用 MGR 默认单主模式)。

(1)组复制第一个实例配置
①参数配置

先给这组 MGR 起个组名,组名可以随便起,但是不能使用主机的 GTID.

可以通过节点的 UUID 作为 loose-group_replication_group_name 的组名,并且每个节点的这个组名必须一样!

这里使用参照官网设置手册,如下设置组名,https://dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html

 # 如果要通过节点的UUID设置组名,查看节点node1的uid
 [root@node1 mysql]# cat /var/lib/mysql/auto.cnf 
 [auto]
 server-uuid=dd746660-528a-11ed-9c86-000c293b9f86
     -- 或者通过sql查看
 mysql> select uuid();
 +--------------------------------------+
 | uuid()                               |
 +--------------------------------------+
 | bf4b19ea-60f1-11ed-a06b-000c293b9f86 |
 +--------------------------------------+
 # 配置参数文件
 [root@node1 ~]# vim /etc/my.cnf
 [mysqld]
 # 原有默认配置
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
log-error=/var/log/mysql/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
# 密码验证方式
default_authentication_plugin=mysql_native_password
#Storage Engines
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#Replication Framework
server_id=81
gtid_mode=ON
enforce_gtid_consistency=ON
​binlog_checksum=NONE
 ​
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE
transaction_write_set_extraction=XXHASH64
 ​
sync-master-info =1
sync_binlog =1
#Group Replication Settings
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= "node1:33061"
group_replication_group_seeds= "node1:33061,node2:33061,node3:33061"
group_replication_bootstrap_group=off
# 双主模式,如果是单主模式无需配置,默认单主模式
 # 当前不配置,后续切换多主模式后再持久化该参数
 # group_replication_single_primary_mode=off
 # group_replication_enforce_update_everywhere_checks=on

参数说明:

 #以便在server收集写集合的同时将其记录到二进制日志。写集合基于每行的主键,并且是行更改后的唯一标识此标识将用于检测冲突。
 transaction_write_set_extraction=XXHASH64
 plugin_load_add='group_replication.so'
 #组的名字可以随便起,但不能用主机的GTID! 所有节点的这个组名必须保持一致!
 group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
 #为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。
 group_replication_start_on_boot=off
 group_replication_local_address= "node1:33061"
 group_replication_group_seeds= "node1:33061,node2:33061,node3:33061"
 group_replication_bootstrap_group=off
 #关闭单主模式的参数
 #group_replication_single_primary_mode=off
 #开启多主模式的参数
 #group_replication_enforce_update_everywhere_checks=on
②重启服务
 # 所有节点
 systemctl restart mysqld
③用户凭据

为了在每个实例上单独创建复制用户,可以禁用二进制日志记录后再创建,请按照以下语句执行:

https://dev.mysql.com/doc/refman/8.0/en/group-replication-user-credentials.html

[root@node1 ~]# mysql -proot
mysql>
# mysql8默认密码认证方式,客户端是无法连接的,使用mysql_native_password,或在参数文件中加入参数
# default_authentication_plugin=mysql_native_password
# CREATE USER repl@'%' IDENTIFIED BY 'repl';
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED with mysql_native_password BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
 ​
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';

修改mysql密码 

进入mysql创建复制用户

④组复制插件
 # 安装组复制插件
 # INSTALL PLUGIN group_replication SONAME 'group_replication.so';
 # 本次已经在配置文件添加引导,无需再次安装
 mysql> SHOW PLUGINS;
 +----------------------------+----------+--------------------+----------------------+-------------+
 | Name                       | Status   | Type               | Library              | License     |
 +----------------------------+----------+--------------------+----------------------+-------------+
 | binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | PROPRIETARY |
 ​
 (...)
 ​
 | group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | PROPRIETARY |
 +----------------------------+----------+--------------------+----------------------+-------------+
⑤加入组复制
 # 引导只能由单个服务器完成,即启动组的服务器并且只执行一次。
 # 这就是为什么group_replication_bootstrap_group选项的值没有存储在实例的选项文件中的原因。
 # 如果它保存在选项文件中,则在重新启动服务器时会自动引导第二个具有相同名称的组。这将导致两个不同的组具有相同的名称
 mysql>
SET GLOBAL group_replication_bootstrap_group=ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group=OFF;
SELECT * FROM performance_schema.replication_group_members;
 # 可以检查该组现在是否已创建并且其中有一个成员
 # 要保证group_replication_applier的状态为"ONLINE"!
mysql> SELECT * FROM performance_schema.replication_group_members;
 +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
 | CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
 +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
 | group_replication_applier | dd746660-528a-11ed-9c86-000c293b9f86 | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.31         | XCom                       |
 +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
 1 row in set (0.00 sec)
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Query OK, 0 rows affected (0.00 sec)

mysql>  START GROUP_REPLICATION;

Query OK, 0 rows affected (1.30 sec)

mysql>  SET GLOBAL group_replication_bootstrap_group=OFF;
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | fa4f25e1-5beb-11f0-885f-000c29c274d2 | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.42         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
1 row in set (0.00 sec)

⑥数据测试
 # 组复制环境下要求每个表都需要有主键,否则表上的DML会报错:
 # ERROR 3098 (HY000): The table does not comply with the requirements by an external plugin.
 mysql>
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
INSERT INTO t1 VALUES (1, 'Luis');
 ​
mysql> SELECT * FROM test.t1;
 +----+------+
 | c1 | c2   |
 +----+------+
 |  1 | Luis |
 +----+------+
mysql> SHOW BINLOG EVENTS;
mysql> CREATE DATABASE test;
Query OK, 1 row affected (0.00 sec)

mysql> USE test;
Database changed
mysql>  CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.03 sec)

mysql> SELECT * FROM test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)

mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+-----------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                              |
+---------------+-----+----------------+-----------+-------------+-----------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         126 | Server ver: 8.0.42, Binlog ver: 4 |
| binlog.000001 | 126 | Previous_gtids |         1 |         157 |                                   |
| binlog.000001 | 157 | Stop           |         1 |         180 |                                   |
+---------------+-----+----------------+-----------+-------------+-----------------------------------+
3 rows in set (0.00 sec)

(2)组复制添加其他实例成员
①参数配置

参数配置和第一个节点的参数类似,只需修改server_idgroup_replication_local_address.

 # 将参数文件拷贝到其他节点
 [root@node1 ~]# scp /etc/my.cnf root@node2:/etc/my.cnf
 [root@node1 ~]# scp /etc/my.cnf root@node3:/etc/my.cnf
 ​
 # 配置参数文件,其他参数相同,修改如下两个参数
 [root@node2 ~]# vim /etc/my.cnf
 [mysqld]
 server_id = 82
 group_replication_local_address= "node2:33061"
 [root@node3 ~]# vim /etc/my.cnf
 [mysqld]
 server_id = 83
 group_replication_local_address= "node3:33061"

切换到node2主机修改配置文件 

 切换到node3主机修改配置文件

②重启服务
 # 所有节点
 systemctl restart mysqld
③用户凭据

为了在每个实例上单独创建复制用户,可以禁用二进制日志记录后再创建,请按照以下语句执行:

User Credentials For Distributed Recovery

mysql>
SET SQL_LOG_BIN=0;
CREATE USER repl@'%' IDENTIFIED BY 'repl';
GRANT REPLICATION SLAVE ON *.* TO repl@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;
 ​
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';

切换到node2主机创建复制用户

 切换到node3主机创建复制用户

④组复制插件
 # 安装组复制插件
 # INSTALL PLUGIN group_replication SONAME 'group_replication.so';
 # 本次已经在配置文件添加引导,无需再次安装
⑤加入组复制
 #这里只需要执行这一步即可,因为组已经创建
 mysql> START GROUP_REPLICATION;
 #查看组内情况,发现node2,node3已经成功加入这个组了
 #一主两从模式
 mysql> SELECT * FROM performance_schema.replication_group_members;
 +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
 | CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
 +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
 | group_replication_applier | 2dd88a45-6161-11ed-b5d2-000c299aa451 | node3       |        3306 | ONLINE       | SECONDARY   | 8.0.31         | XCom                       |
 | group_replication_applier | 30c9d73b-6161-11ed-b523-000c2913fd72 | node2       |        3306 | ONLINE       | SECONDARY   | 8.0.31         | XCom                       |
 | group_replication_applier | 32710bb7-6161-11ed-b45b-000c29b2256f | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.31         | XCom                       |
 +---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
 3 rows in set (0.00 sec)

切换到node2主机加入组复制 

切换到node3主机加入组复制 

(3)数据测试
#主库创建
mysql> CREATE DATABASE recovery_test;
Query OK, 1 row affected (0.01 sec)
mysql> USE recovery_test;
Database changed
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.01 sec)

#从库查询
mysql> SELECT * FROM recovery_test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+
1 row in set (0.00 sec)
#主库添加数据
INSERT INTO recovery_test.t1 VALUES (2, 'Klaus');
#从库查询
mysql>  SELECT * FROM recovery_test.t1;
+----+-------+
| c1 | c2    |
+----+-------+
|  1 | Luis  |
|  2 | Klaus |
+----+-------+
2 rows in set (0.00 sec)

node2验证 

node3验证

以上验证成功后,组复制配置结束

总结:

        基于GTID的组复制通过事务唯一标识+自动位点同步,显著简化了分布式集群的运维复杂度。部署核心在于:

        1.全节点GTID参数统一配置;

        2.初始数据强一致保障;

        3.多主架构下冲突解决策略优化;

        4.配套半同步复制与自动故障转移提升可用性。

        5.生产环境中需持续监控GTID执行进度,并规避非事务引擎操作,以维持集群稳定性。