浅析MySQL的WriteSet并行复制

 更新时间:2020年12月01日 11:21:23   作者:蒋乐兴的技术随笔  
这篇文章主要介绍了浅析MySQL的WriteSet并行复制的相关资料,帮助大家更好的理解和学习MySQL,感兴趣的朋友可以了解下

【历史背景】

  岁月更迭中我已经从事MySQL-DBA这个工作三个年头,见证MySQL从“基本可用”,“边缘系统可以用MySQL”,“哦操!你怎么不用MySQL”;

  正所谓!“一个数据库的境遇既取决于历史的进程,取决于它的自我奋斗!”,关于“历史的进程”在此不表,关于“自我奋斗”这里也只想谈一下并行复制的几个关键时间结点

  总的来说MySQL关于并行复制到目前为止经历过三个比较关键的时间结点“库间并发”,“组提交”,“写集合”;真可谓是江山代有人才出,前浪死在沙滩上;总的来说就后面的比前面的不知道高到哪里去了!

【库间并发】

  库间并发的理论依据是这样的 ---- 一个实例内可能会有多个库(schema),不同的库之间没有什么依赖关系,所以在slave那边为每一个库(schema)单独起一个SQL线程,这样就能通过多线程并行复制的方式来提高主从复制的效率。

  这个理论听起来没问题,但是事实上一个实例也就一个业务库,所以这种库间并发就没什么作用了;也就是说这个方式的适用场景比较少,针对这个不足直到“组提交”才解决!

【组提交】

  组提交的理论依据是这样的 --- 如果多个事务他们能在同一时间内提交,这个就间接说明了这个几个事务锁上是没有冲突的,也是就说他们各自持有不同的锁,互不影响;逻辑上我们几个事务看一个组,在slave以“组”为单位分配给SQL线程执行,这样多个SQL线程就可以并行跑了;而且不在以库为并行的粒度,效果上要比“库间并发”要好一些。

  这个事实上也有一些问题,因为它要求库上要有一定的并发度,不然就有可能变成每个组里面只有一个事务,这样就有串行没什么区别了,为了解决这个问题MySQL提供了两个参数就是希望在提交时先等一等,尽可能的让组内多一些事务,以提高并行复制的效率。

  “binlog_group_commit_sync_no_delay_count” 设置一个下水位,也就是说一个组要凑足多少个事务再提交;为子防止永远也凑不足

  那么多个事务MySQL还以时间为维度给出了另一个参数“binlog_group_commit_sync_delay”这个参数就是最多等多久,超过这个时间长度后就算没有凑足也提交。 

  亲身经历呀! 这两个参数特别难找到合的值,就算今天合适,过几天业务上有点变化后,又可能变的不合适了;如果MySQL能自己达到一个自适应的效果就好了;这个自适用要到WriteSet才完成(WriteSet并不是通过自动调整这两个参数来完成,它采用了完全不同的解决思路)。

【WriteSet】

  WriteSet解决了什么问题?当然是解决了“组提交”的问题啦! 说了和没说一个样,好下面我们来举个例子(比较学院派);假设你第一天更新了id == 1 的那一行,第二天你更新了id == 2 的那一行,第三天有个slave过来同步你的数据啦! 以“组提交”的尿性,这两个更新会被打包到不同的“组”,也就是说会有两个组;由于每个组内只有一个事务,所以逻辑上就串行了,起来! 

  身为DBA的你一可以看出来这两个事实上是可以打包到同一个组里来的,因为他们互不冲突,就算打包到同一个组也不引起数据的不一致。 于是你有两个办法

  办法1): 妹妹你大胆的把“binlog_group_commit_sync_no_delay_count”设置成 2,也就是说一个组至少要包含两个事务,并且把“binlog_group_commit_sync_delay”设置成24小时以上!如果你真的做了,你就可以回家了,你的数据库太慢了(第一条update等了一天),才完成!

  办法2): 叫MySQL用一本小本子记下它最近改了什么,如果现在要改的数据和之前的数据不冲突,那么他们就可以把包到同一个组;还是我们刚才的例子,由于第二天改的值的id==2所以它和第一天的不冲突,那么它完全可以把第二天的更新和第一天的更新打包到同一个组。这样组里面就有两个事务了,在slave第三天回放时就会有一种并行的效果。

  这本小本子这么牛逼可以做大一点吗?当然!binlog_transaction_dependency_history_size 这个参数就小本子的容量了;那我的MySQL有这本小本子吗? 如果你的mysql比mysql-5.7.22新的话,小本子就是它生来就有的。

  也就是说“WriteSet”是站在“组提交”这个巨人的基础之间建立起来的,而且是在master上做的自“适应”打包分组,所以你只要在master上新增两个参数

binlog_transaction_dependency_tracking = WRITESET     # COMMIT_ORDER   
transaction_write_set_extraction  = XXHASH64

理论说完了,下面我们看一下实践。

【WriteSet实践】

   基于WriteSet的并行复制环境怎么搭建我这里就不说了,也就是比正常的“组提交”在master上多加两个参数,不讲了;我这里想直接给出两种并行复制方式下的行为变化。

  1): 我们要执行的目标SQL如下

create database tempdb;
use tempdb;
create table person(id int not null auto_increment primary key,name int);

insert into person(name) values(1);
insert into person(name) values(2);
insert into person(name) values(3);
insert into person(name) values(5);

  2): 看一下组提交对上面SQL的分组情况

  3): 看write_set的对“组提交”优化后的情况

   可以看到各个insert是可以并行执行的,所以它们被分到了同个组(last_committed相同);last_committed,sequence_number,这两个值在binlog里面记着就有,我在解析binlog的时候习惯使用如下选项

mysqlbinlog -vvv --base64-output='decode-rows' mysql-bin.000002  

 【总结】

  WriteSet是在“组提交”方式上建立起来的,一种新的并行复制实现;相比“组提交”来说更加灵活;当然,由于并发度上去了,相比“组提交”WriteSet在性能上会更加好一些,在一些WriteSet没有办法是否冲突时,能平滑过度到“组提交”模式。

以上就是浅析MySQL的WriteSet并行复制的详细内容,更多关于MySQL WriteSet并行复制的资料请关注脚本之家其它相关文章!

相关文章

  • MySQL CPU占用过高的排查指南

    MySQL CPU占用过高的排查指南

    使用关系数据库MySQL版时,如果您的CPU使用率很高或接近100%,会导致数据读写处理缓慢、连接缓慢、删除出现报错等,从而影响业务正常运行,所以本文给大家介绍了MySQL CPU占用过高的排查指南,需要的朋友可以参考下
    2025-08-08
  • MySQL 亿级数据导入导出及迁移笔记

    MySQL 亿级数据导入导出及迁移笔记

    上周被安排做了一个MySQL亿级数据的迁移,特此记录一下,导入和导出是两个过程,本文想详细的介绍一下具体的使用,感兴趣的小伙伴们可以参考一下
    2021-06-06
  • 深入了解MySQL中聚合函数的使用

    深入了解MySQL中聚合函数的使用

    这篇文章主要为大家详细介绍一下MySQL中聚合函数的使用,文中的示例代码讲解详细,对我们学习MySQL有一定帮助,需要的可以参考一下
    2022-07-07
  • innodb引擎redo文件维护方法

    innodb引擎redo文件维护方法

    下面小编就为大家带来一篇innodb引擎redo文件维护方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • mysql8重置root用户密码的完整步骤

    mysql8重置root用户密码的完整步骤

    这篇文章主要给大家分享介绍了关于mysql8重置root用户密码的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • 解决mysql导入还原时乱码的问题

    解决mysql导入还原时乱码的问题

    sql文件,直接记事本方式打开,中文显示正常,还原导入后,发现中文是乱码
    2012-12-12
  • MySQL中处理各种重复的一些方法

    MySQL中处理各种重复的一些方法

    这篇文章主要介绍了MySQL中处理各种重复的一些方法,包括对表和查询结果的重复的一些处理,需要的朋友可以参考下
    2015-05-05
  • mysql异常占用资源排查

    mysql异常占用资源排查

    本文详细介绍了通过MySQL的全局变量检查日志状态,监控连接数及启用和调整慢查询记录,以帮助排查数据库性能问题,感兴趣的可以了解一下
    2025-07-07
  • mysql的group by函数使用方法

    mysql的group by函数使用方法

    MySQL中的GROUP BY子句用于将查询结果按一个或多个列进行分组,通常与聚合函数,实现数据的分组统计,本文给大家介绍mysql的group by函数使用方法,感兴趣的朋友跟随小编一起看看吧
    2025-08-08
  • Mysql数据库中数据的操作CRUD详解

    Mysql数据库中数据的操作CRUD详解

    这篇文章主要介绍了Mysql数据库中数据的操作(CRUD),详细描述对Mysql数据库中数据的操作(CRUD),包括插入、修改、删除数据,还有查询数据,包括where、in、like、ifnull、与或非、order by、聚集函数等,需要的朋友可以参考下
    2025-05-05

最新评论