Writeset

server/2024/9/23 15:27:45/

优质博文:IT-BLOG-CN

MySQLWriteSet功能主要用于增强复制的并发性和一致性,特别是在主从复制环境中。WriteSetMySQL 5.7引入的一个特性,主要用于解决复制过程中可能出现的写冲突问题。

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_22">三、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-5.7.22之后的版本小本子就是它生来就有的。

只要在master上新增两个参数开启writeSet

binlog_transaction_dependency_tracking  = WRITESET                 #    COMMIT_ORDER          
transaction_write_set_extraction        = XXHASH64
binlog_transaction_dependency_history_size = 500000

binlog_transaction_dependency_tracking这个参数用于配置二进制日志中事务依赖关系的跟踪方式。它的主要目的是提高从库的并行复制能力。可选值:
【1】COMMIT_ORDER:基于提交顺序的事务依赖跟踪。这是默认值,表示从库按照主库上事务的提交顺序来执行事务。
【2】WRITESET:基于写集的事务依赖跟踪。启用这个选项后,MySQL会生成每个事务的写集,并在从库上进行冲突检测,以允许并行执行不冲突的事务。
【3】WRITESET_SESSION:基于写集的事务依赖跟踪,但在会话级别进行。与WRITESET类似,但冲突检测仅在同一会话内进行。

transaction_write_set_extraction这个参数用于配置写集提取的算法。写集提取是生成事务写集的过程,主要用于冲突检测。可选值:
【1】OFF:禁用写集提取。这是默认值。
【2】XXHASH64:使用XXHASH64算法进行写集提取。XXHASH64是一种快速的非加密哈希算法,适用于高性能场景。

binlog_transaction_dependency_history_size是内存中保存的做冲突检测的数据行数量的上限值,该值越大,保存的数据行越多,事务间冲突检测后并发度越高。

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

std::set<uint64> write_set_unique;

集合中的每一个元素都是hash值,这个hash值和我们的transaction_write_set_extraction参数指定的算法有关,其来源就是行数据的主键和唯一键。每行数据包含了两种格式:
【1】字段值为二进制格式
【2】字段值为字符串格式

四、实现细节

【1】生成WriteSet 当一个事务在主库上提交时,MySQL会扫描事务中的所有写操作(如INSERTUPDATEDELETE),并将这些操作涉及的键生成一个WriteSet

假设我们有一个简单的事务,它在一个表users上执行了一些写操作:

START TRANSACTION;
INSERT INTO users (id, name) VALUES (1, 'Alice');
UPDATE users SET name = 'Bob' WHERE id = 2;
DELETE FROM users WHERE id = 3;
COMMIT;

在这个事务中,涉及的写操作包括一个插入操作、一个更新操作和一个删除操作。MySQL会生成一个WriteSet来表示这些操作涉及的键。

WriteSet示例:假设users表的主键是id,那么生成的WriteSet可能会包含以下信息:

INSERT 操作:插入了 id = 1 的记录。
UPDATE 操作:更新了 id = 2 的记录。
DELETE 操作:删除了 id = 3 的记录。

简化后的WriteSet可以表示为:

WriteSet = { (users, id, 1), (users, id, 2), (users, id, 3) }
WriteSet = { (users, id, 1), (users, id, 2), (users, id, 3) }

这里的(users, id, 1)表示在users表中主键为1的记录。

在实际实现中,WriteSet可能会使用更复杂的数据结构和算法来存储和处理这些信息。例如,MySQL可能会使用哈希表或其他高效的数据结构来存储这些键,并使用哈希算法(如XXHASH64)来生成键的哈希值。

【2】传播WriteSet 生成的WriteSet会随着二进制日志binlog一起传播到从库。在从库上,MySQL会解析这些日志并提取出WriteSet

【3】冲突检测和处理: 从库在执行事务前,会检查当前事务的WriteSet是否与正在执行的其他事务的WriteSet有冲突。如果有冲突,当前事务会被推迟执行,直到冲突消除。

冲突检测:当从库接收到这个事务时,它会使用WriteSet来进行冲突检测。假设从库上有另一个事务正在执行,它的WriteSet是:

WriteSet = { (users, id, 2), (users, id, 4) }

从库会检测两个WriteSet是否有交集。在这个例子中,两个WriteSet都有 (users, id, 2),说明存在写冲突。因此,从库会推迟执行这个事务,直到冲突消除。

WriteSet_99">五、WriteSet实践

我们要执行的目标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);

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

last_committed(组号)sequence_num(组内id)SQL语句
11create database tempdb
22create table person(id int not null auto_increment primary key,name int)
33insert into person(name) values(1)
44insert into person(name) values(2)
55insert into person(name) values(3)
66insert into person(name) values(5)

write_set的对“组提交”优化后的情况

last_committed(组号)sequence_num(组内id)SQL语句
11create database tempdb
22create table person(id int not null auto_increment primary key,name int)
33insert into person(name) values(1)
34insert into person(name) values(2)
35insert into person(name) values(3)
36insert into person(name) values(5)

可以看到各个insert是可以并行执行的,所以它们被分到了同个组last_committed相同。

last_committedsequence_number这两个值在binlog里面记着就有,我在解析binlog的时候习惯使用如下选项

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

http://www.ppmy.cn/server/120851.html

相关文章

知乎:从零开始做自动驾驶定位; 注释详解(一)

消息发布与订阅 目录 消息发布与订阅缓冲区机制CMakeLists文件规划*注释参考链接 1. 消息发布与订阅 消息的订阅和发布&#xff0c;这是每个ROS工程都必备的东西&#xff0c;我们常见的使用方式是在main函数中定义subscriber和publisher&#xff0c;每个subscriber会有一个cal…

等保测评与网络安全等级划分

等保测评与网络安全等级划分的关系 等保测评&#xff08;信息安全等级保护测评&#xff09;是根据国家信息安全等级保护制度&#xff0c;对信息系统进行安全等级评定的活动。它旨在确保信息系统能够抵御各种安全威胁&#xff0c;保障信息的机密性、完整性和可用性。网络安全等级…

旷视轻量化网络shufflenet算法解读

目录 预备知识 1. 回顾MobileNet V1的核心思想---深度可分离卷积 2.ShuffleNet主要有两个创新点 2.1 分组卷积与11分组卷积 2.2 channel Shuffle&#xff08;通道重排&#xff09; 2.3 通道重排过程 3. ShuffleNet网络结构 3.1 ShuffleNet unit 3.2 不同分组数的Shu…

Real-Time Linux 合并到内核主线

在长达 20 年之后&#xff0c;Real-Time Linux(PREEMPT_RT)合并到内核主线。 从 Linux 6.12 开始&#xff0c;所有发行版都将包含实时 Linux 代码。 这意味着 Linux 将开始运行在更多任务关键设备和工业硬件上。实时操作系统对时间限制非常严格&#xff0c;需要确保关键任务在…

智能BI项目第一期

该项目是全程跟着鱼皮,还未进行功能扩展。为了方便日后复习,打算将一些重要的步骤记录下来。 项目概述 BI:即商业智能:Business Intelligence 过去 需要手动导入数据、选择要分析的字段和图表&#xff0c;并由专业的数据分析师完成分析&#xff0c;最后得出结论。 现在 用户…

【测试】——Selenium API (万字详解)

&#x1f4d6; 前言&#xff1a;本文详细介绍了如何利用Selenium进行Web自动化测试&#xff0c;包括定位元素&#xff08;如cssSelector和xpath&#xff09;、常用操作函数&#xff08;如点击、输入等&#xff09;、窗口管理、键盘鼠标事件和浏览器导航&#xff0c;以及处理弹窗…

基于SpringCloud的能源管理系统-能源管理平台源码-双碳平台源码-能管管理系统源码

一、介绍 基于SpringCloud的能管管理系统-能源管理平台源码-能源在线监测平台-双碳平台源码-SpringCloud全家桶-能管管理系统源码 二、软件架构 二、功能介绍 三、数字大屏展示 四、数据采集原理 五、软件截图

【Linux】指令和权限的这些细节,你确定都清楚吗?

&#x1f680;个人主页&#xff1a;奋斗的小羊 &#x1f680;所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 前言&#x1f4a5;一、Linux基本指令&#x1f4a5;1.1 mv 指令&#x1f4a5;1.2 cat 指令&#x1f4a5;…