1 主从一致性加强支持在事务commit前等待ACK


新版本的semi sync 增加了rpl_semi_sync_master_wait_point参数 来控制半同步模式下 主库在返回给会话事务成功之前提交事务的方式。

该参数有两个值:

  • AFTER_COMMIT(5.6默认值)

   master将每个事务写入binlog ,传递到slave 刷新到磁盘(relay log),同时主库提交事务。master等待slave 反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。

wKiom1jkwuywfgnSAABtrBNGPlA973.jpg-wh_50

  • AFTER_SYNC(5.7默认值,但5.6中无此模式)


master 将每个事务写入binlog , 传递到slave 刷新到磁盘(relay log)。master等待slave 反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。

wKiom1jkwwSgTNc-AABxSxvLGck768.jpg-wh_50

因此5.7引入了after_sync模式,带来的主要收益是解决after_commit导致的master crash主从间数据不一致问题,因此在引入after_sync模式后,所有提交的数据已经都被复制,故障切换时数据一致性将得到提升。


2 性能提升支持发送binlog和接受ack的异步化

旧版本的semi sync 受限于dump thread ,原因是dump thread 承担了两份不同且又十分频繁的任务:传送binlog 给slave ,还需要等待slave反馈信息,而且这两个任务是串行的,dump thread 必须等待 slave 返回之后才会传送下一个 events 事务。dump thread 已然成为整个半同步提高性能的瓶颈。在高并发业务场景下,这样的机制会影响数据库整体的TPS .

wKiom1jkwxzDY12cAABrxUnGYaQ437.png-wh_50

图:Without ACK receiving thread

为了解决上述问题,在5.7版本的semi sync 框架中,独立出一个 ack collector thread ,专门用于接收slave 的反馈信息。这样master 上有两个线程独立工作,可以同时发送binlog 到slave ,和接收slave的反馈。

wKioL1jkwzCQqvQBAABoY5jDqZw156.jpg-wh_50

图:With ACK receiving thread

3 性能提升控制主库接收slave 写事务成功反馈数量

MySQL 5.7新增了rpl_semi_sync_master_wait_slave_count参数,可以用来控制主库接受多少个slave写事务成功反馈,给高可用架构切换提供了灵活性。

如图所示,当count值为2时,master需等待两个slave的ack

wKiom1jkw0XT5R4LAAAkhCEJay4736.jpg-wh_50

4 性能提升

Binlog 互斥锁改进

旧版本半同步复制在主提交binlog的写会话和dump thread读binlog的操作都会对binlog添加互斥锁,导致binlog文件的读写是串行化的,存在并发度的问题。

wKioL1jkw1WiaRGFAAA6ZFU3CiI138.jpg-wh_50

MySQL 5.7对binlog lock进行了以下两方面优化

1.移除了dump thread对binlog的互斥锁

2.加入了安全边际保证binlog的读安全

wKioL1jkw2DhOmEKAACNn98HPWA858.png-wh_50

5 性能提升组提交

5.7引入了新的变量slave-parallel-type,其可以配置的值有:

DATABASE (5.7之前默认值),基于库的并行复制方式;LOGICAL_CLOCK (5.7新增值),基于组提交的并行复制方式; 

MySQL 5.6版本也支持所谓的并行复制,但是其并行只是基于DATABASE的,也就是基于库的。如果用户的MySQL数据库实例中存在多个DATABASE ,对于从机复制的速度的确可以有比较大的帮助,如果用户实例仅有一个库,那么就无法实现并行回放,甚至性能会比原来的单线程更差。

 

MySQL5.7中增加了一种新的并行模式:为同时进入COMMIT阶段的事务分配相同的序列号,这些拥有相同序列号的事务在备库是可以并发执行的。

MySQL 5.7真正实现的并行复制,这其中最为主要的原因就是slave服务器的回放与主机是一致的即master服务器上是怎么并行执行的slave上就怎样进行并行回放。不再有库的并行复制限制,对于二进制日志格式也无特殊的要求(基于库的并行复制也没有要求)。

 

因此下面的序列中可以并发的序列为(其中前面一个数字为last_committed ,后面一个数字为sequence_number ):

trx1 1…..2

trx2 1………….3

trx3 1…………………….4

trx4        2……………………….5

trx5               3…………………………..6

trx6                     3………………………………7

trx7                            6………………………………..8 

备库并行规则:当分发一个事务时,其last_committed 序列号比当前正在执行的事务的最小sequence_number要小时,则允许执行。

因此,

a)trx1执行,last_commit<2的可并发,trx2, trx3可继续分发执行

b)trx1执行完成后,last_commit < 3的可以执行, trx4可分发

c)trx2执行完成后,last_commit < 4的可以执行, trx5, trx6可分发

d)trx3、trx4、trx5完成后,last_commit < 7的可以执行,trx7可分发


综上所述:

我们认为MySQL 5.7版对Loss-Less半同步复制技术的优化,使得其成熟度和执行效率都得到了质的提高。我们建议在使用MySQL 5.7作为生产环境的部署时,可以使用半同步技术作为高可用与读写分离方案的数据复制方案。


    

资料转载于:http://sanwen.net/a/iogoybo.html