mysql group replication,组复制,提供了多写(multi-master update)的特性,增强了原有的mysql的高可用架构。mysql group replication基于mysql插件架构实现,本身就是一个mysql插件。

提供的特性:

  • 多写,写冲突检测
  • 良好的扩展能力,可动态增删节点,组成员自动管理
  • 组内高可用
  • 确保组内数据最终一致性【重要】(通过分布式协议和分布式recovery机制保证)

1. 架构

组复制基于mysql插件架构实现,本身作为一个mysql插件而存在。如上图所示,蓝色和绿色两部分表示组复制架构。

组复制依赖mysql server主模块(上图灰色部分)以及mysql的复制架构,包括binary log caches、binary log applier模块、GTID、relay log模块、replication applier threads(组复制distributed recovery第一个阶段会使用这些线程)和performance_schema(用于存储监控组复制的状态信息)。

上图架构中各个模块的作用简单介绍如下:

  • APIs

API层提供了组复制与上层mysql server交互的接口。上层(mysql server)会主动通知下层(组复制)根据它的状态去做对应的动作,包括server的启动、恢复、接受连接、提交事务等等。组复制根据这些接口调用做出对应的响应动作。

  • Capture、Applier、Recovery

组复制中的三个核心模块,当上层API发生调用,将根据调用类型路由到下面这三个模块执行相应的逻辑。Capture模块负责追踪事务执行的上下文信息;Applier模块负责将远程事务加载到本地执行;Recovery模块管理组内节点的recovery。

  • Replication Protocol Logics

Replicaiton Protocol Logics模块实现了replication协议的逻辑,逻辑功能包括: 处理冲突检测、接收并传播事务到组内去执行。

  • Group Communication System API

提供状态机(Replication State Machine)的高层抽象API,以此分离与下层协议实现的逻辑。

  • Group Communication Engine

根据上层的状态机API的抽象,这一层主要提供Paxos协议变种的核心实现。

2. Group

一个Group由若干个mysql节点组成,每个Group有自己的唯一命名来标识,格式为UUID。Group内的mysql节点数据保持一致。一个组可以动态增加和删除节点。

组成员管理自动化。新增一个节点到一个组里面,这个节点会自动同步自身数据跟组内其他节点保持一致。保持同步会利用Asynchronous MySQL replication。当一个节点从一个组里移除,将自动更改group的配置,以让其他节点知道这个节点的移除。

3. Multi Primary

组复制有两种运行模式: (1) Single-Primary Mode 和 (2) Multi-Primary Mode,其中Single-Primary Mode表示一个组里面只有一个节点用于写,而Multi-Primary Mode下组内所有节点都可以参与写,事务的提交可以在组内的任意一个节点进行。

看起来Multi-Primary模式好像很屌!但是,这个模式下目前存在挺多的使用限制:

3.1 并发写冲突

Multi-Primary模式下,对于事务的提交,需要组内所有节点进行通讯,共同决定事务是否可以提交。高并发模式下有可能出现分布式提交冲突——不同的节点并发提交的事务操作了同一行数据。group replication提供的乐观的解决方案是——先提交(时间序靠前的)的事务,能够正确被提交,而后面提交的事务,将会失败。

官方建议,避免并发写冲突的最好的做法是将这些会产生冲突的写事务放到同一个节点上进行提交。

3.2 并发DDL

MySQL目前不支持事务类型的DDL,也就是说DDL操作不是一个原子操作,在Multi-Primary模式下,DDL操作并发地在多个节点执行,很有可能产生数据不一致的情况。因此,官方提醒,在Multi-Primary下DDL操作最好在同一个节点上执行。

如果运行在Single-Primary模式下,就没有上面所提到的限制了。

4. Distributed Recovery

当一个新节点(被叫作joiner)加入一个group,需要从group里面其他节点同步状态。这个新节点从其他节点获取这些落后数据,并接受新提交的事务,最终保持与group内其他节点数据一致的这个过程,称为distributed recovery(DR)。DR过程分为两个阶段:

4.1 阶段1

Joiner选择group里面的一个节点作为复制源(这个节点被称作donor),基于原有的异步复制技术进行recovery。这个过程会建立从donor到joiner的replication channel,joiner不断接收从donor端发送的binary log,apply到自身。于此同时,joiner还会监听并缓存group里面自从它加入以来产生的新事务。阶段1结束后,将会关闭之前建立在donor和joiner之间的replication channel。

donor有可能在这个阶段挂掉,此时joiner将自动选择集群内的其他一个存活节点作为donor,继续之前的recovery。这个过程无需人为干预。

4.2 阶段2

阶段2,joiner执行在阶段1缓存队列里的新事务(直到缓存队列为空),然后将joiner的状态标记为online,表示这个节点的数据已经跟其他节点保持一致,可以被正常访问。

只有online的节点才能正常接收用户请求。

4.3 Recovering From a Point-in-time

这里有个问题: 在阶段1,joiner怎么知道它在什么时候会完成所有缺失数据的recovery,单单依靠GTID机制是不够的(依靠GTID机制只能让joiner知道它是否少了这部分数据)。这个时候,需要有另外一个机制,来代表一个时间点——这个时间点能够标识阶段1的结束,也就是说在这个时间点上,joiner已经完成了从donor上所有缺失数据的recovery,接下来可以进入阶段2了。

这个机制,就是binary log view change markers,在阶段1传输binary log流中,会带上view change markers。那么joiner在接受到binary log的时候,就可以利用这些标识来判断那个时间点的到来。

4.4 View and View Changes

在解释view change markers之前,需要介绍view change markers关联的概念: ViewView Changes

  • View

一个Group里面所有节点在某个时间点上达成的配置,对外表示为一个View。

  • View Changes

View Changes指引起Group配置发生变化的事件,比如新增节点,删除节点。

每个View有一个唯一标识(View Identifier)进行标识。当发生View Changes时,就会生成这样一个唯一标识来表示这个新的View。

View changes产生的view ids作为新节点与donor同步数据的临界点。View change事件对应到binary log里面是一个新binary log event的实现——view change log event。在这个view change log event里面携带了view id。

假设在之前的multi-primary部署示例完成后,我们通过登陆S2执行以下语句检索到view change event log:

mysql > show binlog events\G;

可以看到如下view change event log:

*************************** 9. row ***************************
Log_name: binlog.000001
Pos: 742
Event_type: View_change
Server_id: 1
End_log_pos: 881
Info: view_id=14817781596395401:1

4.5 Distributed Recovery Example

接下来我们分析一个例子: 一个新节点加入一个group的过程

4.5.1 Begin: Stable Group

一开始group有3个节点S1、S2、S3,整个group处于稳定状态

4.5.2 View Change: Member Joins

接下来新节点S4准备加入group,引起view changes(VC4)。所有的节点都会在缓存队列里面缓存view change event log到队列。同时,新节点S4会选择group里面的某个节点作为donor。

所有的节点都要缓存view change event log到队列,因为这个event log之前有可能还存在着未apply的event log,这些event log是属于old view的。

4.5.3 State Transfer: Catching Up

当S4选择好donor后,就会建立与donor的replication channel,基于async replication机制从donor上同步状态进行recovery,直到S4遇到期望的view change marker为止。

于此同时,S4也会不断地接受group里面下发的新提交事务,缓存到队列里面。

4.5.4 Finish: Caught Up

当S4遇到期望的view change marker(根据view change event log 判断)以后,与donor之间的replication channel将会被关闭,这个时候,就会从之前的缓存队列里面取新的事务(图示中的T22)进行apply,直到缓存队列为空,然后就可以将S4的状态标记为online,这就是阶段2的主要动作。

注意,阶段2的执行周期是不确定的,取决于系统的负载情况,因为在阶段2期间,有可能系统不断产生新的事务。系统的负载越高,产生的事务会越多,那么阶段2经历的时间自然也就越长了。

0
 

MySQL Group Replication 技术点的更多相关文章

  1. Mysql 5.7 基于组复制(MySQL Group Replication) - 运维小结

    之前介绍了Mysq主从同步的异步复制(默认模式).半同步复制.基于GTID复制.基于组提交和并行复制 (解决同步延迟),下面简单说下Mysql基于组复制(MySQL Group Replication ...

  2. MySQL group replication介绍

    “MySQL group replication” group replication是MySQL官方开发的一个开源插件,是实现MySQL高可用集群的一个工具.第一个GA版本正式发布于MySQL5.7 ...

  3. mysql group replication观点及实践

    一:个人看法 Mysql  Group Replication  随着5.7发布3年了.作为技术爱好者.mgr 是继 oracle database rac 之后. 又一个“真正” 的群集,怎么做到“ ...

  4. MySQL Group Replication配置

    MySQL Group Replication简述 MySQL 组复制实现了基于复制协议的多主更新(单主模式). 复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事 ...

  5. mysql group replication 安装&配置详解

    一.原起: 之前也有写过mysql-group-replication (mgr) 相关的文章.那时也没有什么特别的动力要写好它.主要是因为在 mysql-5.7.20 之前的版本的mgr都有着各种各 ...

  6. MySQL Group Replication 动态添加成员节点

    前提: MySQL GR 3节点(node1.node2.node3)部署成功,模式定为多主模式,单主模式也是一样的处理. 在线修改已有GR节点配置 分别登陆node1.node2.node3,执行以 ...

  7. Docker Images for MySQL Group Replication 5.7.14

    In this post, I will point you to Docker images for MySQL Group Replication testing. There is a new ...

  8. Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication

    Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication Overview Galera Cluster 由 Coders ...

  9. mysql group replication 主节点宕机恢复

    一.mysql group replication 生来就要面对两个问题: 一.主节点宕机如何恢复. 二.多数节点离线的情况下.余下节点如何继续承载业务. 在这里我们只讨论第一个问题.也就是说当主结点 ...

随机推荐

  1. Autofac - 装配

    从容器中的可用服务中, 选取一个构造函数来创造对象, 这个过程就是自动装配. 一.选择构造函数 默认情况下, autofac会使用无参构造函数, 去创建对象. 我将Person类稍微修改了下. pub ...

  2. C语言中结构体的位域(bit-fields)

    转自:http://blog.sina.com.cn/s/blog_6240b5980100tcba.html 有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位.例如在存放一 ...

  3. 记录路径dp-4713-Permutation

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4713 题目大意: 题意同HDU 3092这不过这题要输出路径. 解题思路: 思路同HDU 3092. ...

  4. PHP文本路径转换为链接文字

    <?php /** * 文本路径转换为有链接的文字 * @param string $str 转换内容 * @return string */ function urlToLink($str) ...

  5. python之time模块

    from time import * ''' class struct_time(tuple): pass ''' tuple1 = (, , , , , , , , ) s = struct_tim ...

  6. Vue中ajax返回的结果赋值

    这是第二次在项目中遇到此问题,ajax请求成功后在success函数中为Vue实例data里的变量赋值,却失败了 new Vue({ el:'#app', data:{ msg:'' }, creat ...

  7. 【代码笔记】Web-Javascript-javascript break和continue语句

    一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. Linux中对逻辑卷的移除

    移除前先df -mT 看一下:(在上一篇的基础上:Linux中对逻辑卷进行扩容) 1.取消挂载同时删除/etc/fstab下的记录 取消挂载 umount /dev/zhi/lv-zhi 删除记录 v ...

  9. [2017BUAA软工]第零次博客作业

    第一部分:结缘计算机 1. 你为什么选择计算机专业?你认为你的条件如何?和这些博主比呢?(必答) 当年高考前在专业这件事上纠结了好久,因为我对于大学各个专业具体学什么都不甚了解,于是就迟迟没有明确的目 ...

  10. Java常用的非受检异常

    IllegalArgumentException 非 null 的参数值不正确 IllegalStateException 对于方法调用而言,对象状态不合适 NullPointException 参数 ...