上篇文章我们聊了单机模式下,MySQL是如何保证数据一致性的,但是在实际的生产环境中,很少采用单机模式。现在所有的集群架构都是从MySQL的主从复制演变过来的。MySQL的主从复制是通过将主库的binlog发送至从库,从库重新提交主库的变更来实现主从数据的一致性。MySQL的主从复制主要分为三种:异步复制、半同步复制、组复制(MGR)。
1. 异步复制
异步复制是MySQL的默认复制方式,其原理就是主库写入binlog日志后即可成功返回给客户端,不用等待binlog日志传递给从库。这样就会出现一个问题,假如主机crash掉了,主库上提交的事务可能并没有传到从库,我们将从库提升为主库,这样就会造成数据丢失的情况。
2. 半同步复制
MySQL在5.5中引入了半同步复制,启用半同步复制后,主库在应答客户端提交的事务前需要保证至少一个从库接收并写入relay log中。如果等待超时,超过rpl_semi_sync_master_timeout参数设置的时间,则关闭半同步复制,并自动转换为异步复制模式,直到至少有一台从库通知主库已经接收到了binlog为止。
半同步复制通过rpl_semi_sync_master_wait_point参数来控制master在哪个环节接收到slaveack后返回状态给客户端。该参数由两个值:
(1) AFTER_COMMIT
该参数是MySQL5.6版本的默认值,表示主库将事务写入binlog,并传递给从库,同时主库提交该事务,只有收到从库返回ack的时候,才将成功结果反馈给客户端。在等待从库ack的时候虽然没有给客户端反馈,但是事务已经提交,其他客户端会读取到该事务。
如果slave端还没有读取到该事务的events,同时主库发生crash,然后切换到了备库,那么之前已经在主库提交的时候就不见了,这时就出现了数据不一致的问题,如果主库用于启动不了了,那么该事务也就丢失了。
(2) AFTER_SYNC
针对上面提到的问题,MySQL5.7版本又引入了after_sync参数,该模式下主库会等到至少有N个从库接收了binlog并反馈ack之后才提交事务。N是由rpl_semi_sync_master_wait_for_slave_count控制。
after_sync模式下解决了after_commit模式下带来的数据不一致的问题,因为主库只有等到从库的ack之后才提交事务。但是同样还有一个问题,当主库的binlog同步到从库之后,binlog sync之前发生了crash,很明显这个事务在主库上未提交成功,但是从库已经接收了这些binlog,并且执行成功,如果发生了主从切换,相当于从库多出了数据,而主库已经回滚掉了,这时候就又造成了主从的数据”不一致”。
3. 组复制
从异步复制到半同步复制,MySQL提高了数据库的强一致性,2016年12月MySQL Group Replication(MGR,即组复制)的第一个GA版本正式发布于MySQL5.5.17中,MySQL组复制提供了高可用、高容错、高扩展、高灵活性的MySQL集群服务。
高一致性:基于原生复制及paxos协议的组复制技术,并以插件的方式提供,提供一致性数据安全保证。
高容错性:只要不是大多数节点坏掉就可以继续工作,有自动检测机制,当不同节点产生资源争用冲突时,按照先到者优先的原则处理,并且内置了自动化脑裂防护机制。
高扩展性:节点的新增和移除都是自动的,新节点加入后,会自动从其他节点同步状态,直到新节点和其他节点保持一致,如果节点被移除了,其他节点也会自动更新组信息。
高灵活性:有单主模式和多主模式,单主模式下会自动选主,所有更新都会在主库上进行,多主模式下,所有server都可以同时处理更新操作。
基于组的复制(Group-basedReplication)是一种被使用在容错系统中的技术。复制组是一个通过消息传递互相交互的server集群,通信层提供了原子消息(atomic message)和完全有序信息交互等保障机制。MySQL Group Replication正是基于这些技术和概念,实现了一种多主更新的复制协议。
复制组有多个server成员构成,组中的每个成员都可以独立的执行事务,而读写(RW)事务则会在于group内的其他节点进行协调之后再commit。只读事务(RO)不需要进行冲突检测,可以立即提交。换句话说,对于RW事务,在始发server上,当事务准备提交时,会自动在group内进行原子性的广播,告知其他节点变更了什么内容/执行了什么事务,冲突检测通过后,为该事务建立一个全局的顺序,这种原子广播的方式,也使得这个事务在每一个节点上都保持着同样顺序。因此,所有的server成员以相同的顺序应用相同的更改,以确保组内一致。
不同的节点上执行的事务之间可能存在资源争用的情况,这种现象容易出现在两个不同的并发事务上,假设在不同的节点上有两个并发事务,更新了同一行数据,那么就会发生资源争用。面对这种情况,Group Replication判定先提交的事务可以在所有server上提交,后提交的事务会在源server上回滚,最后丢弃掉。这就是分布式中的先提交当选规则。
4.小结
今天我们一起聊了MySQL在集群模式下的三种复制模式,从异步复制到半同步复制再到组复制,从易丢失数据到实现数据的强一致性,再到MGR的无损复制,也代表了MySQL的复制模式的进化史,代表了MySQL在数据一致性道路上的探索和前进。这篇文章主要对三种复制模式进行了简单的介绍,未做深入的探讨,后面我们还会继续介绍MySQL三种复制模式。