MySQL:MGR 学习(2):Write set(写集合)的写入过程


水平有限,有误请谅解。

源码版本5.7.22

前文 >中已经说明了Write set的生成过程,但是Write set是需要封装如下Transaction_context_log_event中进行广播到其他节点进行认证的。本文就描述Write set的写入和广播的过程。

如前文所描述,整个事物的Write set在函数binlog_log_row中生成,对于5.7来讲每一行的每个唯一键都会生成一个Write set(但是咨询宋利兵老师得知8.0唯一键不会再记录Write set了),每个Write set实际上是一个8字节的uint64类型其通过hash函数生成,并且在Rpl_transaction_write_set_ctx存储了一个vector数组和一个set集合来分别存储,如果修改的行比较多那么可能需要一个更多内存来存储这些hash值,虽然8字节比较小,但是如果是大事物上千万的表在一个事物里面做修改那么内存可能消耗会上百兆。如下图是事物执行期间(commit之前)最终形成的Write set内存空间示意图。

image.png

在事物执行期间会生成map event/query event/dml event等并且会源源不断的写入到binlog cache中,同时会将Write set 不断的写入到Rpl_transaction_write_set_ctx保存在内存中,这些逻辑都在binlog_log_row中。但是Transaction_context_log_event的生成却是在commit的时候,具体的位置是在MYSQL_BIN_LOG::prepare之后但是在MYSQL_BIN_LOG::ordered_commit之前,显而易见这个时候的binlog event还在bing cache中,还没有写入binlog file中。所以MGR的事物全局认证的动作是发生在binlog event落地之前。下面是这个栈帧:

下面是我通过对源码浅显的理解得出过程:

1、获取当前的binlog cache内容记录为cache_log,这些就是已经在执行阶段生成map/query/dml event等。

2、生成一个新的IO_CACHE作为临时存储为cache,目的在于存储。Transaction_context_log_event 和Gtid_log_event。

3、将cache_log类型转换为READ类型同时初始化各种辅助类容如偏移量。

4、初始化Transaction_context_log_event 。

5、扫描Rpl_transaction_write_set_ctx中的write_set_unique 集合的内容,并且将其存储到Transaction_write_set 定义的内存空间中write_set中,注意这里只是用到了集合没用到数组。这里也就是进行Write set的一个拷贝而已其考到write_set临时变量中。

6、将write_set内容填充到Transaction_context_log_event中,整个过程还会做base64的转换,最终填充到event的是base64格式的Write set类容。完成后析构write_set来临时变量

7、 将Transaction_context_log_event写入到第二步定义的cache中。

8、生成Gtid_log_event,只是做一些初始化动作,Gtid并没有生成。

9、将Gtid_log_event写入到第二步定义的cache中。

10、通过cache+cache_log的总和来对比

group_replication_transaction_size_limit

设置的值,也就是判断整个事物的binlog event是否操作了参数设置。

11、将cache类型转换为READ类型同时初始化各种辅助类容如偏移量。

12、将cache和cache_log分别写入到到transaction_msg中。

13、流控相关,没仔细看,如果有机会学习流控机制在仔细学习。

14、gcs_module负责发送transaction_msg到各个节点

15、挂起等待事物认证的结果。

那么整个过程大概就是:

经过hash的Write set (集合)->拷贝到write_set变量(类数组)->通过base64算法写入到Transaction_context_log_event ->合并其他binlog event到transact开发云主机域名ion_msg->gcs_module广播transaction_msg到其他节点->等待认证结果

作者微信

相关推荐: PHP Mysql support: 是mysql 还是mysqlnd?

您正在使用其中一个备用存储库安装现代版本的php,突然间您遇到了一个令人困惑的选择。你想在php程序中支持mysql(mysqli或PDO-mysql)。你会怎么选择? 首先,您可能应该使用PDO。与mysqli相比,它只是一个更干净的数据库界面,如果你使用像…

免责声明:本站发布的图片视频文字,以转载和分享为主,文章观点不代表本站立场,本站不承担相关法律责任;如果涉及侵权请联系邮箱:360163164@qq.com举报,并提供相关证据,经查实将立刻删除涉嫌侵权内容。

Like (0)
Donate 微信扫一扫 微信扫一扫
Previous 06/05 12:01
Next 06/05 12:01

相关推荐