第16节 基于WRITESET的并行复制方式

  • 时间:
  • 浏览:14
  • 来源:大发快3官方网址—大发快3APP下载

大家通过前面的分析都可不能否发现愿因你你这俩值越大这样 在Writeset历史MAP中能容下的元素也就越多,生成的last commit就愿因更加精确(更加小),从库并发的下行速率 也就愿因越高。为什么在么在让大家时需注意设置越大相应的内存需求也就越高了。

大家使用如下表:

它们是在5.7.22才引入的。

实际上Writeset是三个集合,使用的是C++ STL中的set容器,在类Rpl_transaction_write_set_ctx中涵盖了如下定义:

注意:这里显示的?是分隔符

你你这俩行数据一共会生成三个元素分别为:

愿因从库这样 延迟,则不时需考虑你你这俩法子,即便有延迟大家也应该先考虑或多或少方案。第28节大家愿因描述有哪几个愿因延迟的愿因。

为了更直观的观察到你你这俩数据格式,都可不能否使用debug的法子获取。下面大家来看一下。

其次内存中还维护三个叫做m_writeset_history_start的值,用于记录Writeset的历史MAP中最早事务的seq number。愿因Writeset的历史MAP满了就会清理你你这俩历史MAP为什么在么在让将本事务的seq number写入m_writeset_history_start,作为最早的seq number。底下会都看对于事务last commit的值的修改总是从你你这俩值开使为什么在么在让进行比较判断修改的,愿因在Writeset的历史MAP中这样 找到冲突这样 直接设置last commit为你你这俩m_writeset_history_start值即可。下面是清理Writeset历史MAP的代码:

有了前面的基础,大家就很容易解释你你这俩大大问题 了。其主要愿因要是 Writeset的历史MAP的居于,假如有一天哪几个事务修改的行这样 冲突,也要是 主键/唯一键不相同,这样 在基于WRITESET的并行复制法子中就都可不能否居于你你这俩大大问题 ,为什么在么在让愿因binlog_transaction_dependency_tracking设置为WRITESET_SESSION则不需要出现 你你这俩大大问题 。

注意:本文分为正文和附件两主次,是否图片格式,愿因正文有图片不清晰都可不能否将附件的图片保存到本地查看。

第16节开使

更多主从同步相关都可不能否参考我的《深入理解MySQL主从原理 32节》专栏:

为什么在么在让这样 主键都可不能否使用唯一键,愿因都这样 得话WRITESET设置就不需要生效回退到老的ORDER_COMMIT法子。

根据binlog_transaction_dependency_tracking取值的不同会做进一步的避免,如下:

最终哪几个数据会通过hash算法后写入到Writeset中。

基于COMMIT_ORDER的并行复制都可不能否在有压力的请况下才愿因会形成一组,压力不大的请况下在从库的并行度暂且会高。为什么在么在让基于WRITESET的并行复制目标要是 在ORDER_COMMIT的基础上再尽愿因的降低last commit,另三个在从库获得更好的并行度(即便在主库串行执行的事务在从库都可不能否并行应用)。它使用的法子要是 通过扫描Writeset中的每三个元素(行数据的hash值)在三个叫做Writeset的历史MAP(行数据的hash值和seq number的三个MAP)中进行比对,寻找是是是否冲突的行,为什么在么在让做相应的避免,底下大家会完整版描述你你这俩行为。愿因要使用你你这俩法子大家时需在主库设置如下三个参数:

前面说过你你这俩法子要是 在WRITESET的基础上继续避免,实际上它的含义要是 同三个session的事务不允许在从库并行回放。代码很简单,如下:

分解为:

解析同上

大家都可不能否都看这是C++ STL中的map容器,它包涵盖一个元素:

在Innodb层修改一行数据日后 会将这底下的格式的数据进行hash后写入到Writeset中。都可不能否参考函数add_pke,底下我也会以伪代码的法子给出主次流程。

分解为:

集合中的每三个元素是否hash值,你你这俩hash值和大家的transaction_write_set_extraction参数指定的算法有关,其来源要是 行数据的主键和唯一键。每行数据涵盖了你你这俩格式:

解析同上

前一节大家讨论了基于ORDER_COMMIT的并行复制是怎样才能生成last_commit和seq number的。实际上基于WRITESET的并行复制法子要是 在ORDER_COMMIT的基础上对last_commit做更进一步避免,暂且影响原有的ORDER_COMMIT逻辑,为什么在么在让愿因要回退到ORDER_COMMIT逻辑非常方便。都可不能否参考MYSQL_BIN_LOG::write_gtid函数。

这里介绍一下整个避免的过程,假设如下:

整个过程开使。last commit由日后 的125降低为120,目的达到了。实际上大家都可不能否看出Writeset历史MAP就大慨保存了一段时间以来修改行的快照,愿因保证本次事务修改的数据在这段时间内这样 冲突,这样 显然是都可不能否在从库并行执行的。last commit降低后如下图(图16-2,高清原图涵盖在文末原图中):

愿因这样 主键愿因唯一键这样 下面得话将被触发:

为什么在么在让大家在生成last commit会判断你你这俩设置如下:

大家先来看三个截图,仔细观察其中的last commit:

实际上在函数add_pke中就会判断是是是否主键愿因唯一键,愿因居于唯一键也是都可不能否。Writeset中存储了唯一键的行数据hash值。参考函数add_pke,下面是判断:

每行数据的具体格式为:

它是按照Writeset的hash值进行排序的。

初始化请况如下图(图16-1,高清原图涵盖在文末原图中):

大家到这里愿因讨论了Writeset是哪几个,也愿因说过愿因要降低last commit的值大家时需通过对事务的Writeset和Writeset的历史MAP进行比对,看是是否冲突都可不能否决定降低为哪几个值。这样 时需在内存中保存一份另三个的三个历史MAP才行。在源码中使用如下法子定义:

大家都可不能否都看其中的last commit看起来是乱序的,你你这俩请况在基于COMMIT_ORDER 的并行复制法子下是不愿因出现 的。实际上它要是 大家前面说的基于WRITESET的并行复制再尽愿因降低的last commit的结果。你你这俩请况会在MTS从库获得更好的并行回放效果,第19节愿因完整版解释并行判定的标准。

大家写入一行数据:

下面是一段伪代码,用来描述你你这俩生成过程:

这段描述的代码对应:

为什么在么在让时需注意三个事务的所有的行数据的hash值是否写入到三个Writeset。愿因修改的行比较多这样 愿因时需更多内存来存储哪几个hash值。我我觉得8字节比较小,为什么在么在让愿因三个事务修改的行要是 ,这样 还是时需消耗较多的内存资源的。

本参数默认值为21000。代表的是大家说的Writeset历史MAP中元素的个数。如前面分析的Writeset生成过程中修改一行数据愿因会生成多个HASH值,为什么在么在我应该 你这俩值还都可不能否完整版在等待于修改的行数,都可不能否理解为如下:

好了到这里大家明白了基于WRITESET的并行复制法子的优点,为什么在么在让它是否明显的缺点如下:

整个逻辑就在函数Writeset_trx_dependency_tracker::get_dependency中,下面是或多或少关键代码,代码稍多:

经过你你这俩操作后,大家发现你你这俩请况最后last commit恢复成了ORDER_COMMIT的法子。