复制技术的演进实际上有两条路线,一条路线为基于数据安全的复制技术演进;另一条路线为基于复制效率的复制技术演进。
复制格式概述
接触过MySQL的朋友都或多或少地知道,MySQL的复制是基于binlog(二进制日志)实现主从实例之间的数据同步的。binlog的格式可以分为三种,从某种意义上来说,也可以说对应着三种复制格式,使用binlog_format控制binlog的格式,该参数的不同值代表了不同的复制格式。下面通过该参数的三个值对复制格式进行简单的阐述。
- statement:在MySQL5.1.5版本之前只支持statement格式(statement binary replication,SBR),实现数据同步,但在执行跨库更新等SQL时容易出现主从库的数据不一致的问题。
- row:在MySQL5.1.5及之后的版本中,新增支持row格式(row binary replication,RBR),不再简单记录SQL语句的执行顺序,而是逐行记录在存储引擎的数据是如何变更的,主从库的数据一致性保障得到大幅度提升。
- mixed:在MySQL5.1.8及之后的版本中,新增支持mixed格式(mixed binary replication,MBR),本质上是让MySQL服务器自行根据SQL语句的不同来判断是否需要使用row格式,当出现可能造成主从库数据不一致的SQL语句时,binlog自动转为row格式记录,否则默认使用statement格式记录。
基于数据安全的复制技术演进
异步复制
1、原理:异步复制主要利用三个线程来实现数据流转:主库binlog dump线程、从库IO线程和SQL线程。
异步复制原理大致如下:
用户对数据的修改进行提交,然后master把所有数据库的变更写进binlog中,主库线程binlog dump把binlog内容推送给从库,从库被动接收数据,而不是主动去获取数据的。
从库IO线程读取主库上的binlog信息,并把binlog写到本地中继日志(relay log)中。
从库SQL线程读取并解析relay log内容,按照主库中的提交顺序进行事务回放,写入本地数据文件中,这样就实现了数据在主从实例之间的同步。
这里有一个小细节需要注意:主库在写入binlog并落盘之后,通知dump线程有新的binlog产生,并发送到从库中,然后主库并不理会从库是否接收到binlog,而是自顾自地照常进行事务提交。
半同步复制
1、原理:在半同步复制出现之前,虽然异步复制可以满足主从实例之间的数据同步,同时row格式的binlog也能够大幅度避免主从实例的数据不一致的情况,但是如果碰到主库崩溃,写业务故障切换到从库,将从库提升为主库时,原来的主库上可能有一部分数据还没来得及被从库接收,而事实上这部分丢失的数据可能在主库上已经正常提交完成了。为解决这个问题,在MySQL5.5版本中引入了半同步复制,半同步复制的关键改进就是当客户端在主库写入一个事务时,需要等待从库接收到主库的binlog,且主库接收到ACK确认之后,客户端才能收到事务成功提交的消息。