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用来解决读写冲突问题,乐观锁或者悲观锁用来解决写和写的冲突。从而最大程度的提高数据库的并发性 。

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

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

相关文章

opencv进阶 ——(十一)基于RMBG实现生活照生成寸照

实现步骤 1、检测人脸,可以使用opencv自带的级联分类器或者dlib实现人脸检测 2、放大人脸范围,调整到正常寸照尺寸 3、基于RMGB算法得到人像掩码 4、生成尺寸相同的纯色背景与当前人像进行ALPHA融合即可 alpha融合实现 void alphaBlend(cv::Mat&…

c++(内存分配,构造,析构)

#include <iostream>using namespace std; class Per { private:string name;int age;double *height;double *weigh; public://无参构造Per(){cout << "Per::无参构造" << endl;}//有参构造Per(string name,int age,double height,double weigh):…

分布式锁redisson

1&#xff1a;pom.xml添加依赖 <dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.21.1</version> </dependency>2-1&#xff1a;方法一&#xff1a;读取默认ym…

新书速览|Python Django 4构建动态网站的16堂课

Python Django 4构建动态网站的16堂课 本书内容 《Python Django 4构建动态网站的16堂课》是一本关于Django框架的网站开发入门教材&#xff0c;适合想要学习并掌握Django框架的开发人员阅读。《Python Django 4构建动态网站的16堂课》共分16课&#xff0c;内容包括网站开发环境…

C++ STL - 容器

C STL&#xff08;标准模板库&#xff09;中的容器是一组通用的、可复用的数据结构&#xff0c;用于存储和管理不同类型的数据。 目录 零. 简介&#xff1a; 一 . vector&#xff08;动态数组&#xff09; 二. list&#xff08;双向链表&#xff09; 三. deque&#xff08…

磁盘未格式化:深度解析、恢复方案及预防之道

在当今这个信息化爆炸的时代&#xff0c;磁盘未格式化问题无疑成为了众多用户头疼的难题。当我们的存储设备突然提示“磁盘未格式化”时&#xff0c;数据的丢失与恢复的挑战便摆在了我们面前。本文将深入解析磁盘未格式化的现象、原因&#xff0c;并给出两种有效的数据恢复方案…

MYSQL数据库细节详细分析

MYSQL数据库的数据类型(一般只需要用到这些) 整型类型&#xff1a;用于存储整数值&#xff0c;可以选择不同的大小范围来适应特定的整数值。 TINYINTSMALLINTMEDIUMINTINTBIGINT 浮点型类型&#xff1a;用于存储带有小数部分的数值&#xff0c;提供了单精度&#xff08;FLOA…

uniapp小程序开发 | 从零实现一款影视类app (后台接口实现,go-zero微服务的使用)

uniapp小程序开发实战系列&#xff0c;完整介绍从零实现一款影视类小程序。包含小程序前端和后台接口的全部完整实现。系列连载中&#xff0c;喜欢的可以点击收藏。 该篇着重介绍获取轮播图后台接口和获取正在热映电影的两个后台接口的实现。 后台服务使用golang&#xff0c;…

解决MAC M1 Docker Desktop启动一直在starting

问题描述&#xff1a; 今天使用docker buildx 构建Multi-platform&#xff0c;提示如下错误&#xff1a; ERROR: Multi-platform build is not supported for the docker driver. Switch to a different driver, or turn on the containerd image store, and try again. 于是按…

关系代数与规范化

本文是根据自己的理解&#xff0c;结合实践整理所得&#xff0c;有兴趣的可以参考学习。

在k8s中部署Kafka高可用集群超详细讲解

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《数据流专家&#xff1a;Kafka探索》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Kafka简介 2、为什么在Kubernetes中部署Kafka 二、…

金融科技发展报告:移动支付的市场格局、趋势与优缺点

一、引言 随着科技的飞速发展,金融科技已成为推动全球经济发展的重要力量。移动支付作为金融科技的重要分支,其市场格局与趋势日益受到业界的关注。本报告将详细剖析移动支付的市场格局,并深入探讨其发展趋势,同时结合相关案例和数据,为读者呈现移动支付的优缺点,以及国…

idea 中:运行 Application 时出错。命令行过长

一、问题描述&#xff1a; idea 导入新项目&#xff0c;在编译后&#xff0c;运行项目时&#xff0c;报以下错误&#xff1a; 14:47 运行 Application 时出错运行 Application 时出错。命令行过长。通过 JAR 清单或通过类路径文件缩短命令行&#xff0c;然后重新运行。二、问题…

小程序丨最大填表限制如何开启?

老师在新建填表时&#xff0c;希望设置最大数量限制&#xff0c;若填表达到限制&#xff0c;后续的学生将不能继续提交填表。 通过开启【表格最大限制】功能即可实现&#xff0c;下面就来教大家如何制作吧。 &#x1f50e;如何开启表格最大限制功能&#xff1f; 按照常规流程…

C++结合OpenCV进行图像处理与分类

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的在读研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三…

GPT-4o:重塑人机交互的未来

一个愿意伫立在巨人肩膀上的农民...... 一、推出 在人工智能&#xff08;AI&#xff09;领域&#xff0c;自然语言处理&#xff08;NLP&#xff09;技术一直被视为连接人类与机器的桥梁。近年来&#xff0c;随着深度学习技术的快速发展&#xff0c;NLP领域迎来了前所未有的变革…

使用正则表达式分割字符串

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 split()方法用于实现根据正则表达式分割字符串&#xff0c;并以列表的形式返回。其作用同字符串对象的split()方法类似&#xff0c;所不同的就是分割…

【Vue】路由的基本使用

文章目录 一、固定5个固定的步骤二、代码示例三、两个核心步骤四、完整代码 vue-router插件作用 修改地址栏路径时&#xff0c;切换显示匹配的组件 说明 Vue 官方的一个路由插件&#xff0c;是一个第三方包 官网 https://v3.router.vuejs.org/zh/ VueRouter的使用&#xff0…

【java基础】内部类

1、 非静态成员内部类可以访问所在类的全部方法和对象&#xff08;就相当于一个对象方法&#xff08;属于对象阶层和非静态方法同时加载在类加载之后&#xff09;&#xff09; 2、非静态成员内部类无法在该类&#xff08;就是非静态成员内部类所在的类&#xff09;的静态方法中…

期望18K,4年前端Cvte 视源股份一面挂

一面 1、自我介绍&#xff1f;毕业的时候一直在 xx 公司&#xff0c;你基本都在做什么项目&#xff1f; 2、你讲一下你主要负责哪一块的&#xff1f;balabala 3、你们的 json 是怎么定义组件间的联动的&#xff1f; 4、怎么确定区分两个 input&#xff1f; 5、你们是怎么触…