【MySQL事务(下)(重点)】

文章目录

  • 再次理解MySQL事务
  • 一、MVCC机制
    • 数据库并发的场景有三种:
    • 3个记录隐藏列字段
    • undo日志——由mysql维护的一段内存空间
      • 再次理解隔离性和隔离级别
    • Read View 理论部分
    • RR 和 RC 的本质区别


再次理解MySQL事务

  • 1.每个事务都有自己的事务ID,根据事务的大小,进行排队。
  • 2.既然事务能排队,那就不能简单地认为事务就是一堆sql语句的集合,事务在语言看来,就是一个结构体对象/类对象。
  • 3.mysql可能会面临处理多个事务的情况,事务也有自己的生命周期,所以mysql要对多个事务进行管理,那就需要先描述,再组织

一、MVCC机制

数据库并发的场景有三种:

读-读 :不存在任何问题,也不需要并发控制
读-写 :有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读(重点)
写-写 :有线程安全问题,可能会存在更新丢失问题,比如第一类更新丢失,第二类更新丢失(后面补充)

重点在于第二类问题——读写。
要解决读写问题,就要学习MVCC机制,要学习MVCC机制,就要了解三个知识点:

  • 3个记录隐藏字段
  • undo日志
  • Read View

3个记录隐藏列字段

  • 1.DB_TRX_ID:占6字节,记录创建这个记录/最近修改这个记录的事务ID。
  • 2.DB_ROLL_PTR:7字节,回滚指针,跟回滚有关的。指向这条记录的上一个版本。
  • 3.DB_ROW——ID:6字节,这是一个隐藏的自增主键,如果表中没有创建主键,InnoDB会以该隐藏字段,产生一个聚簇索引。(就是建立一棵B+树,叶子节点与数据一起放的)

举例:

创建一个表,并插入一条数据:
create table if not exists student(
name varchar(11) not null,
age int not null);
mysql> insert into student (name, age) values (‘张三’, 28);

并且查看变量’autocommit’,这是一直开着的,所以,insert 这条插入sql语句,一定会被看成一个事务,自动提交了。

在这里插入图片描述

所以,看到的table,不仅仅是name,age两列,还有三个隐藏的字段:
在这里插入图片描述

因为insert语句也被看成了一个事务!

undo日志——由mysql维护的一段内存空间

这里理解undo log,简单理解成,就是 MySQL 中的一段内存缓冲区,用来保存日志数据的就行。

模拟MVCC的过程:

在上表的基础上,现在有一个事务10(仅仅为了好区分),对student表中记录进行修改(update):将name(张三)改成
name(李四)。

具体过程如下:
1.加锁
2.将修改前的整个记录,先拷贝一份到undo日志中,再将相关数据进行修改,结果如下:
在这里插入图片描述
回滚指针指向的是默认的上一条历史版本。
事务10的update语句完成后,就会释放锁。

现在又有一个事务11,对student表中记录进行修改(update):将age(28)改成age(38)。

注意:这里修改,一定不会是修改历史版本的记录,因为历史版本记录是稳定的,持久的,改的是最新版本的事务。

1.加锁
2.将现存的事务先拷贝一份到undo日志中,再更新相关数据。
3.释放锁。

在这里插入图片描述
如上,就完成了数据的更新,同时形成了一份历史版本链。
这就是对历史事务进行管理的提现:先描述再组织,这个组织的过程就用了链表。

注意一些细节问题:

  • 1.如果一个事务commit后,就无法回滚了。要知道,undo log只是一块内存缓冲区,会被写满,每次update/delete数据,都会保存一份历史版本,一旦commit后,就会把undo log的空间释放。
  • 2.对于比较特殊的insert操作,因为是新插入的操作,那么在此之前不会形成版本链,但是为了回滚操作,insert的数据也会被拷贝到undo log中,所以一旦commit之后,undo log就会被释放,也就是insert也不会回滚了。

再次理解隔离性和隔离级别

正因为有了undo log这样的缓冲区来保存历史版本数据。
才有了读写并发访问事务,不需要加锁。因为读的是历史版本事务,写的是最新数据,读写的版本位置不同就不需要加锁。所以就是隔离性,针对隔离级别,就有RU,RC,RR,串行化等几种隔离级别,本质上就是是否允许同时读写历史版本的不同位置。

那么,如何保证,不同的事务,看到不同的内容呢?也就是如何如何实现隔离级别?

Read View 理论部分

现在的问题就是,当前快照读,应不应该读到当前版本记录,也就是应不应该读到历史版本链的事务。

Read View就是一个视图,在MySQL源码中,这是一个类,当我们查看历史版本时,就会生成这个Read View。具体只需要记住该类的四个成员即可:

m_ids;      //一张列表,用来维护Read View生成时刻,系统正活跃的事务ID
up_limit_id;   //记录m_ids列表中事务ID最小的ID(没有写错)
low_limit_id;   //ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1(也没有写错,注意不是视图里面的最大事务ID+1)
creator_trx_id  //创建该ReadView的事务ID

注意:不是创建事务的时候,就形成这个Read View类,而是该事务已经存在的前提下,该事务第一次进行快照读(查看历史版本)的时候,就会形成这个Read View类。

所以,在该视图第一次查看事务时,会产生一个视图,这个视图就能看到当前sql系统正在活跃的事务。

具体如下图:
注意:事务ID是不断递增的,事务ID越小,说明该事务创建的越早。
在这里插入图片描述

  • 1.首先解析中间的事务,在快照时,当前系统正在活跃的事务,也就是已经begin但未commit的事务。
  • 2.已经提交的事务:在当前事务第一次进行快照读产生的Read View视图之前,已经commit的事务。
  • 3.快照后来的新事务:这些事务是在进行快照都之后,才开始begin活跃的事务。
  • 由于是已经形成Read View视图之后,才开始活跃的事务,所以在Read View列表中看不到。

在这里插入图片描述
解析这部分的意思:

  • 1.creator_trx_id就是创建该视图的事务ID,当该事务ID(creator_trx_id) == 版本链中的某个事务ID(DB_TRX_ID)时,说明我要看的事务ID,就是我本身。
  • 2.DB_TRX_ID < up_limit_id,说明我要查询的历史事务ID,小于当前我这个事务创建出来的视图ID(Read View),说明该事务是已经commit的,我应该要看到。

在这里插入图片描述
解析这部分的意思:
说明我当前要查询的事务ID,比我这个视图里面能看到的最大事务ID还要大,说明在我创建这个视图Read View的时候,你那个事务还没出生呢,或者你在我创建视图后才到来的。所以我不应该能看到你。

在这里插入图片描述
解析这部分的意思:
快照到的事务不一定连续。
如果要查询的事务ID不在Read View视图列表中,说明该事务已经提交,那就可以看到。
如果要查询的事务ID在Read View视图列表中,说明该事务同样是活跃事务还没commit,那么它的增删查改就不应该看到。

上面所提到的应不应该看到,指的是,应不应该出现在Read View视图里,这就像,假如我是大二学生,我应该要看到大四毕业学长的工作情况,但是当我大四的时候,我不可能也不应该看到大一的工作情况。

源码策略:
在这里插入图片描述

RR 和 RC 的本质区别

正是Read View生成时机的不同,从而造成RC,RR级别下快照读的结果的不同
在RR级别下的某个事务的对某条记录的第一次快照读会创建一个快照及Read View, 将当前系统活跃的其他事务记录起来此后在调用快照读的时候,还是使用的是同一个Read View,所以只要当前事务在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可见;

即RR级别下,快照读生成Read View时,Read View会记录此时所有其他活动事务的快照,这些事务的修改对于当前事务都是不可见的。而早于Read View创建的事务所做的修改均是可见。

而在RC级别下的,事务中,每次快照读都会新生成一个快照和Read View, 这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因。

总之在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。正是RC每次快照读,都会形成Read View,所以,RC才会有不可重复读问题。

简单说:RR和RC,RR:不更新Read View视图。
RC,每次进行快照读都会更新Read View视图。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蒙特卡洛法求解机械臂工作空间(以IRB4600型工业机械臂为例)

1. 概念 工作空间是衡量机器人工作能力的一个重要的运动学指标&#xff0c;蒙特卡洛法是一种随机模拟方法&#xff0c;用于在计算机上估计某些统计量&#xff0c;对于要估计的统计量&#xff0c;通过模拟大量的随机抽样&#xff0c;并计算这些样本的随机值来估算这个统计量的值…

释放 OSINT 的力量:在线调查综合指南

开源情报 (OSINT) 是从公开信息中提取有价值见解的艺术。无论您是网络安全专业人士、道德黑客还是情报分析师&#xff0c;OSINT 都能为您提供先进的技术&#xff0c;帮助您筛选海量的数字数据&#xff0c;发现隐藏的真相。 在本文中&#xff0c;我们将深入研究大量的OSINT 资源…

【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)

【LeetCode刷题】Day 10 题目1&#xff1a;30. 串联所有单词的子串&#xff08;困难&#xff09;思路分析&#xff1a;思路1&#xff1a;滑动窗口哈希map 题目2&#xff1a;LCR 017.最小覆盖子串思路分析思路1&#xff1a;滑动窗口哈希表 题目1&#xff1a;30. 串联所有单词的子…

【论文阅读|cryoET】DeepETPicker:使用弱监督深度学习的快速准确cryoET三维颗粒挑选算法

题目 DeepETPicker: Fast and accurate 3D particle picking for cryo-electron tomography using weakly supervised deep learning 发表期刊&#xff1a; Nature Communications 发表时间&#xff1a;2024.02 Accepted 作者&#xff1a;Guole Liu, Tongxin Niu 中科院自动化…

43-2 Linux入侵排查实验

环境准备: 老规则,我没有靶场就自己搭建了类似, 这里准备一台CentOS 7虚拟机作为受害者,然后使用CS制作木马并在受害者主机上线,具体过程可以看我之前写的一篇文章: 黑客必备利器:如何在系统上安装和使用 CobaltStrike(简称:CS)_cobalt strike-CSDN博客 最终的效果…

FPGA——eMMC验证

一.FPGA基础 1.FPGA烧录流程 (1) 加载流文件 —— bitfile (2) 烧录文件 —— cmm 二.MMC 1.基础知识 (1)jz4740、mmc、emmc、sd之间的关系&#xff1f; jz4740——处理器 mmc——存储卡标准 emmc——mmc基础上发展的高效存储解决方案 sd—— 三.eMMC和SD case验证 1.ca…

【一竞技DOTA2】RAMZES666替补参加裂变联赛

1、根据主办方文件,RAMZES666将继续作为Tundra战队替补参加裂变联赛。该比赛为欧洲线上赛,于5月27日-30日举行,总奖金8万美元。 除此之外,Nigma战队在上个月宣布四号位Matthew离队后,也选择启用老队员GH参赛。而在本月初让ah fu转回教练、携替补Thiolicor出战PGL瓦拉几亚的Secr…

浏览器提示网站不安全怎么办?有什么解决办法吗?

当你在浏览器中访问一个网站时&#xff0c;如果看到提示说该网站不安全&#xff0c;这通常是由于网站没有使用SSL证书或者SSL证书存在问题。SSL证书在这里扮演着非常关键的角色&#xff0c;下面我会详细解释它的作用以及如何解决这类不安全提示。 SSL证书的作用&#xff1a; 1…

JAVA基础----线程池

①什么是线程池&#xff1f; 线程池是对所有线程进行统一的管理和控制&#xff0c;从而提高系统的运行效率。当我们要使用线程的时候可以直接从线程池中拿&#xff0c;用完也不用自己去销毁&#xff0c;省去创建和销毁的时间&#xff0c;提升系统的响应时间。 ②线程池的七大核…

Apache、Nginx、IIS文件解析漏洞

目录 1、文件解析漏洞介绍 2、Apache相关的解析漏洞 &#xff08;1&#xff09;多后缀解析漏洞 &#xff08;2&#xff09;Apache配置问题 &#xff08;3&#xff09;换行符解析漏洞 &#xff08;4&#xff09;罕见后缀解析 3、Nginx相关的解析漏洞 &#xff08;1&…

【安装笔记-20240528-Linux-在 Vultr 云服务器上安装 OpenWRT】

安装笔记-系列文章目录 安装笔记-20240528-Linux-在 Vultr 云服务器上安装测试 OpenWRT 文章目录 安装笔记-系列文章目录安装笔记-20240528-Linux-在 Vultr 云服务器上安装测试 OpenWRT 前言一、软件介绍名称&#xff1a;OpenWRT主页官方介绍 二、安装步骤测试版本&#xff1a…

【SCAU操作系统】实验二页面置换算法的模拟实现及命中率对比python源代码及实验报告参考

一、课程设计目的 通过请求页式管理方式中页面置换算法的模拟设计&#xff0c;了解虚拟存储技术的特点&#xff0c;掌握请 求页式存储管理中的页面置换算法。 二、课程设计内容 模拟实现 OPT &#xff08;最佳置换&#xff09;、 FIFO 和 LRU 算法&#xff0c;并计算缺页…

Linux快速定位日志 排查bug技巧和常用命令

1. 快速根据关键字定位错误信息 grep 在 Linux 系统中&#xff0c;可以使用 grep 命令来查找日志文件中包含特定关键字的行。假设你的日志文件路径为 /var/log/myapp.log&#xff0c;你想要查找包含关键字 "abc" 的日志内容&#xff0c;可以按照以下步骤操作&#…

【浅水模型MATLAB】尝试完成一个数值模拟竞赛题

【浅水模型MATLAB】尝试完成一个数值模拟竞赛题 前言题目描述问题分析理论基础控制方程数值方法边界条件 代码框架与关键代码结果展示写在最后 更新于2024年5月25日 前言 最近看到第四届水科学数值模拟创新大赛的通知&#xff0c;就好奇翻看了前几年的比赛试题。发现去年的一个…

信息安全法规和标准

《全国人民代表大会常务委员会关于维护互联网安全的决定》规定&#xff0c;威胁互联网运行安全的行为&#xff1a;&#xff08;1&#xff09;侵入国家事务、国防建设、尖端科学技术领域的计算机信息系统&#xff0c;&#xff08;2&#xff09;故意制作、传播计算机病毒等破坏性…

[ue5]建模场景学习笔记(1)——混合材质

卷首&#xff1a;这部分会记录建模场景等相关学习内容&#xff0c;与ue引擎学习笔记不同的是&#xff0c;可能会略过一些基础内容&#xff0c;因为部分知识在blender中已经学习过了&#xff0c;不再继续记录。 1.需求分析&#xff1a; 想构建一个山地的场景&#xff0c;在ue5中…

在豆包这事上,字节看得很明白

大数据产业创新服务媒体 ——聚焦数据 改变商业 导语&#xff1a; 1.基于豆包的话炉/猫箱APP市场反响一般 2.价格战对于豆包来说是副产物 3.价格战对大模型市场是良性的 4.豆包接下来会推广至国际社会 因为宣称价格比行业便宜99.3%&#xff0c;豆包成功出圈了。根据火山引擎公…

通过安全的云开发环境重新发现 DevOps 的心跳

云开发平台如何“提升” DevOps 首先&#xff0c;我来简单介绍一下什么是云开发环境&#xff1a;它通常运行带有应用程序的 Linux 操作系统&#xff0c;提供预配置的环境&#xff0c;允许进行编码、编译和其他类似于本地环境的操作。从实现的角度来看&#xff0c;这样的环境类…

猫耳 WebSocket 跨端优化实践

前言 在现代的移动应用程序中&#xff0c;长连接是一种不可或缺的能力&#xff0c;包括但不限于推送、实时通信、信令控制等常见场景。在猫耳FM的直播业务中&#xff0c;我们同样使用了 WebSocket 长连接作为我们实时通信的基础。 在我们推进用户体验优化的工作中&#xff0c;…

如何将音频中的人声分离出来?

想要把一段视频中的人声跟背景音乐分离开来&#xff0c;找个好一点的音频处理软件就能把声音分离了&#xff0c;常见的有以下方法&#xff0c;一起来看看吧。 pr 打开软件&#xff0c;然后将电脑上的音频文件&#xff0c;上传到软件中&#xff0c;然后按住[ctrla]选择所有音频…