InnoDB存储引擎非常重要的一个机制--MVCC(多版本并发控制)

Mysql是如何实现隔离性的?(锁+MVCC)

隔离性是指一个事务内部的操作以及操作的数据对正在进行的其他事务是隔离的,并发执行的各个事务之间不能相互干扰。隔离性可以防止多个事务并发执行时,可能存在交叉执行导致数据的不一致。

MySQL 对隔离性的保证主要有两个方面:

--用锁机制来保证一个事务写操作对另一个事务写操作的隔离性,

---用 MVCC 机制来保证一个事务写操作对另一个事务读操作的隔离性。

MySQL 中按照锁的粒度,可以分为全局锁,表锁和行锁。

全局锁会使整个数据库处于只读状态,在做全库逻辑备份时经常用到。表级锁在操作数据时会锁定整张表,并发性能一般,而行锁可以做到只锁定需要操作的记录行,并发性能很好。但是由于加锁本身需要消耗资源,因此某些在锁定数据较多的情况下可以使用表锁来减少开销。

MVCC 主要解决的是读写冲突的问题它是由 undo log + read view 实现的。其中 undo log 可以为每条记录保存多个历史版本,MySQL 在执行快照读的时候,会根据事务的 read view 里的信息,顺着 undo log 的版本链找到满足可见性的记录。

MVCC-Multi-Version Concurrency Control 多版本并发控制

是指维护一个数据的多个版本,使得读写操作没有冲突,快照读为MySQL实现MVCC提供了一个非阻塞读功能。MVCC的具体实现,还需要依赖于数据库记录中的三个隐藏字段、undo log日志、readView。

数据库记录中的三个(两个)隐藏字段:

 undo log日志:

多个事务 提交事务之后undo log不会立即删除.原因是有活动的事务,正在用到这个undo log,结合ReadView..

undo log版本链: 

  • 在不同事务/相同事务对同一记录进行修改,修改过程中会记录 该记录的undo log日志。
  • 会导致该记录的uodo log生成一条记录版本链表。链表的头部是最新的旧记录,尾部是最早的旧记录!
  • undo log日志中记录了当前记录(行数据)的历史版本。

查询时应该返回哪一个版本呢??
具体返回哪个版本,要取决于MVCC实现原理中的readview

ReadView(读视图)

ReadView 是 快照读 SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。

 版本链数据访问规则:

 不同的隔离级别,生成ReadView的时机不同:
- RC: 在事务每次快照读的时候,都会产生一个新的ReadView....(里面维护着当前活动的事务ID)
- RR: 在事务第一次快照读的时候,会产生一个新的ReadView,后续的每次快照读都会复用第一个ReadView..(里面维护着当前活动的事务ID)

(这是造成 不可重复读 和 幻读的本质原因)

RC隔离级别下:

每次快照读的时候,会从当前记录的最新版本开始,和ReadView中的字段,通过版本链数据访问规则开始对比。如果符合就返回当前 版本记录,如果不符合,就按照版本链的链表往下继续做对比,直到找到符合规则的那个版本返回。。

因为RC(读已提交)隔离级别下每次快照读都是新的ReadView,所以维护的活动事务ID集合m_ids都可能不一样,所以会有不可重复读的现象出现!(问题根源)

比如上图:一次快照读是{3,4,5},一次快照读是{4,5}

RR隔离级别下:

第一次快照读,会产生一个ReadView,分别记录四个属性,接下来第二个快照读的时候,不会再生成一个ReadView了 ,直接复用第一个,所以匹配规则也都 一样,在undo log版本链中查找时查出来的数据 也都一样,这就保证了 可重复读!

所以:MVCC-- 它的主要作用就是在 快照读 的时候,决定我们提取的到底是哪一个版本

总结:

扩展:

1、当前读

当前读就是读取到的是最新的数据!通过select .. lock in share mode(共享锁)实现,或通过select ...for update、update、insert、delete(排它锁)等实现!

 2、快照读

3、在InnoDB存储引擎下的RR隔离级别下:

  • 快照读会使用MVCC. (select * ... 普通sql语句)
  • 当前读会采用Next-Key-Lock,是行锁 + 间隙锁的方式来处理(锁机制).  (select ..lock in share mode/for ..update  update  insert delete)  

4、 RR级别下 快照读 使用了MVCC一定能避免幻读吗?
- 能,但不完全能!
- 因为MVCC并不是采用锁的方式完全的对事务数据进行了隔离,而是通过版本控制变相的实现了解决幻读的功能

特例:当两次快照读之间存在当前读,ReadView会重新生成,会导致产生幻读。

 MVCC在快照读的情况下可以解决幻读问题,但是在当前读的情况下是不能解决幻读的

5、RR可重复读隔离下为什么会产生幻读?

在可重复读隔离级别下,普通的查询是快照读,是不会看到别的事务插入的数据的(因为复用同一个 ReadView)。因此,幻读在 当前读 下才会出现。

SELECT * FROM player LOCK IN SHARE MODE;
SELECT * FROM player FOR UPDATE;
INSERT INTO player values ...
DELETE FROM player WHERE ...
UPDATE player SET ...

6、什么是幻读
在可重复读的数据隔离级别下,在同一个事务中,使用当前读,读到了其他事务新插入的数据的现象叫做幻读。这里有几个定语:可重复读的事务隔离级别,当前读,插入的新数据。只有在这些定语的约束下​才能形成幻读。​

我们知道可重复读的数据隔离级别下,一个事务无法查询到另外一个事务对数据表进行的变更,不过,这个结论的前提是,这个查询是一个普通查询,也就是快照读,如果查询的方式是当前读(select * from table for update),那么就可以查询到另外一个事务的变更结果的。但是"幻读"的定义,对"变更"又做了更严格的限制,幻读,只仅仅针对 "insert" 的变更,而对 "update" 的变更,虽然查询也可以感知到,但这不会被称为幻读。虽然这里说的有点啰嗦,但是幻读的定义就是那么严格,所以我要多强调一遍。

我们在使用MVCC的时候,一般是根据业务场景选择组合搭配,乐观锁或悲观锁。

MVCC用来解决读写冲突问题,乐观锁或者悲观锁用来解决写和写的冲突。从而最大程度的提高数据库的并发性 。

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

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

相关文章

Android 如何保证开启debug模式之后再启动

很多时候会需要debug看Android启动时候的一些数据,但很多时候会存在自己开启debug后app已经过了自己要debug的那段代码的时机了。 那么怎么样可以保证一定能让启动后不会错过自己要debug的那段代码执行的时机呢? 可以用下面这行命令,其中co…

记忆化搜索汇总

记忆化搜索简介 记忆化搜索(Memoization Search):是一种通过存储已经遍历过的状态信息,从而避免对同一状态重复遍历的搜索算法。 记忆化搜索是动态规划的一种实现方式。在记忆化搜索中,当算法需要计算某个子问题的结果…

Nginx+Tomcat负载均衡、动静分离集群

目录 1.Nginx负载均衡 1.1 负载均衡概念 1.2 负载均衡原理 1.3 Nginx配置反向代理 1.3.1 反向代理概念 1.3.2 反向代理主要参数 2.Nginx动静分离 2.1 动静分离的概念 2.2 Nginx 静态处理优势 2.3 动静分离原理 3. NginxTomcat动静分离的实验设计 3.1 准备三台虚拟机…

Java速成要多久?这篇文章告诉你答案!

Java速成要多久?这篇文章告诉你答案! Java作为一门用途广泛且经久不衰的编程语言,吸引了无数学习者的目光。许多人希望能够快速掌握Java,以便进入软件开发行业或者提升自身的竞争力。那么,Java速成究竟要多久呢&#x…

【遗传算法】【机器学习】【Python】常见交叉方法(二)、多点交叉和均匀交叉

一、遗传算法流程图 交叉过程即存在于上图的”交叉“(crossover)步骤中。 二、多点交叉 多点交叉的原理就是,随机地从父代两个基因型中,选择n个位点进行交换,其中n小于等于父代基因型长度(假设双亲基因长…

基于小波变换和峰值搜索的光谱检测matlab仿真,带GUI界面

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于小波变换和峰值搜索的光谱检测matlab仿真,带GUI界面.对光谱数据的成分进行提取,分析CO2,SO2,CO以及CH4四种成分比例。 2.…

【越界写null字节】ACTF2023 easy-netlink

前言 最近在矩阵杯遇到了一道 generic netlink 相关的内核题,然后就简单学习了一下 generic netlink 相关概念,然后又找了一到与 generic netlink 相关的题目。简单来说 generic netlink 相关的题目仅仅是将用户态与内核态的交互方式从传统的 ioctl 变成…

使用from…import语句导入模块

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在使用import语句导入模块时,每执行一条import语句都会创建一个新的命名空间(namespace),并且在该命名…

类的特殊成员函数

使用类的嵌套&#xff0c;并自定义析构函数 #include <iostream>using namespace std; class Per{ private:string name;int age;double hight;double weight; public:Per(string name,int age,double hight,double weight):name(name),age(age),hight(hight),weight(we…

当边缘计算用在定位设备

什么是边缘计算&#xff1f; 边缘计算是个比较高大上的概念&#xff0c;在这里就不提众多官方与非官方的定义了&#xff0c;只说说自己的理解。 边缘计算就是在最靠近物理设备的使用现场&#xff0c;利用有限的硬件资源&#xff0c;完成设备层数据采集、协议转换、数据上传、…

微信小程序开发的详细解读

目录 小程序的ID 小程序的项目结构 小程序调试基础库 小程序调试 小程序配置文件 Pages配置 Windows配置 tabbar配置 页面配置 项目配置文件 sitemap文件配置 样式与组件 小程序常用组件 轮播图组件 图片组件 Text组件 跳转方式 滚动方式 字体图表使用 背景…

用python写一个基于PyQt5和OpenAI的智能问答项目

摘要&#xff1a; 使用python写一个可以对话的智能问答机器人&#xff0c;界面是使用PyQt5写的&#xff0c;通过调用OpenAl的免费接口&#xff0c;实现实时聊天功能。 1.申请免费的API key 前往页面https://github.com/chatanywhere/GPT_API_free 点击下面链接&#xff1a; …

寻找 llvm v3.5 的目标代码生成模块

summ.c --(clang -emit-llvm -S)--> summ.ll --(llvm-as)----> summ.bc --(llc)---> summ.s opt -S -O2 实施机器无关优化&#xff0c;跟后端目标代码生成无关&#xff0c;故llc是llvm的后端。 1&#xff0c;示例代码 summ.c int adddd(int aaa, in…

Rethinking overlooked aspects in vision-language models

探讨多模态视觉语言模型的一些有趣结论欢迎关注 CVHub!https://mp.weixin.qq.com/s/zouNu-g-33_7JoX3Uscxtw1.Introduction 多模态模型架构上的变化不大,数据的差距比较大,输入分辨率和输入llm的视觉token大小是比较关键的,适配器,VIT和语言模型则不是那么关键。InternVL-…

【ArcGIS微课1000例】0017:ArcGIS中如何将kml(kmz)文件转json(geojson)?

文章目录 一、kml获取方式二、kml转图层三、图层转json一、kml获取方式 kml文件是一种很常用的数据格式,可以从谷歌地球(googleearth)获取某一个地区的kml范围文件,如青海湖(做好的kml文件可以从配套实验数据包0117.rar中获取)。 二、kml转图层 打开【KML转图层】工具,…

java判断对象是否还在被引用

1、代码取消强引用后&#xff0c;gc回收对象 public static void main(String[] args) {Object obj new Object();WeakReference<Object> weakRef new WeakReference<>(obj);System.out.println(weakRef.get());obj null; // 取消强引用,后续gc会被回收,如果不…

Web IDE 在线编辑器综合实践(Web IDE 技术探索 三)

前言 前面两篇文章&#xff0c;我们简单讲述了 WebContainer/api 、Terminal 的基本使用&#xff0c;离完备的在线代码编辑器就差一个代码编辑了。今天通过 monaco editor &#xff0c;来实现初级代码编辑功能&#xff0c;讲述的是整个应用的搭建&#xff0c;并不单独针对monac…

nginx --- 反向代理|负载均衡 | 动静分离

目录 反向代理如何配置 1、反向代理实例一 2、反向代理实例二 ocation 指令说明 Nginx 负载均衡 负载均衡常用算法 应用场景 总结 Nginx实现动静分离 一、什么是动静分离 二、实现方案 三、配置Nginx动静分离 四、验证测试 反向代理如何配置 1、反向代理实例一 实…

css文字超出元素省略,单行、多行省略

通用CSS .box {width: 500px;border: 1px solid red;padding: 10px;line-height: 24px;} 1.单行省略 .singe-line {text-overflow: ellipsis;overflow: hidden;word-break: break-all;white-space: nowrap;}<p>单行省略</p><div class"singe-line box&qu…

tomcat8w.exe指向了别的tomcat

这种情况通常发生是因为Tomcat服务在注册表中的配置指向了错误的可执行文件路径。tomcat8w.exe是一个Windows服务配置工具&#xff0c;它用于管理Tomcat服务&#xff0c;包括设置Path to executable&#xff0c;即指向Tomcat服务实际启动的.exe文件的路径。如果Path to executa…