MGR原理解析
目录一、MySQL MGR演化
1.1 MySQL异步复制
master事务的提交不需要经过slave的确认,slave是否接收到master的binlog,master并不care。slave接收到master binlog后先写relay log,最后异步地去执行relay log中的sql应用到自身。由于master的提交不需要确保slave relay log是否被正确接受,当slave接受master binlog失败或者relay log应用失败,master无法感知。
1.2 MySQL半同步复制
基于传统异步存在的缺陷,mysql在5.5版本推出半同步复制。可以说半同步复制是传统异步复制的改进,在master事务的commit之前,必须确保一个slave收到relay log并且响应给master以后,才能进行事务的commit。但是slave对于relay log的应用仍然是异步进行的,原理如下图所示:
1.3 MySQL组复制(MGR)
MySQL是目前最流行的开源关系型数据库,国内金融行业也开始全面使用,其中MySQL 5.7.17提出的MGR(MySQL Group Replication)既可以很好的保证数据一致性又可以自动切换,具备故障检测功能、支持多节点写入,MGR是一项被普遍看好的技术。
MGR (MySQL Group Replication)是MySQL自带的一个插件,可以灵活部署。MySQL MGR集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完整的副本,它是基于ROW格式的二进制日志文件和GTID特性。架构主要是APIs层、组件层、复制协议模块层和GCS API+Paxos引擎层构成。
应用发来的事务从MySQL Server经过MGR的APIs接口层分发到组件层,组件层去capture事务相关信息,然后经过复制协议层进行事务传输,最后经过GCS API+Paxos引擎层保证事务在各个节点数据最终一致性。这是事务进入MGR层内部处理过程。
MGR由若干个节点共同组成一个复制组,一个事务的提交,必须经过组内大多数节点(N / 2 + 1)决议并通过,才能得以提交。如上图所示,由3个节点组成一个复制组,Consensus层为一致性协议层,在事务提交过程中,发生组间通讯,由2个节点决议(certify)通过这个事务,事务才能够最终得以提交并响应。
引入组复制,主要是为了解决传统异步复制和半同步复制可能产生数据不一致的问题。组复制依靠分布式一致性协议(Paxos协议的变体),实现了分布式下数据的最终一致性,提供了真正的数据高可用方案(是否真正高可用还有待商榷)。其提供的多写方案,给我们实现多活方案带来了希望。
1.4 MySQL组复制的特性和限制
特性优点:
1、高一致性,基于原生复制及paxos协议的组复制技术,并以插件的方式提供,提供一致数据安全保证;
2、高容错性,只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,不会出现错误,按照先到者优先原则进行处理,并且内置了自动化脑裂防护机制;
3、高扩展性,节点的新增和移除都是自动的,新节点加入后,会自动从其他节点上同步状态,直到新节点和其他节点保持一致,如果某节点被移除了,其他节点自动更新组信息,自动维护新的组信息;
4、高灵活性,有单主模式和多主模式,单主模式下,会自动选主,所有更新操作都在主上进行;多主模式下,所有server都可以同时处理更新操作。
限制:
(具体可参考官方文档说明:https://dev.mysql.com/doc/refman/5.7/en/group-replication-requirements-and-limitations.html)
1、仅支持InnoDB表,并且每张表一定要有一个主键,用于做write set的冲突检测;
2、必须打开GTID特性,二进制日志格式必须设置为ROW,用于选主与write set;主从状态信息存于表中(--master-info-repository=TABLE 、--relay-log-info-repository=TABLE),--log-slave-updates打开;
3、COMMIT可能会导致失败,类似于快照事务隔离级别的失败场景
4、目前一个MGR集群最多支持9个节点
5、不支持外键于save point特性,无法做全局间的约束检测与部分事务回滚
6、二进制日志不支持binlog event checksum
二、MGR原理
2.1 MGR集群中事务整个生命周期
接下来从全局角度看事务整个生命周期,DB1 、DB2 、DB3构成的MGR集群, 集群中每个DB都有MGR层,MGR层功能也可简单理解为由Paxos模块和冲突检测Certify模块实现。Paxos模块是基于Paxos算法确保所有节点收到相同广播消息,transaction message就是广播消息的内容结构;冲突检测Certify模块进行冲突检测确保数据最终一致性,其中certification info是冲突检测中内存结构;本文详细介绍冲突检测模块实现原理,Paxos算法实现部分后续对比Raft算法详细介绍。
当DB1上有事务T1要执行时,T1对DB1是来说本地事务,对于DB2、DB3来说是远端事务;DB1上在事务T1在被执行后,会把执行事务T1信息广播给集群各个节点,包括DB1本身,通过Paxos模块广播给MGR集群各个节点,半数以上的节点同意并且达成共识,之后共识信息进入各个节点的冲突检测certify模块,各个节点各自进行冲突检测验证,最终保证事务在集群中最终一致性。
在冲突检测通过之后,本地事务T1在DB1直接提交即可,否则直接回滚。远端事务T1在DB2和DB3分别先更新到relay log,然后应用到binlog,完成数据的同步,否则直接放弃该事务。
2.2 transaction message和certification info
介绍冲突检测实现原理之前,先介绍一下广播信息transaction message、冲突检测内存certification info的结构组成。
transaction message
如图8所示,transaction message保存是事务T1要更新行的的相关信息,有transaction_context_log_event和gtid_log_event及log_event_group三部分组成。
具体组成:
1 write set 叫写入集合,是事务更新行相关信息的Hash值。
write set=Hash(库名+表名+主键(唯一键)字段信息)
2 gtid_executed为已经执行过的事务gtid集合,也即事务快照版本。
3 把write set 和gtid_executed打包成为事务上下文信息
transaction_context_log_event。
4 gtid_log_event为已经执行过的事务gtid集合。
5 log_event_group为事务日志信息,后续要更新到relay log中。
6 把3和4和5一起打包成为transaction message广播给其它节点。
certification info
广播的信息到达冲突检测模块certification之后是如何工作?
每个节点都有一个certification info的内存结构,certification info保存了通过冲突检测的事务的write set和gtid_executed。certification info相当于一个map,key是string结构,保存write set中提取的主键值;value是set集合,保存gtid_executed事务快照版本;例如T1事务,T1更新数据库d1中的表t1中两行数据id=1和id=2,它对应快照版本UUID_MGR是:1-100,刚开始certification info为空,所以直接提交,之后certification info中快照版本直接更新为1-101.
2.3 冲突检测核心机制!敲黑板!
通过上面的例子可知通过冲突检测标准:若 transaction UUID_MGR ">="certification info UUID_MGR,则冲突检测通过。
根据上述标准举例,事务T2,更新id=2的行,事务T2的UUID_MGR为1-102, 节点中冲突检测模块中的certification info中的UUID_MGR为1-101,这里T2:UUID_MGR:1-102>UUID_MGR:1-100,则T2冲突检测通过。
反之,事务T3,更新id=1的行,事务T3的UUID_MGR为1-100, 节点中冲突检测模块中的certification info中的UUID_MGR为1-101,很明显T3:UUID_MGR:1-100<UUID_MGR:1-101,则T3冲突检测失败,事务回滚或者丢弃。
上面是针对于单独一个写来进行判断,现在我们来展示一下多节点模式中,多个事务同时写入时冲突检测机制。如下图所示,三个事务T4、T5、T6并行写入某个MySQL节点,通过了Paxos协议模块达成一致性共识,进行冲突检测时遵循下面三个原则:
1)多个事务修改同一个id对应的数值,需要按照先后顺序进行冲突检测。
2)多个事务同时对不同的id进行修改,各自进行修改即可。
3)不同的事务对同一个id修改,需要按照先后顺序进行冲突检测即。
事务T4和事务T5同时更新id=1的行,按照先来后到顺序进行冲突检测,T4先到先进行冲突检测。
事务T4,更新id=1的行,事务T4的UUID_MGR为1-102, 节点中冲突检测模块中的certification info中id=1的UUID_MGR为1-101,很明显T2:UUID_MGR:1-102>UUID_MGR:1-101,则T4冲突检测通过,更新为certification info中UUID_MGR为1-103。
事务T5,更新id=1的行,事务T5的UUID_MGR为1-100, 节点中冲突检测模块中的certification info中id=1的UUID_MGR为1-102,其中T5:UUID_MGR:1-100>UUID_MGR:1-102,则T5冲突检测不通过。
事务T6,更新id=3的行,事务T6的UUID_MGR为1-100, 节点中冲突检测模块中的certification info中id=3的UUID_MGR为空,其中T6:UUID_MGR:1-100>UUID_MGR,则T6冲突检测通过,更新为certification info中UUID_MGR为1-101。
事务T4和事务T5并行修改id=1,T4写入成功,T5丢弃,T6写入id=3事务,写入成功。
随着 write set不断写入certification info中,内存消耗会相应增大,MGR有配套的write set 清理线程,每隔一段时间去清理已经在节点应用或者回放的事务的write set信息。
三、MGR特点
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/William0318/article/details/106889452