§ MGR 数据一致性保障
本文介绍MGR如何保障数据一致性及安全性。
§ MGR事务一致性
对于MGR这样的"分布式"系统而言,需要在多个节点间保障事务的一致性,无论各个节点状态正常,或者个别节点处于故障修复状态,都要能保证各个节点的事务数据最终一致。所谓的最终一致性是指当所有写事务请求都停止后,各个节点上的事务数据是一致的。
与MGR数据一致性相关的因素有这几种:
- 节点发生变化,添加 或 删除。
- 节点故障修复。
- Primary节点发生切换。
通过选项 group_replication_consistency
可以设置节点的事务一致性保障等级。
§ Primary节点切换时如何保障事务一致性
在单主模式中,当Primary节点切换时(无论是手动切换还是因为故障转移),新的Primary节点有两种可选方式应对如何处理积压事务:
- 第一种:不处理积压事务,立即响应读写事务请求。这时,事务可能会读取到旧数据,或者UPDATE丢失,INSERT新数据冲突等问题。
- **第二种:优先处理完积压事务后再响应读写事务请求。**这时,新的Primary节点可能需要耗时更久才能响应读写事务请求,这取决于积压事务队列大小。
§ 事务数据一致性保障
在MGR中,并不是所有的事件(事务)都是同步的,部分流程是异步的,因此Secondary节点上可能存在数据延迟,也就是说在Secondary上可能读取到旧事务数据。
通过设置选项 group_replication_consistency
可以控制RO(只读)、RW(读写)事务在读取或写入数据前的一致性等级,可以避免读取到旧数据,或者写入数据后尽快同步到其他节点,以满足各种不同应用场景对事务一致性等级的要求。
先了解几个基本概念,事务同步点可分为 读时事务同步 以及 写时事务同步,结合MGR的事务机制,更具体的说就是 事务执行前(BEFORE) 和 事务执行后(AFTER)。
接下来,我们介绍选项 group_replication_consistency
都有哪些可选等级。
每个节点上可以单独设置不同的事务一致性等级,而且可做session级修改,但是非常不建议这么做。
§ EVENTUAL
在这个等级下,RO和RW事务执行前,都不会要求等待积压事务先行应用完成。
这是默认等级,也是在引入该选项前的行为。这意味着以下几点:
- RW事务无需等待,而可能先于其他节点进行外部化(将事务广播到其他节点)。
- RO事务可能读取到旧数据。
- 在Primary节点切换时,新产生的RW事务有可能会因为冲突而回滚。
§ BEFORE_ON_PRIMARY_FAILOVER
当发生Primary节点切换时,在新的Primary上需要先等待把所有来自旧Primary节点的积压事务应用完毕,之后才能正式完成切换,转成ONLINE状态,成为新的Primary节点,继续响应新的事务请求。
这么做可以保证在发生故障转移时,客户端不会查到旧数据,保证了数据一致性,不过客户端上也可能会产生延迟等待。
§ BEFORE
RW事务在应用之前,RO事务在执行之前,都要先等待前面堆积的事务完成。
这可以保证RO事务总能读取到最新事务,但对于RW事务而言,只是等待堆积事务应用完成,但并不要求其他节点上也完成该事务。
§ AFTER
它比BEFORE更近一步,要求RW事务在其他节点上也要等待应用完毕。这样一来,后续的事务在任何节点上就都能获取最新事务数据。
事实上,要慎用该级别及更高以上级别,可能会引发其他问题,可参考这个文章:为什么MGR一致性模式不推荐AFTER (opens new window)。
§ BEFORE_AND_AFTER
一致性级别要求最高,对RO和RW事务都要求同步事务数据。也就是说,RW事务在应用之前,要先等待前面堆积的事务完成,并且还需要等待它的事务变更在其他所有节点上也都应用;RO事务在执行之前,也要先等待前面堆积的事务完成。
§ 一致性级别选择建议
对于绝大多数场景,使用默认的 EVENTUAL 等级就足够了;尤其是在使用单主模式时,如果需要实时读取事务数据,只需向Primary节点发起请求即可。
进一步,如果担心Primary节点切换时会读取到旧事务数据,可以提高到 BEFORE_ON_PRIMARY_FAILOVER 级别。
更进一步,如果希望在Secondary节点也能及时读取到最新事务数据,以此提高读扩展能力,可以提高到 BEFORE 级别。
更高的一致性级别就不再建议使用了,潜在的风险以及bug比较多。
P.S,各个节点的一致性级别最好都设置成一样,并且在运行过程中也不要修改其session级选项值,避免造成不可预料的影响。
扫码关注微信公众号