MySQL行级别并行复制能并行应用多少个binlog group?

前两天,无意间看到了林晓斌(丁奇)的一篇文章(详见文末参考链接的第一个),突发好奇心,想从MySQL暴露出来的一些信息上着手,看看能不能直观地看到MySQL 5.7的并行复制到底可以同时执行多少个binlog group(last_committed)的事务,经过一番折腾,将验证过程整理成这篇文章分享给大家。测试验证过程中,使用了两个MySQL版本,如下:

  • MySQL 5.7.22:sysbench加压,然后在从库中查询information_schema.innodb_trx、performance_schema.events_transactions_current、performance_schema.replication_applier_status_by_worker 三张表中的数据,反复操作,发现并没有可靠数据能满足要求。

  • MySQL 8.0.17:sysbench加压,然后在从库中查询performance_schema.replication_applier_status_by_worker 表,发现该表相比之前的版本新增了一个字段看起来比较可靠(这里先卖个关子,具体哪个字段,请大家从下文中寻找吧)。

No.1 环  境

数据库版本:MySQL 5.7.22、MySQL 8.0.17

  • 复制拓扑:一主两从

数据库关键参数:

  • 主库:

    binlog_transaction_dependency_tracking=COMMIT_ORDER

  • 主从库:双一、binlog_order_commits=ON、slave_preserve_commit_order=ON

  • 从库:双TABLE,slave_parallel_workers=32,slave_parallel_type=LOGICAL_CLOCK

sysbench版本:sysbench 1.0.9

  • 对主库使用32线程加oltp压力

  • 测试基础数据量:8张500W的表

操作系统版本:CentOS Linux release 7.2.1511 (Core)

文件系统:xfs

IO调度策略:deadline

PS:以下测试数据均为MySQL 8.0.17,由于MySQL 5.7.22的测试数据并不是那么可靠(本人观点),所以本文中并未列出。

No.2 预  热

MySQL行级别的并行复制,是在MySQL 5.7及其之后的版本中引入的,在MySQL 5.6中只支持库级别的并行复制,在MySQL 5.5及其更早的版本中只支持单线程复制。

关于MySQL行级别的并行复制原理,我们也许经常会听到如下说法:

  • 简单点的:从库中的协调器线程根据Gtid_log_event和Anonymous_gtid_log_event中记录的last_committed值做并行分发,相同的last_committed值的事务就可以并行应用。

  • 复杂点的:主库在做并行事务提交时,处于prepare状态的事务都可以在从库并行应用,因为他们不存在锁冲突。

    * 主库侧:在提交事务时,对每个事务定义其lock interval,并记录到binlog中。使用last_committed表示事务lock interval的起始点,它是在事务进入prepare阶段之后,进入binlog flush队列之前获取的当时commit队列(这里指的是事务提交的flush、sync、commit三个队列中的commit队列)中所有事务的最大sequence_number(为什么要从commit队列里获取,而不是从已提交完成的事务中获取呢?因为提交完成的事务锁已经释放,无法判断有没有锁冲突);使用sequence_number表示事务lock interval的结束点,它是在事务进入binlog flush队列之后从当时正在使用的binlog file的事务计数器中获取值(每个binlog file都会将计数器重置)。

    * 从库侧:协调器线程根据last_committed做分发,只要last_committed和sequence_number组成的lock interval锁范围重叠的事务,就可以并行应用(可以分发)。具体实现上,在MySQL内部定义了一个last_lwm_timestamp变量,用来记录所有回放事务中已经提交完成事务的timestamp(sequence_number)的low-water-mark。low-water-mark对应的事务已经提交,且该事务之前的事务(seqno小于low-water-mark的事务)都已经提交。当协调器线程读取到一个事务的last_committed值时,判断该事务的last_committed值是否小于等于low-water-mark值,如果是,则协调器线程就可以将其分发给worker线程(具体是否分发还需要看是否有worker线程处于空闲状态,如果没有worker线程处于空闲,协调器线程需要等待空闲的worker线程),否则,协调器线程不能将该事务分发给worker线程,需要进行等待。

    * 从库侧并行分发策略的逻辑图解:假设下图中的L代表lock interval的开始,C代表lock interval的结束。

下面,我们一起来看看,除了撸源码总结并行复制原理之外,怎么通过MySQL暴露出来的一些信息来查看并行复制的踪迹。

No.3 揭  底

主库停止任何写压力,并确定从库无延迟。

root@localhost : (none):28: > show slave status\G
*************************** 1. row ***************************
               Slav
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值