mysql 5.7实现组复制 (MGR)

一.原理赘述

 

1.组复制插件架构图

MySQL组复制是一个MySQL插件,它基于常规的MySQL复制,利用了基于行格式的二进制日志和GTID等特性。下图是MySQL组复制的整体框架图。


 1.从上图的最顶端开始,有一系列的API控制组复制插件如何和MySQL Server进行交互(图中灰色方框)。
 2.中间有一些接口可以使信息从MySQL Server流向组复制插件,反之亦然。这些接口将MySQL Server核心部分和插件隔离开来。在Server到插件的方向上,传递一些通知信息,例如server正在启动,server正在恢复,server已准备好接收连接,server将要提交事务等等。另一方向,即插件到server的方向上,插件会通知server对事务进行提交,终止正在进行的事务,将事务放进relay-log中排队等等。
 3.从API往下是一些响应组件,当通知信息路由到它们身上时就响应。capture组件负责跟踪正在执行的事务的上下文信息。applier组件负责在本节点上执行远程传输来的事务。recovery组件负责管理分布式恢复过程,还负责在节点加入组时选择donor,编排追赶过程以及对选择donor失败时的反应。
 4.继续向下,replication协议模块包含了特定的复制协议逻辑。它负责探测冲突,在组中接收和传播事务。
 5.最后两层是组内通信系统(GCS)的API(第一个绿色方框),以及一个基于Paxos组通信引擎的实现(implementation)(第二个绿色方框)。
 6.GCS API是组内通信API,它是一个上层API,它抽象了构建一个复制状态机所需的属性,它从插件的更上层解耦了消息传递层。
 7.组通信引擎负责处理组内成员的通信。

2.组复制原理:

组复制是一种可用于实现容错系统的技术。 复制组是一个通过消息传递相互交互的 server 集群。通信层提供了原子消息(atomic message)和完全有序信息交互等保障机制
实现了基于复制协议的多主更新
复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事务。但所有读写(RW)事务只有在冲突检测成功后才会提交。只读(RO)事务不需要在冲突检测,可以立即提交。句话说,对于任何 RW 事务,提交操作并不是由始发 server 单向决定的,而是由组来决定是否提交。准确地说,在始发 server 上,当事务准备好提交时,该 server 会广播写入值(已改变的行)和对应的写入集(已更新的行的唯一标识符)。然后会为该事务建立一个全局的顺序。最终,这意味着所有 server 成员以相同的顺序接收同一组事务。因此,所有 server 成员以相同的顺序应用相同的更改,以确保组内一致。

3.mysql组复制协议:

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


4.故障检测:

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

 

5.MGR的限制:

仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;
必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set
COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景
目前一个MGR集群最多支持9个节点
不支持外键于save point特性,无法做全局间的约束检测与部分部分回滚
二进制日志不支持binlog event checksum

二:实验;

准备:三台虚拟机,模拟为三个节点

节点一:server4:172.25.17.4

节点二:server2:172.25.17.2

节点三:server1:172.25.17.1

三台主机安装mysql5.7,并且先别开启mysqld,

扫描二维码关注公众号,回复: 5736278 查看本文章

如果开启mysqld,

先关闭

cd /var/lib/mysql    rm -fr *
 

1.三个节点编辑配置文件

vim /etc/my.cnf

添加:
1.server_id=1    #三台主机的id号不同
2.gtid_mode=ON
3.enforce_gtid_consistency=ON
4.master_info_repository=TABLE
5.relay_log_info_repository=TABLE
6.binlog_checksum=NONE
7.log_slave_updates=ON
8.log_bin=binlog
9.binlog_format=ROW

10.transaction_write_set_extraction=XXHASH64  #指示Server必须为每个事务收集写集合,并使用XXHASH64哈希算法将其编码为散列
11.loose-group_replication_group_name="8053c671-0622-11e8-a300-525400b9c5e8"        #表示将加入或者创建的复制组命名为uuid----[查找uuid的命令;uuidgen]
12.loose-group_replication_start_on_boot=off  #设置为Server启动时不自动启动组复制
13.loose-group_replication_local_address= "172.25.17.4:24901"                #绑定本地的172.25.92.1以及25901端口接受其他组成员的连接,IP地址必须为其他组成员可正常访问
14.loose-group_replication_group_seeds="172.25.17.4:24901,172.25.17.2:24901,172.25.17.1:24901"          #本行为告诉服务器当服务器加入组时,应当连接到172.25.17.4:24901,172.25.17.2:24901,172.25.17.1:24901这些种子服务器进行配置。本设置可以不是全部的组成员服务地址
15.loose-group_replication_bootstrap_group= off   #配置是否自动引导组
16.loose-group_replication_single_primary_mode=OFF  #设置组自动选择一个 server 来处理读/写工作。 这个 server 是主(PRIMARY),所有其他的都是从
17.loose-group_replication_enforce_update_everywhere_checks=FALSE  #多主模式下为多主更新启用或禁用严格一致性检查。
18.loose-group_replication_ip_whitelist="172.25.17.0/24"   #开启白名单,认情况下只允许白名单连接到复制组,如果是其他IP则需要配置。

#使用的loose-前缀是指示Server启用时尚未加载复制插件也将继续启动

   

【注:查找uuid

[root@server2 ~]# cd /var/lib/mysql
[root@server2 mysql]# uuidgen
8053c671-0622-11e8-a300-525400b9c5e8】

节点一;

过滤出原始密码:
grep password /var/log/mysqld.log

mysql -p
修改密码:
mysql> ALTER USER root@localhost identified by 'Westos-6';
Query OK, 0 rows affected (0.07 sec)   #创建用户新密码


SET SQL_LOG_BIN=0;

8.
CREATE USER rpl_user@'%' IDENTIFIED BY 'Westos-6';

9.
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';

10.
  FLUSH PRIVILEGES;

11.
 SET SQL_LOG_BIN=1;



12.
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Westos-6' FOR CHANNEL 'group_replication_recovery';

13.
INSTALL PLUGIN group_replication SONAME 'group_replication.so'; #安装插件


14.
SET GLOBAL group_replication_bootstrap_group=ON;

15.
START GROUP_REPLICATION;



16.
SELECT * FROM performance_schema.replication_group_members;

17.
CREATE DATABASE test;

18.
USE test;

19.
 CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);

20.
INSERT INTO t1 VALUES (1, 'Luis');

21.
SELECT * FROM t1;

节点二:

grep password /var/log/mysqld.log 
2019-02-24T08:55:47.650391Z 1 [Note] A temporary password is generated for root@localhost: p1-=gjGiydXu

4.
 mysql -p
Enter password: 

5.
mysql> ALTER USER root@localhost identified by 'Westos-6';
Query OK, 0 rows affected (0.08 sec)
6.
mysql> SET SQL_LOG_BIN=0;
Query OK, 0 rows affected (0.00 sec)

7.
mysql> CREATE USER rpl_user@'%' IDENTIFIED BY 'Westos-6';
Query OK, 0 rows affected (0.00 sec)

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

9.
mysql>  FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

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

11.
mysql> CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Westos-6' FOR CHANNEL 'group_replication_recovery';
Query OK, 0 rows affected, 2 warnings (0.51 sec)


12.
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';
Query OK, 0 rows affected (0.28 sec)

13.
mysql> STOP GROUP_REPLICATION;
Query OK, 0 rows affected (0.00 sec)

14。
mysql> reset master;
Query OK, 0 rows affected (0.23 sec)

15.
mysql> START GROUP_REPLICATION;
Query OK, 0 rows affected (7.51 sec)

16.
use test;


17.
select * from t1;

两个节点成功开启的标志:

节点一执行此命令,会出现两个online;

节点三:
 

grep password /var/log/mysqld.log 
2019-02-24T08:55:47.650391Z 1 [Note] A temporary password is generated for root@localhost: p1-=gjGiydXu

4.
 mysql -p
Enter password: 

5.
ALTER USER root@localhost identified by 'Westos-6';


6.
SET SQL_LOG_BIN=0;


7.
CREATE USER rpl_user@'%' IDENTIFIED BY 'Westos-6';

8.
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';


9.
FLUSH PRIVILEGES;

10.
SET SQL_LOG_BIN=1;

11.
CHANGE MASTER TO MASTER_USER='rpl_user', MASTER_PASSWORD='Westos-6' 
FOR CHANNEL 'group_replication_recovery';


12.
INSTALL PLUGIN group_replication SONAME 'group_replication.so';


13.
reset master;


14.
START GROUP_REPLICATION;

15.
use test;

select * from t1;


insert into t1 values (2,'we');

测试:


select * from t1;


#server4:
use test

select * from t1;

insert into t1 values (3,'westos');

互相可见添加的value 值

猜你喜欢

转载自blog.csdn.net/xys2333/article/details/87915582