1.简介
本文提供mysql组复制的背景信息。
创建一个容错系统的最常见的方法是求助于组件冗余,换句话说,组件能被移除,但系统将如期可以继续操作。这将整个系统的复杂度提升到了更具挑战性的级别。尤其是,复制库必须面对多个而非一个服务器维护和管理的问题。然而,这些服务器一起合作形成一个组,但必须面对几个其他经典分布式系统问题,像网络分区和脑裂等场景。
所以,最终的挑战是将数据库和数据复制逻辑与几台协作的服务器逻辑按照一致简单的方式融合到一起。换句话说,就是让多个服务器的系统状态,数据和系统经历的每个改变都达成一致。总之,就是让多个服务器上的数据库状态转换达成一致,以便所有服务器作为一个数据库一起运行,或最终多个服务器能达成同一状态。这意味着,多个服务器需要作为一个(分布式)状态机器进行操作。
mysql组复制通过服务器间的强大协调功能提供分布式状态机器复制。当多个服务器成为同一组的部分时,它们自动相互协调。该组可以自动主机选举的单一主机模式运行,其中,任意时刻只有一个服务器可以修改。
另外,对更高级的用户,该组还可以多主机模式部署,其中,所有的服务器都可以进行修改,即使它们同时发布。该模式以应用避免其限制作为代价。
有一个内建的组成员服务,其可以在任何时间点为所有服务器保持组一致性和可用性的视图。服务器能离开和加入组,同时,该视图也会相应更新。有时服务器也会意外离开组,此时,失败探测机制探测到这种情况,并通知组视图已发生改变。所有这一切都是自动进行的。对一个事务的提交,组内大部分成员必须同意事务全局顺序中事务的顺序。每个服务器单独决定提交或终止一个事务,但所有服务器需要做出同样的决定。
如果有网络分区,导致组内成员不能达成一致,那么,直到该问题得以解决,系统才会继续进行。然而,也有一个内建的、自动的脑裂保护机制。
所有这些都通过组通信系统(Group Communication System,GCS)协议进行驱动。这提供了一个失败探测机制,一个组成员服务,和安全完全排序的消息交付。所有这些对创建一个确保数据在服务器组内进行一致复制的系统非常关键。该技术的核心在于实施Paxos算法。其扮演组通信引擎的角色。

2.复制技术
介绍mysql组复制(MGR)细节前,该部分先介绍一些背景概念和工作机制的概览。这有助于理解组复制需要什么,以及经典异步mysql复制和组复制间差别。
1)主从复制(primary-secondary replication)
传统mysql复制提供了一种简单的主从复制方法。其中,有一个主库和一个或多个从库。主库执行事务并进行提交,然后,这些事务被送到(一般为异步)从库被重新执行(基于语句的复制)或应用(基于行的复制)。
该架构为无共享(share-nothing)的系统,其中,所有服务器默认都有一份完整的数据拷贝。
也有一种半同步复制,其中,在协议中增加了一个同步步骤。这意味着,提交时主库等待从库已经收到事务的回执。此时,主库才会继续事务的提交操作。
2)组复制
组复制为一种实施容错系统的技术。复制组为一套通过信息传递相互作用的服务器。通信层提供一套类似原子信息和整体有序信息传递的保障机制。这些强有力的属性能被转换成很有用的抽象层,通过它可以构建更高级的数据库复制解决方案。
mysql组复制建立在这些属性和抽闲层之上,并实施了多主库任意地点更新复制协议。实际上,一个复制组由多个服务器组成,且组内的每个服务器可以独立的执行事务。但所有的读写(RW)事务仅被该组同意后才能被提交。只读事务无需组内进行协调就可以立即提交。换句话说,任何读写事务,该组都得决定是否提交,因此,提交操作并非源服务器的一个单边决定。更精确的讲,当事务在源服务器上准备提交时,该服务器自动将写值(rows changed,改变行)和通信写集合(被修改行的唯一鉴定符)进行广播。接着,为该事务建立一个全局总顺序。最后,这意味着所有服务器按照同样的顺序收到同样一套事务。作为结果,所有服务器按照同行顺序应用同样一套改变,所以,它们在组内保持能保持一致。
然而,不同服务器上同时执行的事务间也许会有冲突。通过对两个不同和并发事务的写集合进行检查可以探测到这种冲突,这个过程称为认证。如果两个在不同服务器上执行的并发事务,更改同样的数据行,这将会发生冲突。解决过程为排在第一位的事务将在所有服务器上进行提交,而排在第二位的事务将被终止,这将导致该事务在源服务器上进行回滚,并在组内其他服务器上对该事务进行删除。这实际上是一个先提交先赢的分布式规则。
最后,组复制是一个无共享的复制方案,其中,每个服务器都有其自己的一份完整的数据拷贝。

3.组复制使用场景
组复制通过将系统状态复制到一套服务器的冗余技术来创建容错系统。因此,即使某些服务器失败了,只要大部分服务器没失败,系统就还是可用的,最多就是导致性能和可伸缩性的降级,但还是可用的。失败的服务器被隔离和独立出来。这些服务器被一组依赖于分布式失败探测器的服务进行跟踪,当任何服务器由于资源或意外终止而离开组时,这些分布式失败探测器可以发送信号。一个分布式恢复过程确保当服务器加入组时其状态会被自动更新。不必进行服务器失败切换,多主随地更新的特性确保单个服务器失败事件中不会阻塞任何更新。索引mysql组复制保证数据库服务是连续可用的。
理解一点很重要,那就是当服务器崩溃时,连接到该服务器的客户端必须重定向,或失败切换到其他不同的服务器。这并非mysql组复制试图解决的问题。连接器,负载均衡器,路由器或某些中间件更适合处理这些问题。
总之,mysql组复制提供一个高可用的,高弹性的,可靠的mysql服务。
1)案例场景实例
下面是使用组复制的典型使用案例。
--弹性复制:需要频繁变化复制架构的环境,其中,服务器的数量必须动态的增长或收缩,且尽量降低其带来的副作用。例如:云数据库服务。
--高可用分片:分片是一种获取写扩展的流行方法。通过mysql组复制实施高可用分片,其中,每个分片映射到复制组。
--master-slave复制的替代方案:某些环境中,使用单主服务器会导致单一冲突点。对整个组的写操作在某些环境下也许会提供更好的伸缩性。
--自主系统:另外,可以利用mysql组复制内建于复制协议的自动机来实现这种自主系统。

4.组复制细节
该部分提供组复制基于的某些服务的具体细节。
1)失败探测
有一个失败探测机制,该机制能发现和报告那个服务器没反应,并假设该服务器已经死机。高层面上,失败探测机制是一个能提供有关哪些服务器也许死机(存疑)信息的分布式服务。稍后如果组认为存疑的服务器可能是真的死机,那么,该组决定该服务器确实已经失败了。这意味着组内剩余成员共同决定将该已失败的成员排除在外。
当服务器没反应时就会触发存疑。在特定期间内服务器A收不到服务器B的信息,将发生超时和产生存疑。
如果一个服务器被从组内其余成员隔离,那么,其将认为所有其他服务器已经失败。不能与组达成协议(由于它达不到法定人数),因此,它的存疑并不会有结果。当一个服务器以这种方式被从组隔离时,它并不能执行任何本地事务。
2)组成员
mysql组复制依赖于一个组成员服务。这被建立在插件内。其定义哪些服务器在线并参与组。在线服务器其列表通常被作为一个视图参考。所以,任意时刻组内的每个服务器都会有一个关于哪些服务器参与组的一致性视图。
服务器不仅同意事物提交,还同意哪个是当前视图。所以,如果服务器同意一个新服务器加入组,那么,组将被重新配置以将该服务器集成进来,从而触发一个视图的改变。相反,如果一个服务器离开组,无论是否自愿,那么,组将动态重新安排配置并触发视图修改。
一个成员自愿离开时,将首先初始化一个动态组重配置。这将触发一个过程,期间,所有成员必须同意没有该离开服务器的新视图。然而,如果一个成员不自愿的离开(例如:意外停止或网络不通),那么,失败探测机制认识到这个事实,并提议组内大多数服务器进行重新配置,重配置后的组并不包含失败的成员。如前述这将要求组内大多数服务器的同意。如果组不能达成一致(例如:其按照没有大多数服务器在线的方式分区),那么,系统不能动态改变配置,从而阻塞以阻止发生脑裂的情况。最终,这将意味着管理员需要接入和修复这种情况。
3)容错
mysql组复制建立在Paxos分布式算法的实施之上,从而支持服务器间的分布式协调。这样,其需要大多数服务器为活动状态以达到法定人数,并作出决定。这将直接影响系统能容忍的失败服务器数,而不会对其本身和整体功能造成影响。需要容忍f个服务器失败的服务器数(n)为n = 2 x f + 1。
实际上,这意味着为了容忍组的一个服务器失败,组内必须有三个服务器。这样如果一个服务器失败了,还有两个服务器形成大多数(三分之二),以允许系统继续自动做出决定并前进。然而,如果第二个服务器意外失败了,那么组(只剩下一个服务器)发生阻塞,因为没有大多数来做出决定。