通过MySQL主从同步,我们可以实现读写分离、数据备份和高可用性。主从同步的原理就是基于binlog进行数据同步的,binlog二进制日志记录了对数据库进行更新的事件, 比如insert、update、delete等。在主从复制过程中,会基于3个线程来操作,一个主库线程,两个从库线程。

二进制日志转储线程(binlog dump thread)是一个主库线程。当从库线程连接的时候,主库可以将二进制日志发送给从库,当主库读取事件的时候,会在binlog上加锁,读取完成之后,再将锁释放掉。

从库I/O线程会连接到主库,向主库发送请求更新binlog,这时从库的I/O线程就可以读取到主库的二进制日志转储线程发送的binlog更新部分,并且拷贝到本地形成中继日志(relay log)。

从库SQL线程会读取从库中的中继日志,并且执行日志中的事件,从而将从库中的数据与主库保持同步。

进行主从同步的内容是二进制日志,它是一个文件,在进行网络传输的过程中一定会存在延迟(比如500ms),这样就可能造成主从同步中的数据不一致性问题。

复制方式

如果按照数据一致性从弱到强进行划分,有3种复制方式:异步复制、半同步复制、组复制。

异步复制就是客户端提交commit之后不需要等待从库响应,而是直接将结果返回给客户端,这样做的好处是不会影响到主库写的效率,但可能存在主库和从库数据不一致的异常情况。

半同步复制是在mysql5.5版本之后开始支持。原理是在客户端提交commit之后不直接将结果返回给客户端,而是等待至少有一个从库响应后(接收到binlog,并且写入了中继日志中),再返回给客户端。虽然相对于异步复制来说,至少增加了一个网络连接的延迟,降低了主库写的效率,但是提高了数据的一致性。

组复制技术,是在5.7.17版本中推出的一种新的数据复制技术,这种复制技术是基于paxos协议的状态机复制。

首先,将多个节点共同组成一个复制组,在执行读写(RW)事务的时候,需要通过一致性协议层(consensus层)的同意,也就是读写事务想要提交,必须通过组里“大多数人”(对应node节点)的同意,大多数指的的是同意的节点数量需要大于(N/2+1),因此,对于paxos协议也被称为“多数派”协议。这样才可以进行提交,而不是原发起方一个说了算。而针对只读事务(RO)事务则不需要经过组内同意,直接commit即可。

在一个复制组内有多个节点,它们各自维护了自己的数据副本,并且在一致性协议层实现了原子消息和全局有序消息,从而保证组内数据的一致性。