MySQL分布式高可用-MGR
MySQL Group Replication(MGR)是MySQL官方在5.7.17版本引进的一个数据库高可用与高扩展的解决方案,MySQL组复制是一个MySQL Server插件,使您可以创建弹性的,高可用性的,容错的复制拓扑。。MGR基于分布式paxos协议,实现组复制,保证数据一致性。内置故障检测和自动选主功能,只要不是集群中的大多数节点都宕机,就可以继续正常工作。提供单主模式与多主模式,多主模式支持多点写入。
MySQL组复制为分布式状态机复制提供了服务器之间的强大协调。服务器属于同一组时,它们会自动进行协调。该组可以在具有自动主库选举的单主模式下运行,其中一次仅一个服务器接受更新。或者,对于更高级的用户,可以在多主模式下部署组,在该模式下,所有服务器都可以接受更新,即使它们是同时发布的。这种功能的代价是应用程序必须解决此类部署所施加的限制。
有一个内置的组成员资格服务,可以使组的视图一致,并且在任何给定时间点均可用于所有服务器。服务器可以离开并加入该组,视图将相应更新。有时服务器可能会意外离开该组,在这种情况下,故障检测机制会检测到此情况并通知该组视图已更改,这都是自动的。
对于要提交的事务,组的大多数必须在全局事务顺序中就给定事务的顺序达成一致。每个服务器分别决定提交或中止事务,但所有服务器都要做出相同的决定。如果存在网络分区,分裂导致成员无法达成一致,则系统将不会继续运行,直到解决此问题。因此,还有一个内置的自动裂脑保护机制。
所有这些都由提供的组通信系统(GCS,Group Communication System)协议提供支持。其提供故障检测机制、组成员资格服务、安全以及有序的消息传递。所有这些属性是创建系统的关键,该系统可确保在服务器组之间数据的一致性复制。该技术的核心是Paxos算法的实现。它充当组通信引擎。
一、组复制背景
1.1 主从复制
传统的MySQL复制提供了一种简单的主从复制方法。有一个主服务器(主服务器),有一个或多个辅助服务器(从服务器)。主数据库执行事务,将其提交,然后将它们稍后(因此异步)发送给从数据库,以重新执行(在基于语句的复制中)或应用(在基于行的复制中)。它是无共享系统,默认情况下所有服务器均具有数据的完整副本。
半同步复制,它向协议增加了一个同步步骤。这意味着主服务器在提交时等待辅助服务器确认已接收到事务。只有这样,主服务器才会恢复提交操作。
1.2 组复制
组复制是一种可用于实施容错系统的技术。复制组是一组服务器,每个服务器都有自己的完整数据副本(无共享复制方案),并通过消息传递相互交互。通信层提供了一组保证,例如原子消息和总的有序消息的传递。这些非常强大的属性转化为非常有用的抽象,可以用来构建更高级的数据库复制解决方案。
MySQL组复制建立在这些属性和抽象之上,并在所有复制协议中实现多主机更新。复制组由多个服务器组成,该组中的每个服务器都可以随时独立执行事务。但是,所有读写事务只有在组批准后才提交。换句话说,对于任何读写事务,组都需要确定其是否提交,因此提交操作不是来自原始服务器的单方面决定。只读事务不需要组内的协调并立即提交。
当读写事务准备好在原始服务器上提交时,服务器自动广播其写值(已更改的行)和相应的写集和(已更新的行的唯一标识符)。由于事务是通过原子广播发送的,因此该组中的所有服务器都将接收该事务,否则将不会。如果他们收到了,那么相对于之前发送的其他事务,他们都将以相同的顺序收到它。因此,所有服务器都以相同的顺序接收相同的事务集合,并且为事务集建立了一个全局的总顺序。
但是,在不同服务器上同时执行的事务之间可能存在冲突。通过检查和比较两个不同并发事务的写集和,可以在称为certification的进程中检测到此类冲突 。在certification进程中,冲突检测是在行级别执行的:如果在不同服务器上执行的两个并发事务更新同一行,则存在冲突。冲突解决过程指出,以首先提交的事务在所有服务器上提交,而第二个提交的事务被取消,在原始服务器上回滚并由组中的其他服务器丢弃。例如,如果t1和t2在不同的站点上同时执行,都更改了同一行,并且t2在t1之前提交,则t2赢得了冲突,并且t1被回滚。这实际上是一个分布式的首次提交胜出规则。请注意,如果两个交易必然会发生冲突,那么最好在同一服务器上启动它们,这样它们就有机会在本地锁管理器上同步,而不是由于certification而回滚。
二、组复制多主模式和单主模式
群组的模式是一个群组范围的配置设置,由group_replication_single_primary_mode 系统变量指定,所有成员都必须相同。ON表示单主要模式,这是默认模式,OFF表示多主要模式。
2.1 单主模式
在单主模式下,只有一个节点可以读写,其他节点提供只读服务。
选项 group_replication_enforce_update_everywhere_checks 启用或禁用组的严格一致性检查。在单主要模式下部署或将组更改为单主要模式时,必须将此系统变量设置为 OFF。
如果现有的主数据库主动或意外离开该组,则会自动选择一个新的主数据库。
- 可以使用group_replication_set_as_primary()指定特定成员作为新的主数据库(MySQL 8.0.13或更高版本)
- 如果自动选举,考虑的第一个因素是哪个或哪些成员运行最低的MySQL Server版本;
- 考虑的第二个因素是每个成员的成员权重,具体由group_replication_member_weight 系统变量指定;
- 考虑的第三个因素是每个成员所生成的服务器UUID的字典顺序,由server_uuid系统变量指定,服务器UUID最低的成员被选为主服务器。
可以通过以下命令查看单主模式下的成员角色:
mysql> SELECT MEMBER_HOST, MEMBER_ROLE FROM performance_schema.replication_group_members;
+-------------------------+-------------+
| MEMBER_HOST | MEMBER_ROLE |
+-------------------------+-------------+
| remote1.example.com | PRIMARY |
| remote2.example.com | SECONDARY |
| remote3.example.com | SECONDARY |
+-------------------------+-------------+
2.2 多主模式
在mysql多主模式下,在组复制中通过Group Replication Protocol协议及Paxos协议,形成的整体高可用解决方案 同时增加了certify的概念,负责检查事务是否允许提交,是否与其它事务存在冲突,Group Replication是由多个节点共同组成一个数据库集群,每个节点都可以单独执行事务,但是read-write(rw)的操作只有在组内验证后才可以commit,Read-only (RO)事务是不需要验证可以立即执行,当一个事务在一个节点上提交之前,会在组内自动进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务,然后为该事务建立一个全局的排序,最终,这意味着所有的服务器都以相同的顺序接收相同的事务集。因此,所有服务器都按照相同的顺序应用相同的变更集,因此它们在组中保持一致。 在多主模式下,该组的所有成员都设置为读写模式,在多主模式下,不支持SERIALIZABLE事务隔离级别,且不能完全支持级联外键约束。
如果某个成员停止接受写事务(例如,在服务器崩溃的情况下),则可以将与其连接的客户端重定向或故障转移到处于读写模式的任何其他成员。组复制本身不处理客户端故障转移,因此您需要使用中间件框架(例如MySQL Router 8.0,代理,连接器或应用程序本身)来安排此过程。
为了获得最佳兼容性和性能,组中的所有成员应运行相同版本的MySQL Server,运行相同版本的组复制。在多主模式下,这更为重要,因为所有成员通常都将以读写模式加入该组。
三、组复制体系结构
MySQL组复制建立在Paxos分布式算法的实现之上,以提供服务器之间的分布式协调。因此,它需要大多数服务器处于活动状态才能达到法定人数,从而做出决定。这直接影响了系统可以容忍的故障数量,而不会损害自身及其整体功能。这样,容忍f 故障所需的服务器数量(n)为n = 2 x f + 1。
组复制要求最低3台服务器,最高9台服务器。
MySQL Group Replication是一个MySQL插件,它基于现有的MySQL复制基础结构,利用了二进制日志,基于行的日志记录和全局事务标识符等功能。它与当前的MySQL框架集成,例如性能模式或插件和服务基础结构。
MySQL Group Replication插件包括一组用于捕获,应用和生命周期的API,这些API控制插件如何与MySQL Server交互。负责完成和MySQL Server的交互,获取server的状态,截获事务提交,干涉事务提交或者回滚;
组复制插件体系结构的下一层是一组特定功能的组件,Capture负责收集事务执行相关信息,Applier负责应用集群事务到本地,Recovery负责新节点的数据恢复;
复制协议模块包含复制协议的特定逻辑。它处理冲突检测,并接收事务并将其传播到该组。
组复制插件体系结构的最后两层是组通信系统(GCS)API,以及基于Paxos的组通信引擎(XCom)的实现。GCS API是一个高级API,它抽象了构建复制状态机所需的属性,因此,它将消息传递层的实现与插件的其余上层分离。组通信引擎处理与复制组成员的通信。
四、组复制要求和限制
4.1 组复制要求
4.1.1 基础设置
- InnoDB存储引擎:数据必须存储在InnoDB事务存储引擎中。
- 主键(Primary Keys):每个被组复制的表格需要一个定义的主键或等效的主键。注意跟隐式主键区分(使用Innodb引擎的表格,如果没有指定主键,默认选择第一个非空的唯一索引作为主键,如果没有,则自动创建一个6个字节的rowid隐式主键)。这个主键能在冲突发生时启动极其重要的作用,同时,能够有效提高relay log的执行效率。
- 网络性能(Network Performance):网络延迟和网络带宽都会影响组的性能和稳定性。所有组成员之间必须始终保持双向通信,稳定的网络环境可以减少集群状态的变化,良好的网络性能可提高集群吞吐量。
4.1.2 服务实例配置
- 激活二进制日志:设置 —log-bin[=log_file_name]
- 记录从更新:设置 —log-slave-updates,这个选项默认被激活。组成员需要记录加入时从其捐助者处收到并通过复制应用程序应用的事务,并记录他们从组中接收并应用的所有事务。这样,组复制就可以通过从现有组成员的二进制日志进行状态转移来执行分布式恢复。
- 二进制日志raw格式:设置 —binlog-format=row。组复制依靠基于行的复制格式在组中的服务器之间一致地传播更改。它依靠基于行的基础结构来提取必要的信息,以检测在组中的不同服务器中同时执行的事务之间的冲突。
- 关闭二进制日志校验:设置 —binlog-checksum=NONE。由于复制事件校验和的设计限制,组复制无法使用它们,必须将其禁用。
- 开启GTID: 设置 gtid_mode=ON。组复制使用全局事务标识符来准确跟踪每个服务器实例上已提交哪些事务,从而能够推断出哪些服务器已执行可能与其他位置已提交的事务发生冲突的事务。
- 复制Information库:设置 master_info_repository=TABLE 和 relay_log_info_repository=TABLE。复制应用程序需要将主库信息和中继日志元数据写入 mysql.slave_master_info和 mysql.slave_relay_log_info表。这样可以确保组复制插件对复制元数据具有一致的可恢复性和事务管理。
- 事务写入集提取:设置 —transaction-write-set-extraction=XXHASH64。默认情况下启用此选项。
- 二进制日志依赖项跟踪:设置 binlog_transaction_dependency_tracking=WRITESET_SESSION。可以提高组成员的性能,具体取决于组的工作量。
- 默认表加密:设置 —default-table-encryption=ON 在所有组成员上做相同的设置。默认是OFF。
- 小写表格名: 设置 —lower-case-table-names。在所有组成员上 设置相同的值。设置1对于使用InnoDB存储引擎是正确的,这对于组复制是必需的。
- 多线程应用程序:可以将组复制成员配置为多线程从属,从而使事务可以并行应用。slave_parallel_workers设置为非0值,开启所线程,最高1024,;设置slave_preserve_commit_order=1,可确保并行事务的最终提交与原始事务的顺序相同,这是组复制所需的。最后,设置 slave_parallel_type=LOGICAL_CLOCK,指定的策略被用于确定哪些事务在从服务器上被并行执行。slave_parallel_workers=0取消并行执行。
4.2 组复制限制
- –upgrade=MINIMAL 选项:如果使用此选项更新MySQL server,则组复制无法启动
- 间隙锁(Gap Locks):certification进程没有考虑间隙锁。建议将READ COMMITTED 隔离级别与组复制一起使用
- 表锁和命名锁(Table Locks and Named Locks):certification进程没有考虑Table Locks and Named Locks;
- 复制事件校验:不支持,需要设置 —binlog-checksum=NONE。
- SERIALIZABLE隔离级别:SERIALIZABLE隔离级别在多主复制中默认不支持。
- 并行DDL与DML操作:使用多主模式时,不支持针对同一对象但在不同服务器上执行的并发数据定义语句和数据操作语句。
- 具有级联约束的外键:多主模式不支持具有多级外键依赖关系的表,建议设置group_replication_enforce_update_everywhere_checks=ON。
- 多主模式死锁。 当以多主模式运行时, SELECT … FOR UPDATE语句可能导致死锁。
- 复制筛选器: 全局复制筛选器不能在配置用于组复制的MySQL服务器实例上使用,因为在某些服务器上筛选事务会使组无法就一致状态达成协议。
五、配置MGR-单主模式
环境介绍:
角色 | IP地址 | 主机名 | server_id | MySQL版本 | 操作系统 |
---|---|---|---|---|---|
master | 192.168.154.101 | master01 | 101 | MySQL 8.0.18 | CentOS7.7 |
slave | 192.168.154.102 | slave01 | 102 | MySQL 8.0.18 | CentOS7.7 |
slave | 192.168.154.103 | slave02 | 103 | MySQL 8.0.18 | CentOS7.7 |
5.1 修改master01的主配置文件
配置文件/etc/my.cnf
[root@master01 ~]# vim /etc/my.cnf
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#
# Replication configuration parameters
#
server_id=101
log_bin=/var/lib/mysql/binlogs/master01
log_bin_index=/var/lib/mysql/binlogs/master01.index
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
# Group Replication configuration
#
plugin_load_add='group_replication.so'
group_replication_group_name="c651b0bc-3098-11ea-be9d-000c292bfa3e"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.154.101:33061"
group_replication_group_seeds= "192.168.154.101:33061,192.168.154.102:33061,192.168.154.103:33061"
group_replication_bootstrap_group=off
如果是MySQL 8.0.3之前的版本,复制部门还需要配置以下内容:
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE
组复制配置选项说明:
- plugin_load_add:将组复制插件添加到服务器在启动时加载的插件列表中。在生产部署中,这比手动安装插件更好。
- group_replication_group_name:告诉插件将其加入或创建的组名,可以通过SELECT UUID()用来生成UUID。这个一定不要和服务器的SERVER_UUID相同,否则不能启动组。
- group_replication_start_on_boot:在mysqld启动时不自动启动组复制,等组复制配置完成后,可以设置为on。
- group_replication_local_address:本节点的IP地址和端口,注意该端口是组内成员之间通信的端口,而不是MySQL对外提供服务的端口,应该和业务地址端口分开。
- group_replication_group_seeds:设置组成员的主机名和端口,新成员用来建立其与组的连接。这些成员称为种子成员。建立连接后,组成员身份信息将列在 performance_schema.replication_group_members中。启动组的服务器不使用此选项,因为它是初始服务器,它负责自举引导组。
- group_replication_bootstrap_group:指示插件是否引导组。变量在任何时候都只能在属于某个组的一个服务器实例上启用,通常是在第一次引导该组时(或者在整个组被关闭并再次备份的情况下)。在第一个服务器实例联机后,始终将group_replication_bootstrap_group=off设置为关闭。
5.2 创建用于分布式恢复的复制用户
当加入到组时,组复制使用一个分布式恢复进程来同步组成员,需要传输事务,把一个捐赠者(donor)的二进制日志传输到一个加入成员,使用一个名为group_replication_recovery的复制通道。因此,必须设置具有正确权限的复制用户,以便组复制可以建立直接的成员到成员的复制通道。如果组成员已设置为支持将远程克隆操作用作分布式恢复的一部分,则此复制用户也将用作捐赠者上的克隆用户,并且还需要此角色的正确权限。
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
mysql> create user rpl_user@'%' identified with mysql_native_password by 'Com.123456';
Query OK, 0 rows affected (0.01 sec)
#授权用于复制
mysql> grant replication slave on *.* to 'rpl_user'@'%';
Query OK, 0 rows affected (0.00 sec)
#授权用于在捐赠者上的克隆操作
mysql> grant backup_admin on *.* to 'rpl_user'@'%';
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)
创建用户后,使用CHANGE MASTER TO语句将服务器配置为通过分布式恢复或远程克隆操作,使用给定凭据进行状态传输。
mysql> change master to master_user='rpl_user',
-> master_password='Com.123456' for channel 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.00 sec)
5.3 启动组复制
安装组复制插件。如果在配置文件中设置plugin_load_add=’group_replication.so’配置项,则不用安装;如果您决定手动安装插件,请连接到服务器并发出以下命令:
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 |
+----------------------------+----------+--------------------+----------------------+-------------+
mysql.session用户必须存在,然后才能加载组复制。
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| rpl_user | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
5.4 自举启动组
第一个启动组的过程称为自举引导,你必须使用group_replication_bootstrap_group 系统变量去引导一个组,这个自举应该仅被一个单一的服务器来完成,且仅引导时启动一次。如果在配置文件中此变量设置为ON,这个服务器重启后会自动自举启动另一个相同名字的组,这将导致两个具有相同名称的不同组。
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 (3.35 sec)
mysql> set global group_replication_bootstrap_group=off;
Query OK, 0 rows affected (0.00 sec)
检查组信息及组成员
mysql> mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 823a0adc-3061-11ea-8fc8-000c292bfa3e | master01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
1 row in set (0.00 sec)
为了证明服务器确实在一个组中并且能够处理负载,创建一个表并向其中添加一些内容。
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.03 sec)
mysql> INSERT INTO t1 VALUES (1, 'Luis');
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO t1 VALUES (2, 'Mike');
Query OK, 1 row affected (0.02 sec)
mysql> INSERT INTO t1 VALUES (3, 'John');
Query OK, 1 row affected (0.02 sec)
查看表的内容及二进制日志
mysql> select * from t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | Mike |
| 3 | John |
+----+------+
3 rows in set (0.00 sec)
mysql> show binlog events in 'master01.000005' limit 10;
+-----------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------------------+
| Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
+-----------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------------------+
| master01.000005 | 4 | Format_desc | 101 | 124 | Server ver: 8.0.18, Binlog ver: 4 |
| master01.000005 | 124 | Previous_gtids | 101 | 151 | |
| master01.000005 | 151 | Gtid | 101 | 233 | SET @@SESSION.GTID_NEXT= 'c651b0bc-3098-11ea-be9d-000c292bfa3e:1' |
| master01.000005 | 233 | Query | 101 | 295 | BEGIN |
| master01.000005 | 295 | View_change | 101 | 394 | view_id=15783244827295735:1 |
| master01.000005 | 394 | Query | 101 | 462 | COMMIT |
| master01.000005 | 462 | Gtid | 101 | 542 | SET @@SESSION.GTID_NEXT= 'c651b0bc-3098-11ea-be9d-000c292bfa3e:2' |
| master01.000005 | 542 | Query | 101 | 646 | CREATE DATABASE test /* xid=21 */ |
| master01.000005 | 646 | Gtid | 101 | 726 | SET @@SESSION.GTID_NEXT= 'c651b0bc-3098-11ea-be9d-000c292bfa3e:3' |
| master01.000005 | 726 | Query | 101 | 864 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) /* xid=26 */ |
+-----------------+-----+----------------+-----------+-------------+---------------------------------------------------------------------------------+
10 rows in set (0.00 sec)
5.6 添加第二台服务器
修改主配置文件
[root@slave01 ~]# vim /etc/my.cnf
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
# Replication configuration parameters
#
server_id=102
log_bin=/var/lib/mysql/binlogs/slave01
log_bin_index=/var/lib/mysql/binlogs/slave01.index
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
# Group Replication configuration
#
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
group_replication_group_name="c651b0bc-3098-11ea-be9d-000c292bfa3e"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.154.102:33061"
group_replication_group_seeds= "192.168.154.101:33061,192.168.154.102:33061,192.168.154.103:33061"
group_replication_bootstrap_group=off
创建复制用户:
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER rpl_user@'%' IDENTIFIED with mysql_native_password BY 'Com.123456';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT BACKUP_ADMIN ON *.* TO rpl_user@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> SET SQL_LOG_BIN=1;
Query OK, 0 rows affected (0.00 sec)
mysql> CHANGE MASTER TO MASTER_USER='rpl_user',
-> MASTER_PASSWORD='Com.123456' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)
启动组复制,将slave01加入组
mysql> start group_replication;
Query OK, 0 rows affected (4.39 sec)
mysql> select * from performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 823a0adc-3061-11ea-8fc8-000c292bfa3e | master01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
| group_replication_applier | 9162c999-3061-11ea-8e82-000c29ede891 | slave01 | 3306 | ONLINE | SECONDARY | 8.0.18 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
2 rows in set (0.00 sec)
查看数据同步结果:
mysql> show databases like 'test';
+-----------------+
| Database (test) |
+-----------------+
| test |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from test.t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | Mike |
| 3 | John |
+----+------+
3 rows in set (0.00 sec)
5.7 添加第三台服务器
修改主配置文件
# Disable other storage engines
# #
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
#
# # Replication configuration parameters
# #
server_id=103
log_bin=/var/lib/mysql/binlogs/slave02
log_bin_index=/var/lib/mysql/binlogs/slave02.index
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE
# Group Replication configuration
#
plugin_load_add='group_replication.so'
transaction_write_set_extraction=XXHASH64
group_replication_group_name="c651b0bc-3098-11ea-be9d-000c292bfa3e"
group_replication_start_on_boot=off
group_replication_local_address= "192.168.154.103:33061"
group_replication_group_seeds= "192.168.154.101:33061,192.168.154.102:33061,192.168.154.103:33061"
group_replication_bootstrap_group=off
创建复制用户
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.00 sec)
mysql> create user 'rpl_user'@'%' identified with mysql_native_password by 'Com.123456';
Query OK, 0 rows affected (0.02 sec)
mysql> grant replication slave on *.* to 'rpl_user'@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> grant backup_admin on *.* to 'rpl_user'@'%';
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='rpl_user',
-> master_password='Com.123456' for channel 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.02 sec)
启动组复制,将slave02加入组
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 823a0adc-3061-11ea-8fc8-000c292bfa3e | master01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
| group_replication_applier | 9162c999-3061-11ea-8e82-000c29ede891 | slave01 | 3306 | ONLINE | SECONDARY | 8.0.18 |
| group_replication_applier | a40dccf8-3061-11ea-aaec-000c295f003c | slave02 | 3306 | ONLINE | SECONDARY | 8.0.18 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)
查看数据同步结果:
mysql> show databases like 'test';
+-----------------+
| Database (test) |
+-----------------+
| test |
+-----------------+
1 row in set (0.00 sec)
mysql> select * from test.t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | Luis |
| 2 | Mike |
| 3 | John |
+----+------+
3 rows in set (0.00 sec)
5.8 测试
停止master01上的mysqld.service服务
[root@master01 ~]# systemctl stop mysqld.service
在slave01上进行查看组情况:
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 9162c999-3061-11ea-8e82-000c29ede891 | slave01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
| group_replication_applier | a40dccf8-3061-11ea-aaec-000c295f003c | slave02 | 3306 | ONLINE | SECONDARY | 8.0.18 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
2 rows in set (0.00 sec)
可以看到主库已经进行切换,切换到了slave01主机上。
实验中防火墙要放行的端口:
tcp 33060,tcp 33061, tcp 3306
5.9 监控组复制
组复制创建如下复制通道:
group_replication_recovery: 此通道用于与分布式恢复阶段相关的复制更改
group_replication_applier :此通道用于来自组的传入更改。这是用于应用直接来自组的事务的通道
组复制添加如下表:
#提供了与认证过程相关的组级别信息,还提供了复制组的每个单独成员接收和发起的事务的统计信息
performance_schema.replication_group_member_stats
#用于监视属于该组成员的不同服务器实例的状态:
performance_schema.replication_group_members
另外,这些表也可以显示复制组情况:
#显示有关组复制的信息,例如已从组接收并在申请者队列(中继日志)中排队的事务。
performance_schema.replication_connection_status
#显示与组复制相关的通道和线程的状态。
#如果有许多不同的工作线程在应用事务,那么工作表也可以用来监视每个工作线程在做什么
performance_schema.replication_applier_status
5.10 组复制服务状态
区域 | 描述 | 组同步 |
---|---|---|
ONLINE | 成员已经是全功能的组成员 | YES |
RECOVERING | 该成员正在成为该组的活跃成员,并且正在接受恢复过程,正在接受捐赠者的状态转移。 | NO |
OFFLINE | 组复制插件已经加载,但其不属于任何组的成员 | NO |
ERROR | 该成员处于错误状态,不能作为组成员正常运行。 | YES |
UNREACHABLE | 当本地故障检测器怀疑某个给定的服务器不可访问时(例如,它是非自愿断开连接的), 它会将该服务器的状态显示为不可访问 | YES |
六、配置MGR多主模式
在单主模式的基础上做以下配置:
6.1 修改所有服务器的配置文件
添加如下配置:
# 所有节点均要添加
[root@master01 ~]# vim /etc/my.cnf
# Group Replication Multi-Primary Mode
group_replication_single_primary_mode=OFF
group_replication_enforce_update_everywhere_checks=ON
#重启MySQL服务
[root@master01 ~]# systemctl restart mysqld.service
6.2 启动复制组
选择任意一个节点即可
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 (3.10 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 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 823a0adc-3061-11ea-8fc8-000c292bfa3e | master01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
1 row in set (0.01 sec)
6.3 其它节点加入复制组
mysql> start group_replication;
Query OK, 0 rows affected (4.10 sec)
6.4 查看复制组情况
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
| group_replication_applier | 823a0adc-3061-11ea-8fc8-000c292bfa3e | master01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
| group_replication_applier | 9162c999-3061-11ea-8e82-000c29ede891 | slave01 | 3306 | ONLINE | PRIMARY | 8.0.18 |
| group_replication_applier | a40dccf8-3061-11ea-aaec-000c295f003c | slave02 | 3306 | ONLINE | PRIMARY | 8.0.18 |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+
3 rows in set (0.00 sec)
总结MGR特点如下:
- 高一致性:基于分布式paxos协议实现组复制,保证数据一致性;
- 高容错性:自动检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制;
- 高扩展性:节点的增加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,直到与其他节点数据一致;
- 高灵活性:提供单主模式和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。