从一个调试结果来看MySQL 5.7的无损复制

作者:徐春阳

来源:数据库随笔


MySQL 5.7的新功能中,有一个就是无损复制,其说的无损复制,采用的依然是半同步,跟MySQL 5.6的半同步有什么区别呢?


我们从两张由调试得来的图的结果来看吧?


第一张,主库的查询结果,目前主库是处于调试状态。


我们看到主库上面有两个窗口:

第一个窗口: insert语句在执行,在此之前已经insert一条记录。

第二个窗口: select语句已经执行完成,因为第一个窗口的最后一个insert语句还没有执行完成,所以只能看到一条数据。特别说明一下,第一个窗口的查询时间T3晚于第一个窗口的最有一个insert语句执行时间T2.


因为是调试,我们阻塞了第一窗口的insert语句的线程,让其无法继续进行后续的操作。


接下来,我们看看在从库此时的查询结果:


有没有有点惊奇, 在从库居然查到了主库还没有提交完成的数据? 这会不会有问题?从库的数据比主库还多? 不急,听happypig君慢慢给你道来其中的原因。


这就是MySQL 5.7的无损复制的特性,主库的事务在提交之前,也就是该事务的执行结果对其他线程可见之前,必须在半同步的超时时间内,将事务产生的binlog传送给从库,得到从库的ack包之后,才会进行最后的提交步骤。简单的说来,就是事务的binlog没有传递到从库之前,主库还没有真正提交该事务。 这就是MySQL 5.7的无损复制的特性。 


跟MySQL 5.6的区别在于,在MySQL 5.6的版本中,是事务的执行结果已经被其他线程可见时,再将binlog 发送给从库,等待从库ack返回后,才给客户端返回结果。 等于是将binlog的输送又提前了一步。


下面来看看ORACLE技术嘉年华MySQL官方画出的无损复制流程图吧。



流程图相当清晰,在T2这个时间点查询表t1, 查询的结果里没有出现T1时间点执行的insert.  但在这个时间点,从库已经收到的binlog ,将binlog变成的从库的relay log ,并可以由sql线程进行relay.


现在我们再来解释一下,之前我们看到在从库查询得到的数据比主库还多的原因,原因就是binlog 已经传送过来了,从库就可以relay binlog 了,因为调式中止了主库线程的继续执行,无法完成最后的提交,该事务在主库上不可见,但从库已经relay该事物的binlog ,所以看到了最新的记录。


上面看到的从库比主库的数据多,完全是调式造成的,在实际情况中,不可能存在。因为主库已经完成了该sql的执行,以及事务提交过程中的几乎所有的阶段,只差最后一步操作了,而从库得到binlog之后,需要重新执行这个sql, 几乎落后了一个sql从开始到结束的执行时间。 所以,理论上不存在从库的数据比主库还新的情况,按理论,至少相差一个事务执行的时间。  但这个时间真的很短。




推荐订阅原文作者 happypig(徐春阳) 的公众号 数据库随笔(MysqlPg)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值