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

news2024/11/27 11:54:12

文章目录

  • 再次理解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视图。

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

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

相关文章

盐城市大数据集团携手百望云 以MaaS推进数字经济跃迁

随着ChatGPT的爆火&#xff0c;大模型、人工智能、大数据等技术&#xff0c;被快速推向市场最前沿。如何通过创新技术提升企业的数字化能力&#xff0c;助力数据要素资产沉淀&#xff0c;推动企业及所在行业、区域实现数智化转型&#xff0c;是大家关注的核心问题。 “携手共建…

Linux shell命令

cat 文件名 查看文件内容&#xff0c; tac文件名 倒着显示。 more 文件名 显示内容 less文件名 和more的功能一样&#xff0c;按上下左右键&#xff0c;按Q键结束。 head文件名&#xff0c;只显示前10行内容。 ln是一个默认创建硬链接的命令 ln 文件名 ls -i文件名…

单元测试的实现方式

单元测试的实现方式包括&#xff1a;人工静态检查、动态执行跟踪 人工静态检查 人工静态检查是一种单元测试实现方式&#xff0c;它主要依赖开发人员的人工代码审查和静态分析工具来识别潜在的代码问题。 代码审查&#xff1a;开发人员通过仔细检查代码来发现潜在的问题。他…

IT人的拖延——渴望成功与害怕成功的矛盾

很多人都以为&#xff0c;害怕失败是拖延的主要诱因&#xff0c;但其实“害怕成功”也是拖延的主要诱因之一。要说这个原因&#xff0c;我们不得不提起Bible中的一个人“约拿”&#xff0c;让我们先来看看他的故事带给我们什么启示。 约拿情结简介 约拿是Bible中的一名先知&a…

[C][数组]详细讲解

目录 0.何为数组&#xff1f;1.一维数组1.创建2.数组的初始化3.一维数组的使用4.一维数组在内存中的存储 2.二维数组1.创建2.二维数组初始化3.二维数组的使用4.二维数组在内存中的存储 3.数组越界4.数组作为函数参数 0.何为数组&#xff1f; 数组是一组形同类型的元素int arr[…

数据结构的希尔排序(c语言版)

一.希尔排序的概念 1.希尔排序的基本思想 希尔排序是一种基于插入排序算法的优化排序方法。它的基本思想如下: 选择一个增量序列 t1&#xff0c;t2&#xff0c;......&#xff0c;tk&#xff0c;其中 ti > tj, 当 i < j&#xff0c;并且 tk 1。 按增量序列个数k&#…

快速复制成功模式:解读SaaS裂变工具的核心价值

在数字化快速发展的今天&#xff0c;企业如何在竞争激烈的市场中迅速站稳脚跟&#xff0c;成为许多企业家和管理者关注的焦点。SaaS裂变工具作为一种创新的解决方案&#xff0c;以其独特的优势&#xff0c;帮助企业快速复制成功模式&#xff0c;实现业务的快速增长。 SaaS裂变工…

GTD时间管理法

Part 1. What is GTD? | 什么是GTD&#xff1f; GTD is a framework that enhances focus and productivity. Through techniques such as capturing all tasks in a trusted system and breaking down complex projects into actionable items, GTD allows individuals to co…

组件的传参等

一:组件的生命周期函数 组件的生命周期函数: created只是创建了组件内的实例对象 attached,给组件实例绑定了属性,绑定到页面节点树之后 ready准备好渲染之后,还未渲染之前 moved组件实例被移动到另一个位置后执行 detached在整个组件被被移除执行 error执行的时候,组件内…

左偏树,可合并堆

合并两个堆并维护最小或最大性质解决树上节点问题&#xff0c;从叶节点往根维护&#xff0c;每个节点看作一个堆表示到最近的叶节点的距离&#xff0c;所以每次对合并&#xff08;树高矮&#xff09;表示堆的顶点对应下标关键代码 static void dfs(int x){for(int ihead[x];i&g…

科技守护,河流水文监测保障水资源安全!

中小河流是城乡水资源的补给&#xff0c;又是不可或缺的排放渠道&#xff0c;维系着城乡水资源的平衡与生态的健康。然而&#xff0c;随着工业化、城市化的快速推进&#xff0c;河流生态环境面临着越来越大的压力。为了有效保护和合理利用河流资源&#xff0c;河流水文监测成为…

2024吉林省电赛(达盛杯)

1. 电赛F4系统板3D图 提起自制STM32F407VET6系统板 2. 电赛原理图 3. 电赛PCB图 4. 智能车实物图 下图是电赛的实物图&#xff0c;结构采用3D打印 5. 软件设计 下图是程序设计图 6. 仿真视频 (1) 变化高度 2024吉林省电赛仿真1 (2) 变化轮距 2024电赛仿真2 7. APP控制小车 …

vue项目中使用json编辑器

实现效果&#xff1a; 借助插件json-editor-vue3实现效果如图一&#xff0c;如果嫌丑可以通过类名改一下样式如图二。 实现过程&#xff1a; 安装插件&#xff1a;npm install json-editor-vue3 文档链接&#xff1a;GitCode - 开发者的代码家园 <script setup name&quo…

Django 入门教程

1. Django简介 基本介绍 Django 是一个由 Python 编写的一个开放源代码的 Web 应用框架。 MVC 与 MVT 模型 MVC 模型 MVC 模式&#xff08;Model–view–controller&#xff09;是软件工程中的一种软件架构模式&#xff0c;把软件系统分为三个基本部分&#xff1a;模型&am…

NSSCTF中的pop、babyupload、cve版本签到、奇妙的MD5、easy_html

目录 [SWPUCTF 2021 新生赛]pop [NISACTF 2022]babyupload ​编辑[GKCTF 2020]cve版签到 [SWP5UCTF 2022 新生赛]奇妙的MD5 [HNCTF 2022 Week1]easy_html 今日总结&#xff1a; [SWPUCTF 2021 新生赛]pop 1.代码审计 <?phperror_reporting(0); show_source("…

文本匹配.grep与Select-String用法对比

Linux Shell与PowerShell上匹配字符串 grep与Select-String用法对比 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article…

Lin网络二

目录 根据域名查找出IP地址的流程&#xff1a; DNS域名的功能&#xff1a; 正向解析&#xff1a; 反向解析&#xff1a; DNS的端口&#xff1a; DNS域名解析工作原理&#xff1a; DNS域名解析查询方式&#xff1a; 递归查询&#xff1a;&#xff08;简单来说就是将DNS解…

ICML 2024 | 北大、字节提出新型双层位置编码方案,有效改善长度外推效果

在这项工作中&#xff0c;我们利用语言序列的内在分段特性&#xff0c;设计了一种新的位置编码方法来达到更好的长度外推效果&#xff0c;称为双层位置编码&#xff08;BiPE&#xff09;。对于每个位置&#xff0c;我们的 BiPE 融合了段内编码和段间编码。段内编码通过绝对位置…

LOTO示波器软件新增导览功能

新版本的大部分型号LOTO示波器的上位机软件我们改成了导航工具条方式。原来的方式是把所有功能都显示在不同的标签页中&#xff0c;这样的优点是非常快捷方便&#xff0c;基本上用鼠标一两次点击就能直达想要的功能设置。但是缺点是不熟练的客户可能记不住各种功能的标签位置在…

安全攻防三

一、IDS: 当黑客绕过了防火墙&#xff0c;你该如何发现&#xff1f; IDS &#xff08;Intrusion Detection System&#xff0c;入侵检测系统&#xff09; NIDS 内网中检测网络流量攻击 黑客如果已经进去内网&#xff0c;防火墙就没办法保护了 NIDS部署在交换机和路由器这些路…