MySQL调优-深入理解MVCC机制

news2025/1/13 3:16:46

目录

MySQL调优-深入理解MVCC机制

MVCC多版本并发控制机制

undo日志版本链与read view机制详解

 根据图2和图3对应画出下图的undo日志版本链:

版本链比对规则:

注意:

举例1:分析一下下图select1的read_view以及各个select语句查询到的结果 

(1)第一步:分析select1对应read_view的生成

 (2)第二步:根据最新生成的版本链+read_view进行比对得出当前select查询SQL的数据结果

举例2:在举例1的基础上搞一个select2

 当select2的查询语句执行后,生成select2对应事务结束前的唯一read_view:

其余的比对规则和举例1同理即可

总结:


MySQL调优-深入理解MVCC机制

MVCC多版本并发控制机制

MySQL在可重复读隔离级别下如何保证事务较高的隔离性,之前记录过,同样的sql查询语句在同一个事务里多次执行查询结果相同,就算其它事务对数据有修改也不会影响当前事务SQL语句的查询结果。

这个隔离性就是依靠MVCC机制来保证的,对一行数据的读和写两个操作默认是不会加锁互斥来保证隔离性,避免了频繁加锁互斥,而在串行化隔离级别为了保证较高的隔离性是通过将所有操作加锁互斥来实现的。

但是对于MySQL底层的读已提交和可重复读隔离级别下都是实现了MVCC机制。

undo日志版本链与read view机制详解

undo日志版本链是指一行数据被多个事务依次修改过后,在每个事务修改完后,MySQL会保留修改前的数据undo回滚日志,并且使用两个隐藏字段trx_id和roll_pointer把这些undo日志串联起来形成一个历史记录版本链。

图2:

图3:

 根据图2和图3对应画出下图的undo日志版本链:

版本链比对规则:

1. 如果 row 的 trx_id 落在绿色部分( trx_id<min_id),表示这个版本是已提交的事务生成的,这个数据是可见的。

2. 如果 row 的 trx_id 落在红色部分( trx_id>max_id ),表示这个版本是由将来启动的事务生成的,是不可见的(若 row 的 trx_id 就是当前自己的事务是可见的);

3. 如果 row 的 trx_id 落在黄色部分(min_id<=trx_id<=max_id),那么就包括两种情况:

    a. 若 row 的 trx_id 在视图数组中,表示这个版本是由还没提交的事务生成的,不可见(若 row 的 trx_id 就是当前自己的事务是可见的);

    b. 若 row 的 trx_id 不在视图数组中,表示这个版本是已经提交了的事务生成的,可见。

注意:

(1)undo日志版本链只有一份。

(2)但是在可重复读隔离级别,当事务开启,执行任何查询sql时会生成当前事务的一致性视图read-view,该视图在事务结束之前都不会变化(如果是读已提交隔离级别在每次执行查询sql时都会重新生成),这个read_view视图由执行查询时所有未提交事务id数组(数组里最小的id为min_id)和已创建的最大事务id(max_id)组成。

事务里的任何sql查询结果需要从对应undo日志版本链里的最新数据开始逐条跟read_view做对比从而得到最终的快照结果,比对的过程依照的即是上面那个版本链比对规则这个快照结果即使最终select查询语句查询出的数据值。

(3)总结(1)和(2)

(4)对于删除的情况可以认为是update更新的特殊情况,会将版本链上最新的数据复制一份,然后将trx_id修改成删除操作的trx_id,同时在该条记录的头信息(record header)里的(deleted_flag)标记位写上true,来表示当前记录已经被 删除,在查询时按照上面的规则查到对应的记录如果delete_flag标记位为true,意味着记录已被删除,则不返回数 据。

(5)begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个修改操作InnoDB表的语句, 事务才真正启动,才会向mysql申请事务id,mysql内部是严格按照事务的启动顺序来分配事务id的。

即:只有当执行一次修改操作后mysql才会分配给事务id,如果一直执行select查询SQL,mysql不会分配事务id,begin/start transaction也没用!

举例1:分析一下下图select1的read_view以及各个select语句查询到的结果 

(1)第一步:分析select1对应read_view的生成

select1对应的事务没有执行修改SQL语句所以不生成事务id,但是由于执行了select查询语句,所以该事务会生成对应唯一一个read_view数组。

read_view生成规则如下:

在可重复读隔离级别下,当事务开启时,执行任何查询sql时会生成当前事务的一致性视图read-view,该视图在事务结束之前都不会变化(如果是读已提交隔离级别在每次执行查询sql时都会重新生成)。这个视图由执行查询时所有未提交事务id数组(数组里最小的id为min_id)和已创建(已commit提交)的最大事务id(max_id)组成。

根据生成规则以及上图开启的事务可知以及当第一条select查询语句执行后,在可重复读隔离机制下当前事务的read_view就已经确定了!分析如下:

1.一共开启了三个事务,事务id分别为100,200,300。其中100,200为未提交的事务。300为已创建(即是已提交)的事务。因此得出min_id=100,max_id=300。

2.当前select1对应的read_view为:[100,200],300。

3.其中[100,200]之间即是视图数组范围,300为非视图数组范围。

画出read_view示意图:

 (2)第二步:根据最新生成的版本链+read_view进行比对得出当前select查询SQL的数据结果

1.

事务里的任何sql查询结果需要从对应版本链里的最新数据开始逐条跟read-view做比对从而得到最终的快照结果。

2.版本链比对规则:

3.read_view示意图:

4.根据1和2和3可知,分析如下:

4.1当执行完第一条select查询后:

生成read_view为[100,200],300。其中[100,200]为视图数组范围,300为非视图数组范围。

在第一条select执行之前,一共有两条关于accout表的name字段的修改操作,一个是事务id为80(题目中未显示,篇幅问题)和一个事务id为300。

画出此时undo日志版本链为:

 根据版本链比对规则,从对应版本链里的最新数据开始逐条跟read-view做比对:

最新的数据row如上图即可得知,最新的row对应的事务id为300,300在黄色区域并且300不在视图范围,所以可见。所以第一条select语句返回的数据结果为lilei300。

4.2当执行完第二条select查询后:

 在第二条select执行之前,一共有四条关于accout表的name字段的修改操作,一个是事务id为80(题目中未显示,篇幅问题)和一个事务id为300和两条事务id为100。

画出此时undo日志版本链为:

 根据版本链比对规则,从对应版本链里的最新数据开始逐条跟read-view做比对

1.最新的数据row如上图即可得知,最新的row对应的事务id为100,100落到黄色区域并且100在视图范围,所以不可见。

2.因为1中的row不可见,所以版本链下推比对下一条row,事务id为100,同理1即可

3.因为2中的row不可见,所以版本链继续下推比对下一条row,事务id为300,300在黄色区域并且300不在视图范围,所以可见。

所以第二条select语句返回的数据结果为lilei300。

4.3当执行完第三条select查询后:

  在第三条select执行之前,一共有六条关于accout表的name字段的修改操作,一个是事务id为80(题目中未显示,篇幅问题)和一个事务id为300和两条事务id为100和两条事务id为200。

画出此时undo日志版本链为:

根据版本链比对规则,从对应版本链里的最新数据开始逐条跟read-view做比对

这个比对和4.2同理,省略了。

所以第三条select语句返回的数据结果为lilei300。

举例2:在举例1的基础上搞一个select2

由于举例1以及详细分析过了,所以这里简略记录一下。

 当select2的查询语句执行后,生成select2对应事务结束前的唯一read_view:

由执行查询时所有未提交事务id数组(数组里最小的id为min_id)和已创建的最大事务id(max_id)组成

1.一共开启了三个事务。事务id分别为100,200,300。

其中200为未提交的事务。100,300为已创建(即是已提交)的事务。未提交事务id数组中只有200,已创建的最大事务id为300。因此得出min_id=200,max_id=300。

2.当前select1对应的read_view为:[200],300。

3.其中[200]即是视图数组范围,300为非视图数组范围。

其余的比对规则和举例1同理即可

最终select2中查询语句查询出的数据结果为:lilei2

总结:

MVCC机制的实现就是通过read-view机制与undo版本链比对机制,使得不同的事务会根据数据版本链对比规则读取同一条数据在版本链上的不同版本数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/145731.html

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

相关文章

Cadence PCB仿真使用Allegro PCB SI导入其他板卡的层叠结构的方法图文教程

⏪《上一篇》   🏡《总目录》   ⏩《下一篇》 目录 1,概述2,导入方法3,总结1,概述 本文详细介绍使用Allegro PCB SI PCB仿真软件导入其他电路板层叠结构的方法。 2,导入方法 第1步:打开待仿真的PCB文件,并确认软件为Allegro PCB SI 如果,打开软件不是Allegro PC…

STL-vector的接口使用及模拟实现

文章目录vector类的介绍vector类的常用接口介绍 构造相关 无参构造迭代器区间构造拷贝构造 容量相关的接口 sizereserveresizecapacityempty 数据访问及遍历相关的接口 operator[]begin endrbegin rend 修改数据相关的接口 push_backpop_backinserterase vector类的模拟实现…

excel统计函数:应用广泛的动态统计之王OFFSET 下篇

【前言】在上篇文章中&#xff0c;我们了解了OFFSET函数的运算原理和各个参数的作用&#xff0c;并且我们也通过一些OFFSET的案例&#xff0c;了解了它的用途。那么本篇我们继续来看看&#xff0c;OFFSET函数在实际工作中所能起到的强大效果吧。一、高阶应用的思路&#xff08;…

vector使用指南

目录 引言 空间配置器 vector 与 string的一些差异 vector容器与string容器的一些差异 接口介绍——reserve resize接口 shrink_to_fit 接口 operator[ ] 和 at 接口 assign接口 增删查改接口 swap接口 例题讲解 引言 vector实质上就是数据结构的顺序表&#xff0…

数据结构:栈和队列(详细讲解)

&#x1f387;&#x1f387;&#x1f387;作者&#xff1a; 小鱼不会骑车 &#x1f386;&#x1f386;&#x1f386;专栏&#xff1a; 《数据结构》 &#x1f393;&#x1f393;&#x1f393;个人简介&#xff1a; 一名专科大一在读的小比特&#xff0c;努力学习编程是我唯一…

(8)Qt中的自定义信号

目录 自定义信号需要遵循的规则 信号的发送 自定义信号的基本实现 使用一个父子窗口切换的小案例 Qt框架提供的信号在某些特定场景下是无法满足我们的项目需求的&#xff0c;因此我们还设计自己需要的的信号&#xff0c;同样还是使用connect()对自定义的信号槽进行连接。 自…

制造业ERP管理系统解决方案之销售管理

在企业的生存发展中&#xff0c;销售管理起到了重要的作用&#xff0c;它决定着企业发展的提速和效益的提升。做好销售管理工作&#xff0c;不仅可以推动企业资金有效运转&#xff0c;还可以使企业在稳定中高效发展&#xff0c;使企业价值最大化。而在制造企业销售管理中&#…

Leetcode.1658 将 x 减到 0 的最小操作数

题目链接 Leetcode.1658 将 x 减到 0 的最小操作数 题目描述 给你一个整数数组 nums 和一个整数 x 。每一次操作时&#xff0c;你应当移除数组 nums 最左边或最右边的元素&#xff0c;然后从 x 中减去该元素的值。请注意&#xff0c;需要 修改 数组以供接下来的操作使用。 如…

SHELL脚本学习 --- 第八次作业(安全脚本)

SHELL脚本学习 — 第八次作业 题目要求&#xff1a; 将密码输入错误超过4次的IP地址通过firewalld防火墙阻止访问 思路&#xff1a; 首先需要找到ssh密码输入错误超过四次的IP地址&#xff0c;需要到日志文件中找。 该日志文件为/var/log/secure。 找到之后通过正则匹配到密码输…

JavaEE高阶---SpringBoot 统⼀功能处理

一&#xff1a;什么是SpringBoot 统⼀功能处理 SpringBoot统一功能处理是AOP的实战环节。我们主要学习三方面内容&#xff1a; 统一用户登录权限验证&#xff1b;统一数据格式返回&#xff1b;统一异常处理。 二&#xff1a;统一用户登录权限验证 Spring 中提供了具体的实现…

通过后端代理实现Web搜索功能

大家好&#xff0c;才是真的好。 前面我们都在说使用Domino自带的视图搜索功能&#xff0c;这一篇也是&#xff0c;不过不是视图搜索&#xff0c;而是整个Notes数据库搜索&#xff0c;然后再将结果返回给浏览器网页呈现。 前提和前面两篇都是一样的&#xff0c;即Notes应用需…

Java 如何不使用 volatile 和锁实现共享变量的同步操作

前言 熟悉 Java 并发编程的都知道&#xff0c;JMM(Java 内存模型) 中的 happen-before(简称 hb)规则&#xff0c;该规则定义了 Java 多线程操作的有序性和可见性&#xff0c;防止了编译器重排序对程序结果的影响。 按照官方的说法&#xff1a; 当一个变量被多个线程读取并且至…

「数据密集型系统搭建」原理篇|数据类型不怕精挑细选

本篇围绕MySQL数据库的底层存储模型、列类型来聊聊数据库表设计及建模中要注意的事项&#xff0c;剖析最根源的底层物理存储文件&#xff0c;用最真实的数据剖析来证明和解答开发过程中的疑惑。 在一些技术谈资、面试沟通过程中&#xff0c;MySQL特别是我们常用的Innodb存储引擎…

JavaScript 作用域

文章目录JavaScript 作用域JavaScript 作用域JavaScript 局部作用域JavaScript 全局变量JavaScript 变量生命周期函数参数HTML 中的全局变量你知道吗?JavaScript 作用域 作用域可访问变量的集合。 JavaScript 作用域 在 JavaScript 中, 对象和函数同样也是变量。 在 JavaScr…

ONES X 海银财富|以敏捷流程管理,创新金融服务平台

近日&#xff0c;ONES 签约财富管理行业领跑者——海银财富&#xff0c;助力海银财富落地敏捷流程管理&#xff0c;打造从需求到交付的一体化平台&#xff0c;快速接受业务方的反馈&#xff0c;进行金融平台的迭代与优化。海银财富管理有限公司&#xff08;以下简称海银财富&am…

拆机详解:1968年军用集成电路计算机 高级货赢在做工

halo大家好&#xff0c;这里是一天更两篇的Eric。 今天我在网上偶然看到一个拆军用计算机的&#xff0c;正好给你们分享一下。这可是1970年左右为了F4战斗机敌我识别系统打造的&#xff0c;虽说比之前说的Macintosh更加的挤也更大&#xff0c;不过做工够扎实。 上图&#xff…

centos8安装RabbitMQ和erlang

RabbitMQ 消息队列MQ RabbitMQ简称MQ是一套实现了高级消息队列协议的开源消息代理软件&#xff0c;简单来说就是一个消息中间件。是一种程序对程序的通信方法&#xff0c;其服务器也是以高性能、健壮以及可伸缩性出名的Erlang语言编写而成为什么使用MQ 在项目中&#xff0c;…

QSyntaxHighlighter

一、描述 此类用于自定义语法高亮显示规则&#xff0c;是用于实现 QTextDocument 文本高亮显示的基类。 要自定义语法高亮显示&#xff0c;必须子类化 QSyntaxHighlighter 并重新实现 highlightBlock()。此函数将在合适的时机自动被调用。 highlightBlock() 函数将格式设置应…

SOFA Weekly|SOFANews、本周贡献 issue 精选

SOFA WEEKLY | 每周精选 筛选每周精华问答&#xff0c;同步开源进展欢迎留言互动&#xff5e;SOFAStack&#xff08;Scalable Open Financial Architecture Stack&#xff09;是蚂蚁集团自主研发的金融级云原生架构&#xff0c;包含了构建金融级云原生架构所需的各个组件&#…

Rasa 3.x 学习系列-Rasa [3.4.0] - 2022-12-14新版本发布

Rasa 3.x 学习系列-Rasa [3.4.0] - 2022-12-14新版本发布 任何人都可以学习Rasa之优秀Rasa学习资源推荐 欢迎同学们报名Gavin老师的Rasa系列课程,任何人都可以学习Rasa之优秀Rasa学习资源推荐: 1.NLP on Transformers高手之路137课 2 .Rasa 3.X 智能对话机器人案例开发硬核…