MySQL的Binlog与主从复制

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL的Binlog与主从复制相关的知识,希望对你有一定的参考价值。

参考技术A mysql中,可以使用多种存储引擎。其中最常用的InnoDB引擎支持事务,Redo Log和Undo Log就是InnoDB里面的工具,用于实现事务。而Binlog是MySQL层面的东西,用于实现主从复制,与使用的存储引擎无关。

通过监听并解析Mater的Binlog,也可以实现将MySQL中的数据同步到其他应用组件中(比如更新缓存)的效果。

在不发生宕机的情况下,未提交的事务和已回滚的事务是不写入Binlog日志中的,只有提交成功的事务才写入Binlog日志。这一点和Redo Log不一样,Redo Log中会记录未提交、已回滚的事务内容。

Binlog是一种逻辑日志——例如Binlog的statement格式记录原始SQL语句、RAW格式记录某一行修改前后的值——且一个事务的日志在Binlog中是连续排列的,因此要求每个事务都要串行地写入,这意味着每个事务在写Binlog之前都要排他地锁住Binlog,这会导致写的效率很低。MySQL5.6之后,通过pipline技术异步地批量化将已提交的事务内容写入Binlog。

一个事务的提交既要写Binlog日志又要写Redo Log日志,如何保证双写的原子性?一个写成功,写另外一个时发生宕机,重启后如何处理?在讨论这个问题之前,先说下Binlog自身写入的原子性问题:Binlog刷盘到一半,出现宕机,这个问题和Redo Log的写入原子性是同样的问题,通过类似于checksum的办法或者Binlog中的结束标记来判断出某个事务的Binlog这是不是不完整的Binlog,从而把不完整的部分截掉。对于客户端来说,此时宕机,事务肯定是没有提交成功的,所以截掉也没问题。下面来讲如何保证双写Binlog和Redo Log的原子性。由于双写Binlog和Redo Log发生在同一台机器上,这其实是一个内部分布式事务,可以使用两阶段提交法来实现双写的原子性。简单来说就是:

1)第一阶段(准备阶段):MySQL Server要求innoDB完成将事务内容写入Redo Log中的工作,只等事务提交;以及,MySQL Server完成Binlog内容写入内存的工作,只等刷盘。两个都准备好之后,会向MySQL Server发送OK反馈,MySQL Server紧接着执行第二阶段。

2)第二阶段(提交阶段):收到客户端的Commit指令,MySQL Server先将内存中的Binlog刷盘,然后让innoDB执行事务的提交。两个都完成之后,会向MySQL Server发送OK反馈,两阶段提交结束。

若双写Binlog和Redo Log的过程中发生宕机,处理思路为:

1)若宕机发生在第一阶段,此时Binlog还在内存中,宕机导致全部消失。而Redo Log记录了未提交的日志,MySQL Server重启后感知到Binlog中不存在Redo Log中记录的未提交事务,会自行回滚未提交事务的Redo Log日志;

2)若宕机发生在第二阶段,Binlog写了一半,innoDB还未执行提交,MySQL Server重启后会对Binlog做截断,对Redo Log中记录的未提交事务做回滚;

3)若宕机发生在第二阶段,Binlog写入成功,innoDB还未执行提交,MySQL Server重启后会通过checksum的办法或者Binlog中的结束标记感知到Binlog写入成功,紧接着对Binlog中存在的、但Redo Log未提交的事务发起提交。

在MySQL的Master / Slave集群模式中,有三种主从复制模式:

1)同步复制:所有的Slave都收到Master发送的Binlog,并且接收完,Master才认为事务提交成功,再对客户端返回成功。这种方式最安全,但是性能很差;

2)异步复制:只要Master事务提交成功,就对客户端返回成功。后台线程异步地将Binlog发送给Slave,然后Slave回放Binlog。这种方式性能最好,但是可能会导致数据丢失;

3)半同步复制:Master事务提交后,同时把Binlog同步给Slave,只要有部分(数量可以配置)Slave收到了Binlog,就认为事务提交成功,对客户端返回。

对于半异步复制,如果Slave超时后还未返回,也会退化为异步复制。所以无论是异步复制还是半异步复制,都无法严格保证主从中的数据完全一致,主从复制的延迟会导致主节点宕机后部分数据未来得及同步到从节点,从而丢失数据。但是主节点宕机后,还是要立即切换到从节点,保证服务的可用(牺牲一致性保证可用性),数据的丢失可以通过后续的人工干预来补偿。

以上是关于MySQL的Binlog与主从复制的主要内容,如果未能解决你的问题,请参考以下文章

MySQL主从同步与读写分离

MySQL主从同步与读写分离

MySQL主从同步与读写分离

mysql主从复制之异步复制与半同步复制

mysql主从复制之异步复制与半同步复制

MySQL主从复制与GTID主从复制