MySQL——高可用之组复制MGR
  vxNQtvtQlfbi 2023年11月27日 14 0

一、MySQL 高可用的背景

数据库的主从复制是一个很实用的功能,但如何保证它的高可用却是一件难事。实现MySQL主从复制高可用的工具,常见的有:

  • MMM:淘汰了,在一致性和高并发稳定性等方面有些问题。
  • MHA:有些人还在用,但也有些问题,也是趋于淘汰的MySQL主从高可用方案。
  • Galera:引领时代的主从复制高可用技术。
  • MariaDB Galera Cluster:MariaDB对Galera的实现。
  • PXC:Percona XtraDB Cluster,是Percona对Galera的自我实现,用的人似乎很多。
  • GR:Group Replication,MySQL官方提供的组复制技术(MySQL 5.7.17引入的技术),基于Paxos算法。

但是,上面每个高可用实现方法,都有这样那样的缺点,甚至mmm还是通过perl脚本来自动化模拟高可用环境的。到了Galera,这是一个引领潮流的高可用技术,它主要针对具有事务特性的Innodb存储引擎,Percona和MariaDB都分别实现了自己的Galera技术:MariaDB Galera Cluster和Percona XtraDB Cluster。MySQL没有推出自己的Galera,但却在2016年的MySQL 5.7.17版本中推出了Group Replication,即组复制技术。

 

网上对组复制和 Galera 的对比很多,特别是 2016 年组复制出生后大火的" Galera 将死"的言论,但实际上,仍然有很多人在用着 pxc,毕竟它已经扬帆航行多年,而 GR 才出没多久,前几个版本也一直在修修补补。

二、组复制 (MGR)介绍

MySQL Group Replication(简称MGR)是MySQL官方于2016年12月推出的一个全新的高可用与高扩展的解决方案。MGR是MySQL官方在5.7.17版本引入的一个服务器插件,可用于创建高可用、可扩展、容错的复制拓扑结构。它基于原生的主从复制,将各节点归入到一个组中,通过组内节点的通信协商(组通信协议基于Paxos算法),实现数据的强一致性、故障探测、冲突检测、节点加组、节点离组等等功能。以3个节点的组为例:

image.png

在MGR出现之前,用户常见的MySQL高可用方式,无论怎么变化架构,本质就是Master-Slave架构。MySQL 5.7版本开始支持无损半同步复制(lossless semi-sync replication),从而进一步提示数据复制的强一致性。

 

MGR是MySQL数据库未来发展的一个重要方向。MGR是以Plugin的形式嵌入在MySQL实例中,插件内部实现了冲突检测、Paxos协议通信等。MGR有一个内置的组成员服务,在任何给定的时间点,保持组的视图一致并可供所有服务器使用。服务器可以离开并加入组,视图也会相应更新。当成员离开组,故障检测机制会检测到此情况并通知组视图已更改。

 

MySQL组复制分单主模式和多主模式,mysql 的复制技术仅解决了数据同步的问题,如果 master 宕机,意味着数据库管理员需要介入,应用系统可能需要修改数据库连接地址或者重启才能实现。(这里也可以使用数据库中间件产品来避免应用系统数据库连接的问题,例如 mycat 和 atlas 等产品)。组复制在数据库层面上做到了,只要集群中大多数主机可用,则服务可用,也就是说3台服务器的集群,允许其中1台宕机。

image.png

注意: 组中server可在独立物理机运行,也可在同一台机器,同一机器采用多实例,也就是逻辑认为是独立机器; 组内每台主机,都需要先安装组复制插件,否则会导致启动失败。

2.1、MGR组复制的特点

  • 高一致性:基于分布式paxos协议实现组复制,保证数据一致性;
  • 高容错性:自动检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制;
  • 高扩展性:节点的增加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,直到与其他节点数据一致;
  • 高灵活性:提供单主模式和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。

2.2、MGR与传统复制的区别和大幅改进

2.2.1 传统复制 (即异步复制)

主-从复制:有一个主和不等数量的从。主节点执行的事务会异步发送给从节点,在从节点重新执行。即是在主节点执行和提交事务,然后把他们异步的发送到从节点,行复制的重新执行主节点的SQL语句,这是一个 shared-nothing 的系统,默认情况下所有 server 成员都有一个完整的数据副本。 image.png

2.2.2 半同步复制

它在协议中添加了一个同步步骤。 这意味着主节点在提交时需要等待从节点确认它已经接收到事务。只有这样,主节点才能继续提交操作。 半同步相对异步来说, Master会确认Slave是否接到数据,更加安全。 image.png

2.2.3 并行复制

并行复制:复制->广播->正式复制。

2.2.4 组复制 (MGR)

三、MGR组复制原理

3.1 MGR插件体系结构

MGR是一个MySQL插件,它以现有的MySQL复制架构为基础,利用二进制日志、基于行的日志记录和全局事务标识符(GTID)等功能。 image.png

  • Capture/Apply/Lifecycle APIs:MGR插件包含一组捕获、应用和生命周期API,用于控制插件与MySQL服务器的交互方式。这些接口将MySQL服务器核心与MGR插件隔离。服务器向插件通知启动、恢复、准备接收连接、即将提交事务等消息。插件指示服务器执行诸如提交事务、中止正在进行的事务、事务在中继日志中排队等动作。

  • Capture/Apply/Recovery组件:

    • 捕获组件Capture负责跟踪与正在执行的事务相关的上下文;
    • 应用组件Apply负责在数据库上执行远程事务;
    • 恢复组件Recovery管理分布式恢复,负责选择捐赠者,对故障做出反应,执行追赶程序,使加入该组的服务器获得更新。
    • Replication Protocol Logics:复制协议模块包含复制协议的特定逻辑。它处理冲突检测,接收事务并将其传播到组。
  • 组复制插件体系结构的最后两层是组通信系统(GCS)API,以及基于Paxos的组通信引擎(XCom)的实现。GCS API将消息传递层的实现与插件上层分离,组通信引擎处理与复制组成员的通信。

3.2 MGR复制原理

组复制是一种可用于实现容错系统的技术。 复制组是一个通过消息传递相互交互的 server 集群。通信层提供了原子消息(atomic message)和完全有序信息交互等保障机制实现了基于复制协议的多主更新 复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。

 

换句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。

 

这种原子广播的方式,使得这个事务在每一个节点上都保持着同样顺序。这意味着每一个节点都以同样的顺序,接收到了同样的事务日志,所以每一个节点以同样的顺序重演了这些事务日志,最终整个组内保持了完全一致的状态。

 

MySQL组复制协议工作流程如下image.png

需要注意:MGR组复制是一种 share-nothing 复制方案,其中每个 server 成员都有自己的完整数据副本。

对于在不同的节点上执行的事务之间有可能存在资源争用,特别是在两个不同的并发事务上。假设在不同的节点上有两个并发事务,更新了同一行数据,那么就会发生资源争用。面对这种情况,组复制会判定先提交的事务为有效事务,会在整个组内重演,后提交的事务会直接中断,或者回滚,最后丢弃掉。因此,组复制MGR是一个无共享的复制方案,每一个节点都保存了完整的数据副本。

3.2.1 MGR实现了基于复制协议的多主更新

  • 1、复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。
  • 2、换句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server 成员以相同的顺序接收同一组事务。因此,所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。
  • 3、组复制使您能够根据在一组 server 中复制系统的状态来创建具有冗余的容错系统。因此,只要它不是全部或多数 server 发生故障,即使有一些 server 故障,系统仍然可用,最多只是性能和可伸缩性降低,但它仍然可用。server 故障是孤立并且独立的。它们由组成员服务来监控,组成员服务依赖于分布式故障检测系统,其能够在任何 server 自愿地或由于意外停止而离开组时发出信号。
  • 4、他们是由一个分布式恢复程序来确保当有 server 加入组时,它们会自动更新组信息到最新。并且多主更新确保了即使在单个服务器故障的情况下也不会阻止更新,不必进行 server故障转移。因此,MySQL 组复制保证数据库服务持续可用。
  • 5、值得注意的一点是,尽管数据库服务可用,但当有一个 server 崩溃时,连接到它的客户端必须定向或故障转移到不同的 server。这不是组复制要解决的问题。连接器,负载均衡器,路由器或其他形式的中间件更适合处理这个问题。

总之,MGR组复制提供了高可用性,高弹性,可靠的 MySQL 服务。

3.2.2 MGR复制模式

MGR有两种复制模式:单主模式和多主模式。在单主模式下,组复制具有自动选主功能,每次只有一个节点负责写入,读可以从任意一个节点读取,组内数据保持最终一致。多主模式下,所有的节点都可以同时接受读写,也能够保证组内数据最终一致性。

1、单主模式

复制组内只有一台节点可写可读,其他节点只可以读。单写模式MGR的部署流程如下:

  • 首先运行主节点(即那个可写可读的节点,read_only = 0
  • 运行其他的节点,并把这些节点一一加进group。其他的节点就会自动同步主节点上面的变化,然后将自己设置为只读模式(read_only = 1)。
  • 当主节点意外宕机或者下线,在满足大多数节点存活的情况下,group内部发起选举,选出下一个可用的读节点,提升为主节点。
  • 主选举根据group内剩下存活节点的UUID按字典序升序来选择,即剩余存活的节点按UUID字典序排列,然后选择排在最前的节点作为新的主节点。
2、多写模式

组内的所有机器都是主节点,同时可以进行读写操作,并且数据是最终一致的。

  • 首先关闭单主模式开关loose-group_replication_single_primary_mode=OFF
  • 运行第一个节点,设置loose-group_replication_bootstrap_group=ON
  • 运行其它节点,并START GROUP_REPLICATION加入到group组中
  • 当组内的某个节点发生故障时,会自动从将该节点从组内踢出,与其他节点隔离。剩余的节点之间保持主从复制的正常同步关系。当该节点的故障恢复后,只需手动激活组复制即可(即执行"START GROUP_REPLICATION;");

3.2.3 MGR故障检测

故障检测是提供关于哪些 server 可能已死的信息(猜测)的分布式服务。 某个 server 无响应时触发猜测,组中其余成员进行协调决定以排除给定成员。如果某个 server 与组的其余成员隔离,则它会怀疑所有其他 server 都失败了。由于无法与组达成协议(因为它无法确保仲裁成员数),其怀疑不会产生后果。当服务器以此方式与组隔离时,它无法执行任何本地事务。 在线 server 列表通常称为视图,新成员server的加入离开,无论是自愿还是被迫的离开,该组都会动态地重新规划其配置,并触发视图更新。

3.2.4 MGR复制的限制

  • 存储引擎必须为Innodb,即仅支持InnoDB表
  • 每个表必须提供主键,用于做write set的冲突检测
  • 只支持ipv4,网络需求较高;
  • 必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set;
  • COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景;
  • 目前一个MGR集群组最多支持9个节点;
  • 不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚;
  • 二进制日志binlog不支持Replication event checksums;
  • 多主模式(也就是多写模式) 不支持SERIALIZABLE事务隔离级别;
  • 多主模式不能完全支持级联外键约束;
  • 多主模式不支持在不同节点上对同一个数据库对象并发执行DDL(在不同节点上对同一行并发进行RW事务,后发起的事务会失败);

3.2.5 MGR复制特点

MGR复制有以下特点: image.png

3.2.6 MGR组复制优势

  • 弹性复制(高扩展性):server动态添加移除
  • 高可用分片(高扩展性):分片实现写扩展,每个分片是一个复制组。
  • 替代主从复制(高扩展性):整组写入,避免单点争用。
  • 自动化系统:自动化部署Mysql复制到已有复制协议的自动化系统。
  • 故障检测与容错:自动检测,若服务faild,组内成员大多数达成认为该服务已不正常,则自动隔离。
  • 组内成员会构成一个视图,组内成员主动加入或离开(主动或被动),都会更新组配置,更新视图。成员自愿离开,先更新组配置,然后采用大多数成员(不包含主动脱离的成员)意见是否确认该成员离开更新视图。如果是故障要排除,则需大多数服务确认(包括故障成员意见),然后才会更新组配置和视图。
  • 最大允许即时故障数:f=(n-1)/2,多数正常则正常

四、MGR组复制测试

下面分别记录下 MGR 基于单主模式和多主模式的集群环境部署过程

4.1 准备环境

三台服务器
192.168.121.211     MGR-node1    server_id=1
192.168.121.212     MGR-node2    server_id=2
192.168.121.213     MGR-node3    server_id=3

[root@MGR-node1 ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)
为了方便实验,关闭所有节点的防火墙
[root@MGR-node1 ~]# systemctl stop firewalld
[root@MGR-node1 ~]# firewall-cmd --state
not running
[root@MGR-node1 ~]# cat /etc/sysconfig/selinux |grep "SELINUX=disabled"
SELINUX=disabled
[root@MGR-node1 ~]# setenforce 0           
setenforce: SELinux is disabled
[root@MGR-node1 ~]# getenforce             
Disabled
特别要注意一个关键点: 必须保证各个mysql节点的主机名不一致,并且能通过主机名找到各成员!
则必须要在每个节点的/etc/hosts里面做主机名绑定,否则后续将节点加入group组会失败!报错RECOVERING!!
[root@MGR-node1 ~]# cat /etc/hosts
........
192.168.121.211    MGR-node1
192.168.121.212    MGR-node2
192.168.121.213    MGR-node3

4.2 在三个节点上安装Mysql5.7

在三个mysql节点机上使用yum方式安装Mysql5.7,参考:
安装MySQL yum资源库
[root@MGR-node1 ~]# yum localinstall https://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm
安装MySQL 5.7
[root@MGR-node1 ~]# yum install -y mysql-community-server
启动MySQL服务器和MySQL的自动启动
[root@MGR-node1 ~]# systemctl start mysqld.service
[root@MGR-node1 ~]# systemctl enable mysqld.service
设置登录密码
由于MySQL从5.7开始不允许首次安装后使用空密码进行登录!为了加强安全性,系统会随机生成一个密码以供管理员首次登录使用,
这个密码记录在/var/log/mysqld.log文件中,使用下面的命令可以查看此密码:
[root@MGR-node1 ~]# cat /var/log/mysqld.log|grep 'A temporary password'
2019-01-11T05:53:17.824073Z 1 [Note] A temporary password is generated for root@localhost: TaN.k:*Qw2xs
使用上面查看的密码TaN.k:*Qw2xs 登录mysql,并重置密码为123456
[root@MGR-node1 ~]# mysql -p                 #输入默认的密码:TaN.k:*Qw2xs
.............
mysql> set global validate_password_policy=0;
Query OK, 0 rows affected (0.00 sec)    
mysql> set global validate_password_length=1;
Query OK, 0 rows affected (0.00 se
mysql> set password=password("123456");
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
查看mysql版本
[root@MGR-node1 ~]# mysql -p123456
........
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.7.24    |
+-----------+
1 row in set (0.00 sec)
=====================================================================

温馨提示
mysql5.7通过上面默认安装后,执行语句可能会报错:
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements
这个报错与Mysql 密码安全策略validate_password_policy的值有关,validate_password_policy可以取0、1、2三个值:
解决办法:
set global validate_password_policy=0;
set global validate_password_length=1;

4.3 安装和配置MGR信息

1) 配置所有节点的组复制信息
MGR-node01节点
[root@MGR-node1 ~]# cp /etc/my.cnf /etc/my.cnf.bak
[root@MGR-node1 ~]# >/etc/my.cnf
[root@MGR-node1 ~]# vim /etc/my.cnf
[mysqld]
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
symbolic-links = 0        
log-error = /var/log/mysqld.log
pid-file = /var/run/mysqld/mysqld.pid
#复制框架
server_id=1
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 
#组复制设置
#server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列
transaction_write_set_extraction=XXHASH64
#告知插件加入或创建组命名,UUID
loose-group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
#server启动时不自启组复制,为了避免每次启动自动引导具有相同名称的第二个组,所以设置为OFF。
loose-group_replication_start_on_boot=off
#告诉插件使用IP地址,端口24901用于接收组中其他成员转入连接
loose-group_replication_local_address="192.168.121.211:24901"
#启动组server,种子server,加入组应该连接这些的ip和端口;其他server要加入组得由组成员同意
loose-group_replication_group_seeds="192.168.121.211:24901,192.168.121.212:24901,192.168.121.213:24901"
loose-group_replication_bootstrap_group=off
report_host=192.168.121.211
report_port=3306
如上配置完成后, 将MGR-node1节点的/etc/my.cnf文件拷贝到其他两个节点
[root@MGR-node1 ~]# rsync -e "ssh -p22" -avpgolr /etc/my.cnf root@192.168.121.212:/etc/
[root@MGR-node1 ~]# rsync -e "ssh -p22" -avpgolr /etc/my.cnf root@192.168.121.213:/etc/
3个MGR节点除了server_id、loose-group_replication_local_address、report_host 三个参数不一样外,其他保持一致。
所以待拷贝完成后, 分别修改MGR-node2和MGR-node3节点/etc/my.cnf文件的server_id、loose-group_replication_local_address、report_host 三个参数
2) 配置完成后, 要一次启动数据库,安装MGR插件,设置复制账号(所有MGR节点都要执行)
[root@MGR-node1 ~]# systemctl restart mysqld
[root@MGR-node1 ~]# mysql -p123456
.............
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.13 sec)

mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER repl@'%' IDENTIFIED BY 'repl';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT REPLICATION SLAVE ON *.* TO repl@'%';
Query OK, 0 rows affected (0.00 sec)
 
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec) 

mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)

mysql> CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.21 sec)

4.4 启动MGR单主模式

1) 启动MGR,在主库(192.168.121.11)节点上上执行
[root@MGR-node1 ~]# mysql -p123456
...............
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
Qery OK, 0 rows affected (0.00 sec) 

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (2.31 sec)

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

查看MGR组信息
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 192.168.121.211 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
1 row in set (0.01 sec)
2) 在其他节点加入MGR集群,在从库(192.168.121.212,192.168.121.213)上执行
[root@MGR-node2 ~]#  mysql -p123456
................
mysql> START GROUP_REPLICATION;
ERROR 3092 (HY000): The server is not configured properly to be an active member of the group. Please see more details on error lo
查看日志:
[root@MGR-node2 ~]# tail -2000 /var/log/mysqld.log
.....................
.....................
2019-03-04T09:11:30.683714Z 0 [ERROR] Plugin group_replication reported: 'This member has more executed transactions than those present in the group. Local transactions: 87135ebb-3e51-11e9-8931-005056880888:1-2 > Group transactions: 851d03bb-3e51-11e9-8f8d-00505688047c:1-2,
8769f936-3e51-11e9-acaa-005056ac6820:1-2,
aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-4'
2019-03-04T09:11:30.683817Z 0 [Warning] Plugin group_replication reported: 'The member contains transactions not present in the group. It is only allowed to join due to group_replication_allow_local_disjoint_gtids_join optio
解决办法:
mysql> set global group_replication_allow_local_disjoint_gtids_join=ON;
Query OK, 0 rows affected, 1 warning (0.00 sec)
然后再接着加入MGR集群
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (5.14 sec)

3) 再次查看MGR组信息 (在三个MGR节点上都可以查看)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 192.168.121.212 |        3306 | RECOVERING   |
| group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 192.168.121.213 |        3306 | RECOVERING   |
| group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 192.168.121.211 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
3 rows in set (0.00 sec)
发现新加入的MGR-node2 , MGR-node3两个节点在集群里的状态是RECOVERING!!! 
查看日志
[root@MGR-node3 ~]# tail -2000 /var/log/mysqld.log
.....................
.....................
2019-03-04T09:15:35.146740Z 734 [ERROR] Slave I/O for channel 'group_replication_recovery': Got fatal error 1236 from master when
reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has
purged binary logs containing GTIDs that the slave requires.', Error_code: 1236

解决办法:
登录主库192.168.121.211, 查看被purge的GTID:
[root@MGR-node1 ~]#  mysql -p123456
....................
mysql> show global variables like 'gtid_purged';
+---------------+------------------------------------------+
| Variable_name | Value                                    |
+---------------+------------------------------------------+
| gtid_purged   | 8769f936-3e51-11e9-acaa-005056ac6820:1-2 |
+---------------+------------------------------------------+
1 row in set (0.00 sec) 

接着在两个从库192.168.121.212, 192.168.121.213的数据库上执行下面命令,即跳过这个GTID:
mysql> STOP GROUP_REPLICATION;
Query OK, 0 rows affected (10.14 sec)

mysql> reset master;
Query OK, 0 rows affected (0.06 sec)
 
mysql> set global gtid_purged = '8769f936-3e51-11e9-acaa-005056ac6820:1-2';
Query OK, 0 rows affected (0.24 sec)

mysql>  START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (3.49 sec)
 
再次查看查看MGR组信息 (在三个MGR节点上都可以查看),
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 192.168.121.213 |        3306 | ONLINE       |
| group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 192.168.121.211 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
3 rows in set (0.00 sec)
  
通过上面可以看出:  三个MGR节点状态为online,并且主节点为192.168.121.211,只有主节点可以写入,其他两个MGR节点只读,MGR单主模式搭建成功。
 
==============================================================================
验证下MGR单主模式下节点数据的同步以及读写操作:
先在主库节点192.168.121.211上创建测试数据库
[root@MGR-node1 ~]# mysql -p123456
..............
mysql> CREATE DATABASE kevin CHARACTER SET utf8 COLLATE utf8_general_ci;  
Query OK, 1 row affected (0.06 sec)

mysql> use kevin;
Database changed

mysql> create table if not exists haha (id int(10) PRIMARY KEY AUTO_INCREMENT,name varchar(50) NOT NULL);
Query OK, 0 rows affected (0.24 sec)

mysql> insert into kevin.haha values(1,"wangshibo"),(2,"guohuihui"),(3,"yangyang"),(4,"shikui");
Query OK, 4 rows affected (0.13 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
+----+-----------+
4 rows in set (0.00 sec)

接着在其他的两个从节点192.168.121.212和192.168.121.213上查看数据, 发现主库数据已经同步到两个从库上了
[root@MGR-node2 ~]# mysql -p123456
..................
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
+----+-----------+
4 rows in set (0.00 sec)

然后尝试在两个从库上更新数据, 发现更新失败! 因为这是MGR单主模式, 从库只能进行读操作, 不能进行写操作!
[root@MGR-node3 ~]# mysql -p123456
.................
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
+----+-----------+
4 rows in set (0.00 sec)

mysql> delete from kevin.haha where id>3;
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement
mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui");
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

只有在主库上才能进行写操作
[root@MGR-node1 ~]# mysql -p123456
..............
mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui");
Query OK, 3 rows affected (0.15 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
| 11 | beijing   |
| 12 | shanghai  |
| 13 | anhui     |
+----+-----------+
7 rows in set (0.00 sec)

4.5 切换到多主模式

MGR切换模式需要重新启动组复制,因些需要在所有节点上先关闭组复制,设置 group_replication_single_primary_mode=OFF 等参数,再启动组复制。

1) 停止组复制(在所有MGR节点上执行):
mysql> stop group_replication;
Query OK, 0 rows affected (9.08 sec)

mysql> set global group_replication_single_primary_mode=OFF;
Query OK, 0 rows affected (0.00 sec)

mysql> set global group_replication_enforce_update_everywhere_checks=ON;
Query OK, 0 rows affected (0.00 sec)

2) 随便选择某个MGR节点执行 (比如这里选择在MGR-node1节点):
[root@MGR-node1 ~]# mysql -p123456
...............
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 (2.20 sec)

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

3) 然后在其他的MGR节点执行 (这里指MGR-node2和MGR-node3节点上执行):
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (5.89 sec)

4) 查看MGR组信息 (在任意一个MGR节点上都可以查看)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 192.168.121.213 |        3306 | ONLINE       |
| group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 192.168.121.211 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
3 rows in set (0.00 sec)

可以看到所有MGR节点状态都是online,角色都是PRIMARY,MGR多主模式搭建成功。
=========================================
验证下MGR多主模式的节点数据同步:
在MGR-node1节点更新数据:
[root@MGR-node1 ~]# mysql -p123456
.................
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
| 11 | beijing   |
| 12 | shanghai  |
| 13 | anhui     |
+----+-----------+
7 rows in set (0.00 sec)

mysql> delete from kevin.haha where id>10;
Query OK, 3 rows affected (0.08 sec)

在MGR-node2节点更新数据
[root@MGR-node2 ~]# mysql -p123456
...............
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
+----+-----------+
4 rows in set (0.00 sec)
 
mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui");
Query OK, 3 rows affected (0.08 sec)
Records: 3  Duplicates: 0  Warnings: 0

在MGR-node3节点更新数据
[root@MGR-node3 ~]# mysql -p123456
.............
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
| 11 | beijing   |
| 12 | shanghai  |
| 13 | anhui     |
+----+-----------+
7 rows in set (0.00 sec)

mysql> delete from kevin.haha where id>11;
Query OK, 2 rows affected (0.14 sec)

mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
| 11 | beijing   |
+----+-----------+
5 rows in set (0.00 sec)

如上, MGR多主模式下, 所有节点都可以进行读写操作.

4.6 切回单主模式

1) 停止组复制(在所有MGR节点上执行)
mysql> stop group_replication;
Query OK, 0 rows affected (9.29 sec)

mysql> set global group_replication_enforce_update_everywhere_checks=OFF;
Query OK, 0 rows affected (0.00 sec)

mysql> set global group_replication_single_primary_mode=ON;
Query OK, 0 rows affected (0.00 sec)

2) 选择一个节点作为主节点, 在主节点上执行 (这里选择MGR-node1节点作为主节点)
[root@MGR-node1 ~]# mysql -p123456
................
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 (2.12 sec)

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

3) 在其他剩余的节点, 也就是从库节点上执行 (这里从库节点指的就是MGR-node2和MGR-node3):
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected, 1 warning (6.16 sec)

4) 查看MGR组信息 (在任意一个MGR节点上都可以查看)
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 192.168.121.213 |        3306 | ONLINE       |
| group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 192.168.121.211 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
3 rows in set (0.00 sec)

这样就又切回到MGR单主模式了, 其中192.168.121.211是主节点,具有写权限. 另外两个节点192.168.121.212和192.168.121.213是从库节点, 只能读不能写.

4.7 故障切换

1) 单主模式
如果主节点挂掉了, 通过选举程序会从从库节点中选择一个作为主库节点.  如下模拟故障:
关闭主库MGR-node1的mysqld服务
[root@MGR-node1 ~]# systemctl stop mysqld
接着在其他节点上查看MGR组信息. 比如在MGR-node2节点查看
[root@MGR-node2 ~]# mysql -p123456
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 192.168.121.213 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
2 rows in set (0.00 sec)

尝试在MGR-node2节点更新数据
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
| 11 | beijing   |
| 12 | shanghai  |
| 13 | anhui     |
+----+-----------+
7 rows in set (0.00 sec)

mysql> delete from kevin.haha where id>10;
Query OK, 3 rows affected (0.06 sec)
如上, 发现在之前的主库MGR-node1节点挂掉后, MGR-node2节点可以进行写操作了, 说明此时已经选举MGR-node2节点为新的主节点了
那么,MGR-node3节点还是从节点, 只能读不能写
[root@MGR-node3 ~]# mysql -p123456
..............
mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
+----+-----------+
4 rows in set (0.00 sec)

mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui");
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

然后再恢复MGR-node1节点, 恢复后, 需要手动激活下该节点的组复制功能
[root@MGR-node1 ~]# systemctl start mysqld
[root@MGR-node1 ~]# mysql -p123456
...............
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (3.15 sec)

mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST   | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
| group_replication_applier | 851d03bb-3e51-11e9-8f8d-00505688047c | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | 87135ebb-3e51-11e9-8931-005056880888 | 192.168.121.213 |        3306 | ONLINE       |
| group_replication_applier | 8769f936-3e51-11e9-acaa-005056ac6820 | 192.168.121.211 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+---------------+-------------+--------------+
3 rows in set (0.00 sec)

mysql> select * from kevin.haha;
+----+-----------+
| id | name      |
+----+-----------+
|  1 | wangshibo |
|  2 | guohuihui |
|  3 | yangyang  |
|  4 | shikui    |
+----+-----------+
4 rows in set (0.00 sec)

mysql> insert into kevin.haha values(11,"beijing"),(12,"shanghai"),(13,"anhui");
ERROR 1290 (HY000): The MySQL server is running with the --super-read-only option so it cannot execute this statement

发现MGR-node1节点恢复后, 则变为了从库节点, 只能读不能写.
如果从节点挂了, 恢复后, 只需要手动激活下该节点的组复制功能("START GROUP_REPLICATION;"),
即可正常加入到MGR组复制集群内并自动同步其他节点数据.

=============================================================
2)  多主模式
 如果某个节点挂了, 则其他的节点继续进行同步.
 当故障节点恢复后, 只需要手动激活下该节点的组复制功能("START GROUP_REPLICATION;"),
 即可正常加入到MGR组复制集群内并自动同步其他节点数据.

基于Mysql8.0, 安装MGR 单主/多主模式的集群环境

上面案例是基于Mysql5.7版本的操作记录, 如果换成Mysql8.0版本, 则稍微有些地方不一样.
Mysql8.0版本按照上面的操作, 在实操中没有出现报错.
Mysql8.0安装手册:  
查看组信息, 会显示主从角色: PRIMARY 和 SECONDARY

单主模式
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-----------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST     | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-----------------+-------------+--------------+
| group_replication_applier | e03c7b94-801a-11eb-b715-000c29140600 | 192.168.121.211 |        3306 | ONLINE       |
| group_replication_applier | e72b320f-801a-11eb-b758-000c292778a3 | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | f0868e84-801a-11eb-b7c0-000c29f21453 | 192.168.121.213 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-----------------+-------------+--------------+
3 rows in set (0.00 sec)

多主模式
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-----------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST     | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-----------------+-------------+--------------+
| group_replication_applier | e03c7b94-801a-11eb-b715-000c29140600 | 192.168.121.211 |        3306 | ONLINE       |
| group_replication_applier | e72b320f-801a-11eb-b758-000c292778a3 | 192.168.121.212 |        3306 | ONLINE       |
| group_replication_applier | f0868e84-801a-11eb-b7c0-000c29f21453 | 192.168.121.213 |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-----------------+-------------+--------------+
3 rows in set (0.00 sec)

如果节点发生故障, 在恢复后需要重新加入到MGR集群里, 正确的做法是:
先stop组复制, 然后再start组复制! 不然可能会造成加入到集群后的状态是"RECOVERING"!

正确的做法:
mysql> stop GROUP_REPLICATION;
Query OK, 0 rows affected (8.18 sec)

mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (4.16 sec)

设置MGR组集群的白名单网段: 添加节点所在网段

或者出现报错:  '[GCS] The member is leaving a group without being on one.'
这是因为没有设置白名单网段:需要添加节点自己所在网段.

在任意一个MGR节点上执行:
[root@MGR-node1 ~]# mysql -p123456
.................

# 添加白名单网段
mysql> stop group_replication;
Query OK, 0 rows affected (9.41 sec)

mysql> set global group_replication_ip_whitelist="127.0.0.1/32,192.168.121.0/24,172.16.50.0/24,172.16.51.0/24";
Query OK, 0 rows affected (0.00 sec)

mysql> start group_replication;
Query OK, 0 rows affected (3.37 sec)

mysql> show variables like "group_replication_ip_whitelist";
+--------------------------------+-----------------------------------------------------------+
| Variable_name                  | Value                                                     |
+--------------------------------+-----------------------------------------------------------+
| group_replication_ip_whitelist | 127.0.0.1/32,192.168.121.0/24,172.16.50.0/24,172.16.51.0/24 |
+--------------------------------+-----------------------------------------------------------+
1 row in set (0.01 sec)
group_replication_ip_whitelist = <ip,net,...> 
表示设置白名单,若不配置默认为AUTOMATIC,自动识别本机网口的私网地址和私网网段,127.0.0.1 连接请求始终被允许,
一定要注意: 配置白名单前面一定要先关闭 Group Replication, 及先要执行"stop group_replication;"
也可以在/etc/my.cnf文件里配置白名单信息.

参考: https://blog.51cto.com/u_16099229/7612941

https://blog.csdn.net/qq_62789440/article/details/128630617

https://www.shangyexinzhi.com/article/6905338.html

https://blog.csdn.net/solihawk/article/details/118183944

https://blog.csdn.net/oradbm/article/details/130617763

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月27日 0

暂无评论

推荐阅读
vxNQtvtQlfbi