Writeset

优质博文: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

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实践

我们要执行的目标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.mzph.cn/pingmian/54479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ESP32/ESP8266开发板单向一对多ESP-NOW无线通信

目录 简介读取ESP32/ESP8266接收方Receiver的MAC地址ESP32发送方Sender程序ESP32/ESP8266接收方Receiver程序ESP-NOW通信验证总结 简介 本实验通过ESP-NOW无线通信协议实现ESP32开发板向多个ESP32/ESP 8266开发板发送数据。 读取ESP32/ESP8266接收方Receiver的MAC地址 读取…

Nginx反向代理出现502 Bad Gateway问题的解决方案

&#x1f389; 前言 前一阵子写了一篇“关于解决调用百度翻译API问题”的博客&#xff0c;近日在调用其他API时又遇到一些棘手的问题&#xff0c;于是写下这篇博客作为记录。 &#x1f389; 问题描述 在代理的遇到过很多错误码&#xff0c;其中出现频率最高的就是502&#x…

LabVIEW提高开发效率技巧----代码规范与文档记录

良好的代码规范与文档记录在LabVIEW开发中至关重要。它不仅能够大幅提升开发效率&#xff0c;还为后续的维护和项目交接提供便利。下面将从命名规则、注释标准、功能说明等多个角度&#xff0c;介绍如何通过规范化开发提高项目的可维护性与协作性。 1. 保持一致的命名规则 在L…

Flutter局域网广播(UDP通信)与TCP通信

前言 现在有一个需求&#xff0c;手机和ESP32通过WIFI进行通信。流程如下&#xff1a; 手机创建TCP服务器手机向192.168.0.255的1002端口广播自己的ip地址以及TCP服务器的端口号ESP32监听到1002的广播内容后&#xff0c;连接手机的TCP服务器。最后就是ESP32硬件和TCP服务器进…

双击热备 Electron网页客户端

安装流程&#xff1a; 1.下载node.js安装包进行安装 2.点击Next; 3.勾选&#xff0c;点击Next; 4.选择安装目录 5.选择Online 模式 6.下一步执行安装 。 7.运行cmd,执行命令 path 和 node --version&#xff0c;查看配置路径和版本 8.Goland安装插件node.js 9.配置运行…

【有啥问啥】深度剖析:大模型AI时代下的推理路径创新应用方法论

深度剖析&#xff1a;大模型AI时代下的推理路径创新应用方法论 随着大规模预训练模型&#xff08;Large Pretrained Models, LPMs&#xff09;和生成式人工智能的迅速发展&#xff0c;AI 在多领域的推理能力大幅提升&#xff0c;尤其是在自然语言处理、计算机视觉和自动决策领…

Kafka 下载安装及使用总结

1. 下载安装 官网下载地址&#xff1a;Apache Kafka 下载对应的文件 上传到服务器上&#xff0c;解压 tar -xzf kafka_2.13-3.7.0.tgz目录结果如下 ├── bin │ └── windows ├── config │ └── kraft ├── libs ├── licenses └── site-docs官方文档…

Flink Task 日志文件隔离

Flink Task 日志文件隔离 任务在启动时会先通过 MdcUtils 启动一个 slf4j 的 MDC 环境&#xff0c;然后将 jobId 添加到 slf4j 的 MDC 容器中&#xff0c;随后任务输出的日志都将附带 joid。 MDC 介绍如下&#xff1a; MDC ( Mapped Diagnostic Contexts )&#xff0c;它是一个…

深度学习:(六)激活函数的选择与介绍

激活函数 之前使用的 a σ ( z ) a\sigma(z) aσ(z) &#xff0c;其中 σ ( ) \sigma(~) σ( ) 便是激活函数。 在神经网络中&#xff0c;不同层的激活函数可以不同。 在学习中&#xff0c;一般以 g ( z ) g(z) g(z) 来表示激活函数。 为什么需要(线性)激活函数&#xff…

K8s容器运行时,移除Dockershim后存在哪些疑惑?

K8s容器运行时&#xff0c;移除Dockershim后存在哪些疑惑&#xff1f; 大家好&#xff0c;我是秋意零。 K8s版本截止目前&#xff08;24/09&#xff09;已经发布到了1.31.x版本。早在K8s版本从1.24.x起&#xff08;22/05&#xff09;&#xff0c;默认的容器运行时就不再是Doc…

算法之搜索--最长公共子序列LCS

最长公共子序列&#xff08;longest common sequence&#xff09;:可以不连续 最长公共子串&#xff08;longest common substring&#xff09;&#xff1a;连续 demo for (int i 1;i<lena;i){for (int j 1;j<lenb;j){if(a[i-1]b[j-1]){dp[i][j]dp[i-1][j-1]1;}el…

Qt (17)【Qt 文件操作 读写保存】

阅读导航 引言一、Qt文件概述二、输入输出设备类三、文件读写类四、文件和目录信息类五、自定义“记事本” 引言 在上一篇文章中&#xff0c;我们学习了Qt的事件处理机制&#xff0c;知道了如何响应用户的操作。但应用程序常常还需要处理文件&#xff0c;比如读写数据。所以&a…

python爬虫初体验(一)

文章目录 1. 什么是爬虫&#xff1f;2. 为什么选择 Python&#xff1f;3. 爬虫小案例3.1 安装python3.2 安装依赖3.3 requests请求设置3.4 完整代码 4. 总结 1. 什么是爬虫&#xff1f; 爬虫&#xff08;Web Scraping&#xff09;是一种从网站自动提取数据的技术。简单来说&am…

指针修仙之实现qsort

文章目录 回调函数什么是回调函数回调函数的作用 库函数qsort使用qsort函数排序整形使用qsort函数排序结构体 qsort函数模拟实现说明源码and说明 回调函数 什么是回调函数 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xff09;作为参数…

Sigmoid引发的梯度消失爆炸及ReLU引起的神经元参数失效问题思考

Sigmoid和ReLU激活函数思考&#xff09; 引文Sigmoid函数梯度消失问题梯度爆炸问题解决方案 ReLU函数简化模型示例场景设定前向传播对反向传播的影响总结 内容精简版 引文 梯度消失和梯度爆炸是神经网络训练中常见的两个问题&#xff0c;特别是在使用Sigmoid激活函数时。这些问…

后端-navicat查找语句(单表与多表)

表格字段设置如图 语句&#xff1a; 1.输出 1.输出name和age列 SELECT name,age from student 1.2.全部输出 select * from student 2.where子语句 1.运算符&#xff1a; 等于 >大于 >大于等于 <小于 <小于等于 ! <>不等于 select * from stude…

torch模型量化方法总结

0.概述 模型训练完成后的参数为float或double类型,而装机(比如车载)后推理预测时,通常都会预先定点(量化)为int类型参数,相应的推理的精度会有少量下降,但不构成明显性能下降,带来的结果是板端部署的可能性,推理的latency明显降低,本文对torch常用的量化方法进行总…

JavaEE: 创造无限连接——网络编程中的套接字

文章目录 Socket套接字TCP和UDP的区别有连接/无连接可靠传输/不可靠传输面向字节流/面向数据报全双工/半双工 UDP/TCP api的使用UDPDatagramSocketDatagramPacketInetSocketAddress练习 TCPServerSocketSocket练习 Socket套接字 Socket是计算机网络中的一种通信机制&#xff0…

【VLM小白指北 (1) 】An Introduction to Vision-Language Modeling

开一个新坑Vision-Language Modeling (VLM) &#xff0c;原文76页&#xff0c;慢慢更&#xff0c;for beginners&#xff0c;但也不能之前啥都不会啊。 原文链接&#xff1a;An Introduction to Vision-Language Modeling Introduction 存在的问题&#xff1a;将语言与视觉相…

ChatGPT 在国内使用的方法

AI如今很强大&#xff0c;聊聊天、写论文、搞翻译、写代码、写文案、审合同等等&#xff0c;ChatGPT 真是无所不能~ 作为一款出色的大语言模型&#xff0c;ChatGPT 实现了人类般的对话交流&#xff0c;最主要是能根据上下文进行互动。 接下来&#xff0c;我将介绍 ChatGPT 在国…