June 12 2017

LOGICAL_CLOCK

LOGICAL_CLOCK
基于组提交(LOGICAL_CLOCK)的并行复制
MySQL5.7通过参数–slave-parallel-type=type进行控制并行复制的方式,可选值有DATABASE(默认)和LOGICAL_CLOCK
MySQL5.6版本之前,Slave服务器上有两个线程:I/O线程和SQL线程。I/O线程负责接收二进制日志(更准确的说是二进制日志的event),SQL线程进行回放二进制日志。

MySQL5.6的并行复制是基于库的(database),开启并行复制SQL线程就变为了coordinator线程,coordinator线程主要负责以前两部分的内容:判断可以并行执行,那么选择worker线程执行事务的二进制日志;判断不可以并行执行,如该操作是DDL,亦或者是事务跨schema操作,则等待所有的worker线程执行完成之后,再执行当前的日志。对于有多个数据库的实例,开启并行的执行SQL,对从库能有较大的提升。但对单个库,开启多线程复制,性能可能比单线程还差。

MySQL5.7的并行复制是基于组提交(LOGICAL_CLOCK),即master服务器上是怎么并行执行的slave上就怎样进行并行回放,很好的解决了主从复制延迟的问题。主要思想是一个组提交的事务都是可以并行回放到从,原理是基于锁的冲突检测,因为这些事务都已进入到事务的prepare阶段,则说明事务之间没有任何冲突(否则就不可能提交)。若将slave_parallel_workers设置为0,则MySQL 5.7退化为原单线程复制,但将slave_parallel_workers设置为1,则SQL线程功能转化为coordinator线程,但是只有1个worker线程进行回放,也是单线程复制。然而,这两种性能却又有一些的区别,因为多了一次coordinator线程的转发,因此slave_parallel_workers=1的性能反而比0还要差。

总的来说就是:并发线程执行不同的事务只要在同一时刻能够commit(说明线程之间没有锁冲突),那么master节点就可以将这一组的事务标记并在slave机器上安全的进行并发重放主库提交的事务。所以尽可能的使所有线程能在同一时刻提交可以,可以极大的提高slave机器并发执行事务的数量使主备数据同步。

相关参数:

binlog_group_commit_sync_delay:表示binlog提交后等待延迟多少时间再同步到磁盘,单位是微秒,默认0,不延迟。设置延迟可以让多个事务在用一时刻提交,提高binlog组提交的并发数和效率,从而提高slave的吞吐量。

binlog_group_commit_sync_no_delay_count:表示在等待上面参数超时之前,如果有足够多的事务,则停止等待直接提交。单位是事务数,默认0。

上面提到一个组提交的事务都是可以并行回放到从,那么如何知道事务是否在一组中?在MySQL 5.7版本中,其设计方式是将组提交的信息存放在GTID中。那么如果用户没有开启GTID功能,即将参数gtid_mode设置为OFF呢?故MySQL 5.7又引入了称之为Anonymous_Gtid的二进制日志event类型,如:
这里Gtid有自己类型的event。这意味着在MySQL 5.7版本中即使不开启GTID,每个事务开始前也是会存在一个Anonymous_Gtid,而这GTID中就存在着组提交的信息。通过上述的SHOW BINLOG EVENTS,我们并没有发现有关组提交的任何信息。但是通过mysqlbinlog工具,用户就能发现组提交的内部信息:

[mysqld]
# * slave
slave_parallel_workers = 4 ###并行复制的线程数
slave_parallel_type = LOGICAL_CLOCK ###并行复制的类型,默认database



Copyright 2019. All rights reserved.

Posted 2017年6月12日 by ucjmh in category "mysql

Leave a Reply

Your email address will not be published. Required fields are marked *