部署MGR集群(OpenEuler版步骤详细可参考)

时间:2024-03-12 16:21:38

MGR集群理论知识:

MGR具备以下几个特点:

  1. 基于shared-nothing模式,所有节点都有一份完整数据,发生故障时可以直接切换。

  2. MGR提供了数据一致性保障,默认是最终一致性,可根据业务特征需要自行调整一致性级别。

  3. 支持在线添加、删除节点,节点管理更方便。

  4. 支持故障自动检测及自动切换,发生故障时能自动切换到新的主节点,再配合MySQL Router中间件,应用层无需干预或调整。

  5. 支持单节点、多节点写入两种模式,可根据架构或业务需要选择哪种方案,不过强烈建议选用单主模式

一开始S1节点是Primary角色,提供读写服务。当它发生故障时,剩下的S2-S5节点会再投票选举出S2作为新的Primary角色提供读写服务,而S1节点在达到一定超时阈值后,就会被踢出。

一开始S1-S5所有节点都是Primary角色,都可以提供读写服务,任何一个节点发生故障时,只需要把指向这个节点的流量切换下就行。

上述两种架构模式下,应用端通过MySQL Router连接后端在MGR服务,当后端节点发生切换时,Router会自动感知,对应用端来说几乎是透明的,影响很小,架构上也更灵活。

MGR技术架构:

MGR是以Plugin方式嵌入MySQL,部署更灵活方便。

事务从Server层通过钩子(hook)进入MGR API接口层,再分发到各组件层,在组件层完成事务Capture/Apply/Recover,通过复制协议层(Replication Protocol Logics)传输事务,最后经由GCS协调事务在各节点的最终一致性。

MGR节点间由组通信系统(GCS)提供支持,它提供了故障检测机制、组成员角色管理,以及安全且有序的消息传递,这些机制可确保在各节点间一致地复制数据。这项技术的核心是Paxos算法的实现,在MySQL里称之为XCom,由它充当MGR的通信引擎。

对于要提交的事务,组中的多数派节点必须就全局事务序列中给定的事务顺序达成一致。各节点做出决定提交或中止事务的选择,但所有节点都要做出相同的决定。如果发生网络分区,导致节点间无法达成一致决定,则在网络恢复前,MGR无法工作。

MGR支持单主和多主两种模式,在单主模式下,各节点会自动选定主节点,只有该主节点能同时读写,而其他(从)节点只能只读。在多主模式下,所有节点都可以进行读写。

实验目的:

如何利用MySQL8.0.35构建一个三节点的MGR集群

实验步骤:

1.安装准备

IP 端口 角色
192.168.27.142 3306 node1
192.168.27.143 3306 node2
192.168.27.144 3306 node3

2.配置hosts解析并下载安装MySQL8.0.35

[root@localhost ~]# hostnamectl set-hostname node1 //3台都要进行修改分别为1,2,3
[root@localhost ~]# cat >> /etc/hosts << EOF //配置hosts解析
> 192.168.27.142 node1
> 192.168.27.143 node2
> 192.168.27.144 node3
> EOF
[root@localhost ~]# yum install mysql-server -y //下载mysql8.0.35(可用yum list | grep -i ^mysql-命令来查看版本信息)

3.修改mysql配置文件

[root@localhost ~]# vim /etc/my.cnf*.d/mysql-server.cnf //修改配置文件
在末行添加如下项:
#开启GTID,必须开启
gtid_mode = ON
#强制GTID的一致性
enforce_gtid_consistency = ON
#binlog格式,MGR要求必须是ROW,不过就算不是MGR,也最好用
binlog_format = row
#server-id必须是唯一的
server-id = 1
#MGR使用乐观锁,所以官网建议隔离级别是RC,减少锁粒度
transaction_isolation = READ-COMMITTED
#因为集群会在故障恢复时互相检查binlog的数据,
#所以需要记录下集群内其他服务器发过来已经执行过的binlog,按GTID来区分是否执行过.
log-slave-updates = 1
#binlog校验规则,5.6之后的高版本是CRC32,低版本都是NONE,但是MGR要求使用NONE
binlog_checksum = NONE
#基于安全的考虑,MGR集群要求复制模式要改成slave记录记录到表中,不然就报错
master_info_repository = TABLE
#同上配套
relay_log_info_repository = TABLE
#组复制设置#记录事务的算法,官网建议设置该参数使用 XXHASH64 算法
transaction_write_set_extraction = XXHASH64
#相当于此GROUP的名字,是UUID值,不能和集群内其他GTID值的UUID混用,可用uuidgen来生成一个新的,
#主要是用来区分整个内网里边的各个不同的GROUP,而且也是这个group内的GTID值的UUID
loose-group_replication_group_name = '5dbabbe6-8050-49a0-9131-1de449167446'
#IP地址白名单,默认只添加127.0.0.1,不会允许来自外部主机的连接,按需安全设置
loose-group_replication_ip_whitelist = '127.0.0.1/8,192.168.0.0/16'
#是否随服务器启动而自动启动组复制,不建议直接启动,怕故障恢复时有扰乱数据准确性的特殊情况
loose-group_replication_start_on_boot = OFF
#本地MGR的IP地址和端口,host:port,是MGR的端口,不是数据库的端口
loose-group_replication_local_address = '192.168.27.142:33081'
#需要接受本MGR实例控制的服务器IP地址和端口,是MGR的端口,不是数据库的端口
loose-group_replication_group_seeds = '192.168.27.142:33081,192.168.27.143:33081,192.168.27.144:33081'
#开启引导模式,添加组成员,用于第一次搭建MGR或重建MGR的时候使用,只需要在集群内的其中一台开启,
loose-group_replication_bootstrap_group = OFF
#是否启动单主模式,如果启动,则本实例是主库,提供读写,其他实例仅提供读,如果为off就是多主模式了
loose-group_replication_single_primary_mode = ON
[root@localhost ~]# scp /etc/my.cnf.d/mysql-server.cnf node2:/etc/my.cnf.d/
[root@localhost ~]# scp /etc/my.cnf.d/mysql-server.cnf node3:/etc/my.cnf.d/ //使用scp讲改好的node1配置文件拷贝到node2和3的/etc/my.cnf.d/目录中
[root@localhost ~]# vim /etc/my.cnf.d/mysql-server.cnf //在node2和3中使用vim进入相应路径下对文件进行更改,主要注意更改server_id和loose-group_replication_local_address的值
[root@localhost ~]# systemctl restart mysqld //重启文件使更改的配置文件生效

4.安装相应插件

[root@localhost ~]# mysql -e "install plugin group_replication soname 'group_replication.so'" //node2和3同理也要进行配置
[root@localhost ~]# mysql -e "show plugins;" | grep "group_replication"
group_replication	ACTIVE	GROUP REPLICATION    group_replication.so	GPL

5.配置账号

创建MGR服务专用账户,并准备配置MGR服务通道:
#每个节点都要单独创建用户
mysql> set session sql_log_bin=0;
mysql> create user repl@'%' identified with mysql_native_password by 'repl';
mysql> GRANT BACKUP_ADMIN, REPLICATION SLAVE ON *.* TO `repl`@`%`;
#创建完用户后继续启用binlog记录
mysql> set session sql_log_bin=1;
#配置MGR服务通道
#通道名字 group_replication_recovery 是固定的,不能修改
mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';

6.启动mgr单主模式

在node1中进行:
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 warning (1.35 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 | a4752c1f-df97-11ee-a714-000c29bc1c9a | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
1 row in set (0.00 sec)
在node2和3中,进入mysql:
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.04 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 | 9ec42d13-df97-11ee-a8a8-000c29877e50 | node2       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
| group_replication_applier | a4752c1f-df97-11ee-a714-000c29bc1c9a | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
2 rows in set (0.01 sec)
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (2.32 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 | 9a88699b-df97-11ee-96ac-000c295da631 | node3       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
| group_replication_applier | 9ec42d13-df97-11ee-a8a8-000c29877e50 | node2       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
| group_replication_applier | a4752c1f-df97-11ee-a714-000c29bc1c9a | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
3 rows in set (0.00 sec)
看到上面这个集群共有3个节点处于ONLINE状态,其中 192.168.27.142 是 PRIMARY 节点,其余两个都是 SECONDARY 节点,也就是说当前这个集群采用 单主 模式。如果采用多主模式,则所有节点的角色都是 PRIMARY 

7.向MGR集群中写入数据

接下来我们连接到node1节点,创建测试库表并写入数据:
mysql> create database mgr;
Query OK, 1 row affected (0.01 sec)
mysql> use mgr;
Database changed
mysql> create table t1(c1 int unsigned not null primary key);
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t1 select rand()*10240;
Query OK, 1 row affected (0.03 sec)
Records: 1  Duplicates: 0  Warnings: 0
再连接到node2节点,查看刚刚在node1写入的数据是否可以看到:
mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| node2      |
+------------+
1 row in set (0.00 sec)

mysql> select * from mgr.t1;
+------+
| c1   |
+------+
| 3899 |
+------+
1 row in set (0.00 sec)
再连接到node3节点,查看刚刚在node1写入的数据是否可以看到:
mysql> select @@hostname;
+------------+
| @@hostname |
+------------+
| node3      |
+------------+
1 row in set (0.00 sec)

mysql> select * from mgr.t1;
+------+
| c1   |
+------+
| 3899 |
+------+
1 row in set (0.00 sec)

8.MGR管理维护(主节点切换,单主/多主模式切换)

主节点切换:(将Primary角色切换到第二个节点)
mysql>  select group_replication_set_as_primary('9ec42d13-df97-11ee-a8a8-000c29877e50'); //写入node2的server_uuid
+--------------------------------------------------------------------------+
| group_replication_set_as_primary('9ec42d13-df97-11ee-a8a8-000c29877e50') |
+--------------------------------------------------------------------------+
| Primary server switched to: 9ec42d13-df97-11ee-a8a8-000c29877e50         |
+--------------------------------------------------------------------------+
1 row in set (0.01 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 | 9a88699b-df97-11ee-96ac-000c295da631 | node3       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
| group_replication_applier | 9ec42d13-df97-11ee-a8a8-000c29877e50 | node2       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
| group_replication_applier | a4752c1f-df97-11ee-a714-000c29bc1c9a | node1       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
3 rows in set (0.00 sec)
顺便提一下,在MySQL 5.7版本中,只能通过重启以实现主节点的自动切换,不能手动切换。从这个角度来说,如果想要使用MGR,最好是选择MySQL 8.0版本,而不要使用5.7版本。
切换单主/多主模式:(在命令行模式下,可以调用 `group_replication_switch_to_single_primary_mode()` 和 `group_replication_switch_to_multi_primary_mode()` 来切换单主/多主模式。)
mysql> select group_replication_switch_to_multi_primary_mode(); //直接调用函数即可
+--------------------------------------------------+
| group_replication_switch_to_multi_primary_mode() |
+--------------------------------------------------+
| Mode switched to multi-primary successfully.     |
+--------------------------------------------------+
1 row in set (0.01 sec)

mysql>  select * from performance_schema.replication_g;//查看个节点状态
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 9a88699b-df97-11ee-96ac-000c295da631 | node3       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
| group_replication_applier | 9ec42d13-df97-11ee-a8a8-000c29877e50 | node2       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
| group_replication_applier | a4752c1f-df97-11ee-a714-000c29bc1c9a | node1       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
3 rows in set (0.00 sec)
切换成单主模式时可以指定某个节点的 server_uuid,如果不指定则会根据规则自动选择一个新的主节点。在这里,我选择了指定node3节点作为新主节点
mysql> select group_replication_switch_to_single_primary_mode('9a88699b-df97-11ee-96ac-000c295da631');
+-----------------------------------------------------------------------------------------+
| group_replication_switch_to_single_primary_mode('9a88699b-df97-11ee-96ac-000c295da631') |
+-----------------------------------------------------------------------------------------+
| Mode switched to single-primary successfully.                                           |
+-----------------------------------------------------------------------------------------+
1 row in set (0.02 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 | 9a88699b-df97-11ee-96ac-000c295da631 | node3       |        3306 | ONLINE       | PRIMARY     | 8.0.35         | XCom                       |
| group_replication_applier | 9ec42d13-df97-11ee-a8a8-000c29877e50 | node2       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
| group_replication_applier | a4752c1f-df97-11ee-a714-000c29bc1c9a | node1       |        3306 | ONLINE       | SECONDARY   | 8.0.35         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
3 rows in set (0.00 sec)
在已经是单主模式时,无论是 `group_replication_switch_to_single_primary_mode()` 还是 `switchToSinglePrimaryMode()` 函数中指定另一个节点时是不会发生切换的,但也不会报错,只有提示。

9.添加新节点

首先,要先完成MySQL Server初始化,创建好MGR专用账户、设置好MGR服务通道等前置工作。接下来,直接执行命令start group_replication启动MGR服务即可,新增的节点会进入分布式恢复这个步骤,它会从已有节点中自动选择一个作为捐献者(donor),并自行决定是直接读取binlog行恢复,还是利用Clone进行全量恢复。如果是已经在线运行一段时间的MGR集群,有一定存量数据,这时候新节点加入可能会比较慢,建议手动利用Clone进行一次全量复制。

IP 端口
192.168.27.137 3306
#在node4上设置捐献者
#为了降低对Primary节点的影响,建议选择其他Secondary节点
mysql>set global clone_valid_donor_list='192.168.27.137:3306';
#停掉mgr服务(如果有的话),关闭super_read_only模式,然后开始复制数据
#注意这里要填写的端口是3306(MySQL正常服务端口),而不是33061这个MGR服务专用端口
mysql> stop group_replication; set global super_read_only=0; clone INSTANCE FROM repl@192.168.27.142:3306 IDENTIFIED BY 'repl';

10.删除节点

在命令行模式下,一个节点想退出MGR集群,直接执行 stop group_replication即可,如果这个节点只是临时退出集群,后面还想加回集群,则执行 start group_replication 即可自动再加入。而如果是想彻底退出集群,则停止MGR服务后,执行 reset master; reset slave all; 重置所有复制(包含MGR)相关的信息就可以了。

11.异常退出的节点重新加回

当节点因为网络断开、实例crash等异常情况与MGR集群断开连接后,这个节点的状态会变成 UNREACHABLE,待到超过 group_replication_member_expel_timeout + 5 秒后,集群会踢掉该节点。等到这个节点再次启动并执行 start group_replication,正常情况下,该节点应能自动重新加回集群。

12.重启MGR集群

正常情况下,MGR集群中的Primary节点退出时,剩下的节点会自动选出新的Primary节点。当最后一个节点也退出时,相当于整个MGR集群都关闭了。这时候任何一个节点启动MGR服务后,都不会自动成为Primary节点,需要在启动MGR服务前,先设置 group_replication_bootstrap_group=ON,使其成为引导节点,再启动MGR服务,它才会成为Primary节点,后续启动的其他节点也才能正常加入集群。