MySQL 8 复制(七)——组复制基本原理

目录

一、MySQL复制技术

1. 主从复制       

2. 组复制

二、组复制使用场景

三、组复制相关服务

1. 故障检测

2. 组成员服务

3. 容错

四、组复制技术细节

1. 组复制插件体系结构

2. 复制组

3. 数据操作语言(Data Manipulation Language,DML)

4. 数据定义语句(Data Definition Language,DDL )

5. 分布式恢复


        MySQL Group Replication(MGR)是MySQL 5.7.17版本引入的一个服务器插件,可用于创建高可用、可扩展、容错的复制拓扑结构。组复制可以在单主模式下操作,其中只有一个服务器接受更新,这个单主是系统自动选举出来的。对于高级用户,也可以部署为多主模式,其中所有服务器都可以接受更新。内置的组成员服务可以在任何给定的时间点保持组的视图一致并可供所有服务器使用。当服务器加入或离开组时,视图也会相应更新。当服务器宕机,故障检测机制会检测到此情况并通知组其视图已更改。这些都是自动进行的。

        创建容错系统最常见的方法是组件冗余。换句话说,一个组件被移除时,系统应该继续按预期运行。这产生了一系列挑战,将这种系统的复杂性提高到了一个完全不同的水平。数据复制必须维护和管理多个服务器,还必须处理若干其它经典的分布式系统问题,如网络分区或脑裂。对MySQL而言,最终的挑战是将数据复制逻辑与协调多个服务器的逻辑相融合。这可以概括为让每个服务器的状态在数据变化时达成一致,即便它们都作为单个数据库系统运行,但最终都收敛到相同的状态。

        MGR对属于同一组的服务器自动进行协调。对于要提交的事务,组成员必须就全局事务序列中给定事务的顺序达成一致。提交或回滚事务由每个服务器单独完成,但所有服务器都必须做出相同的决定。如果存在网络分区,导致成员无法达成事先定义的分割策略,则在解决此问题之前系统不会继续进行,这是一种内置的自动裂脑保护机制。MGR由组通信系统(Group Communication System,GCS)协议支持。该系统提供故障检测机制、组成员服务以及安全且有序的消息传递。所有这些属性都是创建系统的关键,可确保在服务器组中一致地复制数据。该技术的核心是Paxos算法的实现,它充当组通信引擎。

一、MySQL复制技术

        在深入了解MySQL组复制的细节之前,先介绍一些其产生的背景以及工作原理,以帮助理解组复制,以及传统异步复制、半同步复制和组复制之间的区别。

1. 主从复制
       

        传统的MySQL复制提供了一种简单的主从复制方法。有一个主库,一个或多个从库。主库执行并提交事务,然后通过二进制日志将事务相关的事件异步发送到从库,以便重放。这是一个无共享系统,默认情况下所有服务器都拥有完整的数据副本。

MySQL 8 复制(七)——组复制基本原理_第1张图片 图1 异步复制

        半同步复制为异步复制协议添加了一个同步步骤。这意味着主库在提交时等待至少一个从库确认它已收到该事务,才会继续提交操作。

MySQL 8 复制(七)——组复制基本原理_第2张图片 图2 半同步复制

        图1图2分别表示MySQL异步复制协议以及它的半同步变体。对角箭头表示服务器之间交换的消息或服务器与客户端应用程序之间交换的消息。

2. 组复制

        组由多个服务器构成,通过传递消息进行交互,通信层保证原子消息传递。MGR构建于此通信层抽象之上,并实现了多主更新复制协议。组中的每个服务器独立地执行事务,但是所有读写事务只有在得到组的批准后才会提交。只读事务在组内不需要协调,因此立即提交。对于任何读写事务,当事务准备好在始发服务器处提交时,服务器以原子方式广播写入值(更改的行)和对应的写入集(更新的行的唯一标识符),然后将该事务加入全局事务列表。最终所有服务器都以相同的顺序接收并应用相同的事务集,所以它们在组内保持一致。

        不同服务器上并发执行的事务之间可能存在冲突。MGR在certify过程中检查并发事务的写集来检测这种冲突。如果在不同服务器上执行的两个并发事务更新同一行,则存在冲突。解决方案是先到事务提交,后到事务回滚,即按顺序第一个事务在所有服务器提交,而第二个事务在在原始服务器上回滚并在组中的其它服务器中删除。这实际上体现的是多主分布式事务的首个提交获胜原则。

MySQL 8 复制(七)——组复制基本原理_第3张图片 图3 MGR协议

        图3描述了MGR协议。组复制同样是一种无共享复制方案,其中每个服务器都有自己的整个数据副本。

二、组复制使用场景

        组复制可用来创建具有冗余的容错系统。即使某些服务器发生故障,只要它不是全部或大多数,系统仍然可用。根据失败的服务器数量,可能会降低性能或可伸缩性,但它仍然可用。组成员服务跟踪服务器故障,该服务依赖于分布式故障检测器,能够在任何服务器脱离组时发出信号,无论是意外停止还是主动停止。分布式恢复过程确保当服务器加入组时能自动更新。单个服务器发生故障时不会停止服务,也无需服务器故障转移。总之,MGR保证数据库服务持续可用。

        需要注意,尽管数据库服务可用,但在服务器崩溃的情况下,必须将连接到它的客户端重定向或转移到其它服务器。组复制不解决数据库连接重定向的问题,连接器、负载平衡器、路由器或某种形式的中间件更适合处理此问题,例如MySQL Router。

        以下是组复制的典型使用场景。

  • 弹性复制:服务器的数量能够动态增加或减少,并且尽可能减小副作用,例如云数据库服务。
  • 高可用分片:分片是实现写扩展的流行方法。使用MGR实现高可用分片,其中每个分片映射到复制组。
  • 主从复制的替代方案:在某些情况下,使用单个主服务器会使其成为热点,写入整个组会更具可扩展性。

三、组复制相关服务

1. 故障检测

        组复制包括一种故障检测机制,该机制能够查找并报告哪些服务器已经宕机。当服务器A在给定时间内没有从服务器B接收到消息时,发生超时并引发怀疑。然后如果组同意怀疑是真的,那么该组决定给定服务器确实宕机了。这意味着该组中的其余成员将采取协调决策以排除给定成员。

        如果一个服务器与组的其余部分隔离,它会怀疑所有其它服务器都已失败,但由于无法与该组达成协议(因为无法确保法定票数),其怀疑并没有结果。当服务器以这种方式与组隔离时,它无法执行任何本地事务。

2. 组成员服务

        MGR依赖于组成员服务,该服务内置于插件中。它定义了哪些服务器在线并参与该组。在线服务器列表通常称为视图。因此,组中的每个服务器都具有一致的视图,其中是在给定时刻主动参与该组的成员。

        服务器不仅必须同意事务提交,还​​要同意当前视图。因此,如果服务器同意新服务器成为组的一部分,则组本身将重新配置为将该服务器集成在其中,从而触发视图更改。相反的情况也会发生,如果服务器离开组,则组会动态更新配置并触发视图更改。

        组成员离开组分主动与被动。主动离开会启动组的动态重新配置,这会触发所有其它成员必须在没有该服务器的情况下就新视图达成一致。被动离开(如已意外停止或断网)时,故障检测机制会建议重新配置组,这需要组中大多数服务器的同意。如果该组无法达成协议,为阻止脑裂,系统无法动态更改配置,这意味着管理员需要介入解决此问题。

3. 容错

        MGR构建于Paxos分布式算法的实现之上,需要多数服务器处于活动状态才能达到法定票数,从而做出决定。这直接影响系统可以容忍的故障机数量,但不会影响组复制自身及其整体功能。容忍 f 个故障机所需的服务器数量 n 为:n = 2 * f + 1。

        实践中为了容忍一个故障机,该组必须具有三个服务器,因为此时如果一个服务器发生故障,仍然有两个服务器构成多数,并允许系统继续自动做出决策并继续提供服务。但如果第二个服务器继续失败,那么该组(剩下一个服务器)会阻塞,因为没有多数票可以做出决定。

四、组复制技术细节

1. 组复制插件体系结构

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

MySQL 8 复制(七)——组复制基本原理_第4张图片 图4 MGR插件架构

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

        组复制插件体系结构的下一层是一组组件。捕获组件负责跟踪与正在执行的事务相关的上下文。应用组件负责在数据库上执行远程事务。恢复组件管理分布式恢复,负责选择捐赠者,对故障做出反应,执行追赶程序,使加入该组的服务器获得更新。

        堆栈下一层的复制协议模块包含复制协议的特定逻辑。它处理冲突检测,接收事务并将其传播到组。

        组复制插件体系结构的最后两层是组通信系统(GCS)API,以及基于Paxos的组通信引擎(XCom)的实现。GCS API将消息传递层的实现与插件上层分离,组通信引擎处理与复制组成员的通信。

2. 复制组

        MGR中的一组服务器构成一个复制组,组名形式为UUID。组是动态的,服务器可以离开(主动或被动)并随时加入组。服务器加入或离开时,组会自行调整。如果服务器加入组,组会通过从现有服务器获取状态自动更新新加入的服务器。状态通过MySQL异步复制进行传输。如果服务器离开该组,其余服务器会知道它已离开并自动重新配置该组。

3. 数据操作语言(Data Manipulation Language,DML)

        组中的每个服务器都被允许随时执行读写事务。任何服务器都可以在没有任何事先协调的情况下执行事务。但在提交时,它与组中的其余服务器协调,以便就该事务的操作做出决定。这种协调有两个目的:一是检查事务是否可以提交;二是传播更新,以便其它服务器也可以应用该事务。

        当事务通过原子广播发送时,组中的所有服务器都接收该事务,或者都不接收该事务。它们会以与之前发送的其它事务相同的顺序收到它,并通过检查和比较写入事务集来执行冲突检测。冲突解决遵循首个提交者获胜规则。例如,事务t1和t2在不同的站点同时执行,t2排在t1之前,并且两者都改变​​了同一行,那么t2赢得冲突被执行,t1被中止。如果两个事务经常发生冲突,最好在同一台服务器上启动它们,这样它们有机会在本地锁管理机制下并行执行,而不是稍后在复制协议中中止。

4. 数据定义语句(Data Definition Language,DDL )

        在组复制拓扑中,执行数据定义语句时需要小心。MySQL 8.0 引入了对原子数据定义语言的支持,其中完整的DDL语句作为单个原子事务提交或回滚。但是,原子或其它DDL语句隐式结束当前会话中处于活动状态的任何事务,就好像在执行语句之前已完成COMMIT一样。这意味着DDL语句自成事务,不能在另一个事务中,或在START TRANSACTION ... COMMIT等事务控制语句中,或者与同一事务中的其它语句结合使用。

        组复制基于乐观复制,其中语句被乐观执行(执行时不事先锁定对象)并在稍后必要时回滚。每个服务器首先执行和提交而不保护组协议。因此,在多主模式下复制DDL语句时需要更加小心。如果对同一对象进行结构更改(使用DDL)并更改对象包含的数据(使用DML),则需要通过同一服务器处理更改。如果不这样做,可能会因操作中断或部分完成,导致数据不一致。如果组以单主模式部署,则不会发生此问题,因为所有更改都是通过同一服务器(主服务器)执行的。

5. 分布式恢复

(1)分布式恢复基础
        组复制分布式恢复可以概括为服务器从组中获得丢失事务的过程,以便它可以加入具有已处理相同事务集成员的组。在分布式恢复期间,加入组的服务器会缓冲其正在接收的,组中所需的事务和成员事件。一旦加入该组的服务器收到了该组的所有事务,它就会应用在恢复过程中缓冲的事务。此过程结束时,服务器随之作为在线成员加入组。

        分布式恢复分为两个阶段。第一阶段,加入该组的服务器选择该组上的一个在线服务器作为其缺失状态的捐赠者。捐赠者负责为新服务器提供加入该组的所有数据,直到它加入该组为止。这是通过在捐赠者和加入该组的服务器之间建立的标准异步复制通道来实现的。复制通道是MySQL 5.7 中提出的概念。简单讲一个复制通道表示从主库到从库的一条复制路径,在多源复制中主到从可以存在多条复制通道。通过此复制通道复制捐赠者的二进制日志,直到加入该组的服务器成为该组的一部分,并发生视图更改时。加入该组的服务器在收到捐赠者的二进制日志时应用它们。

        复制二进制日志时,加入该组的服务器还会缓存在组内交换的每个事务。也就是说,它监听在加入该组之后发生的事务,同时应用来自捐赠者的数据。当第一阶段结束并且关闭捐赠者的复制通道时,加入该组的服务器开始第二阶段:追赶。在此阶段,加入组的服务器继续执行高速缓存的事务。排队等待执行的事务数最终达到零时,该成员将在线声明。

        当加入组的服务器从捐赠者获取二进制日志时,恢复过程可以承受捐赠者故障。在这种情况下,捐赠者在第一阶段期间失败时,加入该组的服务器将故障转移到新的捐赠者并从新捐赠者恢复。加入该组的服务器将关闭与失败的捐赠者的连接,并打开与新捐赠者的连接,这些都是自动进行的。

(2)基于时间点的恢复
        为了使加入组的服务器与捐赠者同步到特定时间点,加入组和捐赠者的服务器利用MySQL全局事务标识符(GTID)机制。但GTID仅提供了一种方法来发现加入该组的服务器缺少哪些事务,不会传达认证信息。这是二进制日志视图标记的工作,它标记二进制日志流中的视图更改,还包含其它元数据信息,如认证相关数据。

        视图对应于主动参与当前配置的一组成员,在特定时间点,这些组成员在系统中是正确的和在线的。视图更改发生在组配置修改(例如成员加入或离开)时。任何组成员身份更改都会导致在同一逻辑时间点向所有成员传达视图更改。视图标识符唯一标识视图。只要视图发生更改,就会生成一个视图标识符。

        在通信层,视图更改及其关联的视图ID是成员加入之前和之后数据变化的边界。此概念通过新的二进制日志事件实现:“视图更改日志事件”。因此视图ID也成为在组成员资格发生变化之前和之后传输的事务的标记。视图标识符本身由两部分构成:随机部分和单调递增整数部分。第一部分在创建组时生成,并且在组中至少有一个成员时保持不变。每次视图更改发生时,第二部分都会递增。随机部分识别组的开始,增量部分标识组的改变。

(3)视图更改
        视图更改时,执行以下步骤将标识符合并到二进制日志事件:

        1. 开始:稳定组
        如图5所示,所有服务器都在线并处理来自组的传入事务。一些服务器复制的事务可能稍微落后,但最终它们会相同。此时该组充当一个分布式数据库副本。

MySQL 8 复制(七)——组复制基本原理_第5张图片 图5 稳定组

 

        2. 视图更改:加入一个组成员
        每当新成员加入组并因此执行视图更改时,每个联机服务器都会把视图更改日志事件排入队列以备执行。在视图更改之前,服务器上可能有一些属于旧视图的事务排队进行应用,将视图更改事件排在它们之后可确保正确标记何时发生了视图更改。

        同时,加入该组的服务器通过视图的在线服务器列表中选择捐赠者。如图6所示,成员加入时生成视图4,在线成员将此视图更改事件写入二进制日志。

MySQL 8 复制(七)——组复制基本原理_第6张图片 图6 成员加入

 

        3. 状态转移:追赶
        一旦加入该组的服务器选择该组中的某服务器作为捐赠者,则在两者之间建立新的异步复制连接并且开始状态转移(第一阶段)。这种与捐赠者的交互一直持续到服务器加入组的应用程序线程,该线程处理服务器进入组时所触发的视图更改日志事件。加入该组的服务器从捐赠者复制,直到它到达与视图改变相匹配的视图标识符,如图7所示。

MySQL 8 复制(七)——组复制基本原理_第7张图片 图7 追赶

 

        加入该组的服务器知道它应该在哪个视图标识符停止复制。由于视图标识符在相同的逻辑时间被发送到组中的所有成员,避免了复杂的GTID集合计算,因为视图ID清楚地标记了属于每个组视图的数据。

        加入该组的服务器正在从捐赠者复制时,它也会缓存来自该组的传入事务。最后它停止从捐赠者复制并切换到应用缓存的那些事务,如图8所示。

MySQL 8 复制(七)——组复制基本原理_第8张图片 图8 排队的事务

 

        4. 完成:赶上
        当加入组的服务器识别出具有预期视图标识符的视图更改日志事件时,终止与捐赠者的连接并开始应用缓存的事务。视图更改日志事件除了在二进制日志中充当分隔标记,还扮演另一个角色。当新服务器进入组时,它传达所有服务器感知的认证信息,即最后的视图改变。如果没有视图更改事件,加入该组的服务器将没有必要的信息对后续事务进行冲突检测。

        追赶的持续时间(第二阶段)是不确定的,它取决于负载和进入组的事务的多少。此过程完全联机,加入组的服务器在追赶时不会阻止组中的任何其它服务器。当进行到第二阶段时,加入该组的服务器的事务可能落后,落后的多少取决于负载。

        当加入组的服务器达到零排队事务并且其存储的数据等于其它成员时,其公共状态将更改为联机,如图9所示。

MySQL 8 复制(七)——组复制基本原理_第9张图片 图9 实例联机

 

(4)分布式恢复的使用建议和限制

        分布式恢复基于传统的异步复制,如果加入组的服务器没有数据或者只有非常旧的备份数据,恢复过程可能很慢。这意味着要在第一阶段传输大量数据,新增服务器可能需要很长时间才能恢复。因此建议在将服务器添加到组之前,应该为其配置已经在组中的服务器的相当近的快照。这最小化了第一阶段的所需时间并减少了对捐赠服务器的影响,因为它只需保传输较少的二进制日志。

你可能感兴趣的:(MySQL,MySQL高可用方案)