mysql数据库现在这么流行,其复制组件功不可没,虽然其它类型的关系型数据库也有复制功能,向oracle,db2但是其复制组件没有Mysql数据库的复制那么灵活,简便,而且mysql开源,开发着可以很容易的就开发出第三方mysql数据库复制中间件,比较有名的像阿里的DTS。
言归正传,下面就介绍一下mysql的复制的模式,主要分为以下三种种
-
异步复制
mysql数据库默认的复制方式为异步模式。主库在执行完客户端提交的事务后会立即将结果返给给客户端,不关心从库是否已经接收并处理过这些事物。这种模式,主从之间因为延迟,导致数据存在差异,当主库宕机之后,从库接管之后,会导致部分数据丢失,这在某些业务场景是不可接受的。 -
全同步
指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。这种全同步模式需要等待所有从库执行完该事务才能返回,会导致复制性能受到影响,并且数据库的TPS也会受到影响。 -
半同步复制
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性。
那是不是配置了数据库的半同步,当发生主从切换之后,业务数据一定不会丢失呢,今天就重点说说半同步复制
先看一下mysql5.6版本的半同步复制原理图
大家有没有从图中发现问题,没错,用户提交的事物在主库“storage commit”,就是说事物已经在主库落地了。然后才进入等待从库去执行该事物,从库执行成功,然后给客户端请求返回成功。
如果主库在“waiting slave dump”阶段宕机了,大家想想会发生什么事情,没错,主库和从库之前就会发生数据不一致。主库比从库多业务数据。
试想一下,主机宕机了,从库接管业务之后,应用已经读到了的数据,在从库删读不到了,因为之前的事物失败了,业务需要重新在从库上做事物,这时候把主库恢复之后,启动主从复制,复制就会报错,因为有主键冲突。这就是mysql半同步的弊端。
在mysql5.7版本修改半同步的流程,解决了在5.6版本中的数据不一致问题,其流程如下所示
从图中可以看到,mysql调整了"Engine commit"的执行顺序,将"Waiting Slave dump"被调整到"Storage Commit"之前,主库将每个事务写入binlog,传递到slave刷新到磁盘,同时主库提交事务。master等待slave反馈收到中继日志,只有收到ACK后master才将commit OK结果反馈给客户端。