加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 站长学院 > MySql教程 > 正文

MySQL 8.0新特性:彻底解决困扰运维的复制延迟问题,你信吗?

发布时间:2018-09-19 06:51:03 所属栏目:MySql教程 来源:雁南归
导读:副标题#e# 技术沙龙 | 邀您于8月25日与国美/AWS/转转三位专家共同探讨小程序电商实战 MySQL 8.0可以说是MySQL发展历史上里程碑式的一个版本,包括了多个重大更新,目前Generally Available版本已经已经发布,在此将介绍8.0版本中引入的一个重要的新特性基于

可以看到,由于是在一个Session中,这些操作按着串行的顺序有着不同的 last_committed,正常情况下,这些BinlogEvent应该在从机上同样以串行的方式回放。我们看一下在MGR集群中的RelayLog情况:

  1. # mysqlbinlog mysql-relay.N | grep -e last_  |  sed -e 's/server id.*last/[...] last/' -e 's/.rbr_only.*/ [...]/'  
  2. #180106 19:31:36 [...] last_committed=0 sequence_number=0 [...]  
  3. #180106 19:31:36 [...] last_committed=1 sequence_number=2 [...] -- CREATE DB  
  4. #180106 19:31:36 [...] last_committed=2 sequence_number=3 [...] -- CREATE TB  
  5. #180106 19:31:36 [...] last_committed=3 sequence_number=4 [...] -- INSERT a  
  6. #180106 19:31:36 [...] last_committed=3 sequence_number=5 [...] -- INSERT b  
  7. #180106 19:31:36 [...] last_committed=3 sequence_number=6 [...] -- INSERT c 

有趣的是,在Secondary节点的RelayLog中, 这些事务有着相同的last_committed值,也就是说这些事务在MGR集群中,回放的时候可以以并行的方式回放。

MGR中,使用的正是WriteSet技术检测不同事务之间是否存在写冲突,并重规划了事务的并行回放,这一技术在8.0中被移到了Binlog生成阶段,并采用到了主从复制的架构中。

四、MySQL 8.0中的并行复制

说了这么多,终于讲到了MySQL 8.0 ,通过以上描述,读者应该对MySQL 8.0中并行复制的优化的原理有了一个大致的轮廓。通过基于WriteSet的冲突检测,在主机上产生Binlog的时候,不再基于组提交,而是基于事务本身的更新冲突来确定并行关系。

1、相关的MySQL参数

在MySQL 8.0中,该版本引入了参数binlog_transaction_depandency_tracking用于控制如何决定事务的依赖关系。

该值有三个选项:

  • 默认的COMMIT_ORDERE表示继续使用5.7中的基于组提交的方式决定事务的依赖关系;
  • WRITESET表示使用写集合来决定事务的依赖关系;
  • 还有一个选项WRITESET_SESSION表示使用WriteSet来决定事务的依赖关系,但是同一个Session内的事务不会有相同的last_committed值。

在代码实现上,MySQL采用一个vector<uint64>的变量存储已经提交的事务的HASH值,所有已经提交的事务的所修改的主键和非空的UniqueKey的值经过HASH后与该vector中的值对比,由此来判断当前提交的事务是否与已经提交的事务更新了同一行,并以此确定依赖关系。该向量的大小由参数binlog_transaction_dependency_history_size控制,取值范围为1-1000000 ,初始默认值为25000。

同时参数transaction_write_set_extraction控制检测事务依赖关系时采用的HASH算法有三个取值OFF|XXHASH64|MURMUR32, 如binlog_transaction_depandency_tracking取值为WRITESET或WRITESET_SESSION,那么该值取值不能为OFF,且不能变更。

2、WriteSet 依赖检测条件

WriteSet是通过检测两个事务是否更新了相同的记录来判断事务能否并行回放的,因此需要在运行时保存已经提交的事务信息以记录历史事务更新了哪些行。记录历史事务的参数为binlog_transaction_dependency_history_size。该值越大可以记录更多的已经提交的事务信息,不过需要注意的是,这个值并非指事务大小,而是指追踪的事务更新信息的数量。在开启了WRITESET或WRITESET_SESSION后,MySQL按以下的方式标识并记录事务的更新。

如果事务当前更新的行有主键(Primary Key),则将HASH(DB名、TABLE名、KEY名称、KEY_VALUE1、KEY_VALUE2……)加入到当前事务的vector write_set中。

如果事务当前更新的行有非空的唯一键 (Unique Key Not NULL), 同样将 HASH(DB名、TABLE名、KEY名、KEY_VALUE1)……加入到当前事务的write_set中。

如果事务更新的行有外键约束( FOREIGN KEY )且不为空,则将该外键信息与VALUE 的HASH加到当前事务的 write_set 中;如果事务当前更新的表的主键是其它某个表的外键,则设置当前事务 has_related_foreign_key = true;如果事务更新了某一行且没有任何数据被加入到 write_set 中,则标记当前事务 has_missing_key = true。

在执行冲突检测的时候,先会检查has_related_foreign_key和has_missing_key , 如果为true,则退到COMMIT_ORDER模式;否则,会依照事务的write_set中的HASH值与已提交的事务的write_set进行比对。

如果没有冲突,则当前事务与最后一个已提交的事务共享相同的last_commited,否则将从全局已提交的write_set中删除那个冲突的事务之前提交的所有write_set,并退化到COMMIT_ORDER计算last_committed 。

在每一次计算完事务的last_committed值以后,需要去检测当前全局已经提交的事务的write_set是否已经超过了binlog_transaction_dependency_history_size设置的值,如果超过,则清空已提交事务的全局write_set。

从检测条件上看,该特性依赖于主键和唯一索引,如果事务涉及的表中没有主键且没有唯一非空索引,那么将无法从此特性中获得性能的提升。除此之外,还需要将Binlog格式设置为Row格式。

3、性能提升

MySQL High Availability对开启了WriteSet的复制性能做了测试,这里直接将测试结果搬运过来,有兴趣的可以直接访问原博客。

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读