[Mysql]MVCC

news/2024/10/6 3:54:00/文章来源:https://www.cnblogs.com/DCFV/p/18285735

多版本并发控制 MVCC

MySQL的大多数事务型存储引擎实现的都不是简单的行级锁。基于提升并发性能的考虑,它们一般都同时实现了多版本并发控制(MVCC)。不仅是MySQL,包括Oracle、PostgreSQL等其他数据库系统也都实现了MVCC,但各自的实现机制不尽相同,因为MVCC没有一个统一的实现标准。

可以认为MVCC是行级锁的一个变种,但是它在很多情况下避免了加锁操作,因此开销更低。虽然实现机制有所不同,但大都实现了非阻塞的读操作,写操作也只锁定必要的行。

MVCC的实现,是通过保存数据在某个时间点的快照来实现的。也就是说,不管需要执行多长时间,每个事务看到的数据都是一致的。根据事务开始的时间不同,每个事务对同一张表,同一时刻看到的数据可能是不一样的。如果之前没有这方面的概念,这句话听起来就有点迷惑。熟悉了以后会发现,这句话其实还是很容易理解的。

前面说到不同存储引擎的MVCC实现是不同的,典型的有乐观(optimistic)并发控制悲观(pessimistic)并发控制。下面我们通过InnoDB的简化版行为来说明MVCC是如何工作的。

InnoDB的MVCC,是通过在每行记录后面保存两个隐藏的列来实现的。这两个列,一个保存了行的创建时间,一个保存行的过期时间(或删除时间)。当然存储的并不是实际的时间值,而是系统版本号(system version number)。每开始一个新的事务,系统版本号都会自动递增。事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号进行比较。下面看一下在REPEATABLE READ 隔离级别下,MVCC具体是如何操作的。

SELECT

InnoDB会根据以下两个条件检查每行记录:

  • a. InnoDB只查找版本早于当前事务版本的数据行(也就是,行的``系统版本号小于或等于事务的系统版本号`),这样可以确保事务读取的行,要么是在事务开始前已经存在的,要么是事务自身插入或者修改过的。

  • b. 行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。

只有符合上述两个条件的记录,才能返回作为查询结果。

INSERT

InnoDB为新插入的每一行保存当前系统版本号作为行版本号。

DELETE

InnoDB为删除的每一行保存当前系统版本号作为行删除标识。

UPDATE

InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

保存这两个额外系统版本号,使大多数读操作都可以不用加锁。这样设计使得读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行。不足之处是每行记录都需要额外的存储空间,需要做更多的行检查工作,以及一些额外的维护工作。

MVCC只在REPEATABLE READ 和READ COMMITTED 两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容 (4) ,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE则会对所有读取的行都加锁。

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

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

相关文章

在wsl中部署puppeteer的相关笔记

二. 缺少依赖问题反复提示缺少各种依赖,到处搜刮一顿操作之后是没问题了,但也不知道哪些是无所谓的 apt install -y gconf-service libc6 libcairo2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libstdc++6 libx11-6 apt inst…

《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》课后习题答案(带解析)(七)

此系列答案配套《计算机组成与系统结构(第二版) 裘雪红 李伯成 西安电子科技大学出版社》一书相关内容。所有内容为博主个人编辑,仅作参考学习交流之用,转载请注明出处。如发现错误,请联系博主及时勘误。如有侵权行为,博主将立即下架全部内容。声明:此系列答案配套《计…

【设计模式(二)】创建型模式--抽象工厂模式

创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是“将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。抽象工厂模式也是⼀种创建型设计模式,提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类 抽象工厂…

[Java] Java 关键字 : transient

0 序 Java中的transient关键字,transient是短暂的意思。对于transient修饰的成员变量,在类的实例对象的序列化处理过程中会被忽略。 因此,transient变量不会贯穿对象的序列化和反序列化,生命周期仅存于调用者的内存中而不会写到磁盘里进行持久化。 1 序列化Java中对象的序列…

告别 .NET 7,支持将于 5 月结束——我们几乎不认识你

微软 .NET 7 软件框架的支持将于 5 月结束,这距离其 2022 年发布仅过去 18 个月——这提醒我们,长期更新时代正在成为过去。 .NET 7 于 2022 年 11 月 8 日首次亮相,与其前身不同的是,它是一个标准期限支持 (STS) 版本,这意味着它的支持期为 18 个月。.NET 6 和 .NET 8 都…

在Ubantu22.04中运行ORB_SLAM3

在Ubantu22.04中运行ORB_SLAM3 一、概述 ORB-SLAM3是一个支持视觉、视觉加惯导、混合地图的SLAM系统,可以在单目,双目和RGB-D相机上利用针孔或者鱼眼模型运行。从第一版的单目相机系统,到第二版加入了对stereo以及RGBD camera的支持,再到目前最新版本的orb-slam整合了visua…

gitlab 解锁账号

现象 登录gitlab后显示 账号被锁,登录方式AD域 管理员后台查看账号 如果是在gitlab导致的锁,那么账号显示的就是Blocked,如果是LDAP导致就是LDAP Blocked,并且后者无法在gitlab UI界面解锁 解锁登录控制端 gitlab-rails console搜索用户user = User.find_by_email("m…

centos 7 ip地址配置

然后输入如下命令: /etc/init.d/network restart我只想安静地学习,捡拾前人的牙慧,默默强大如此弱小的我...

手把手教你解决spring boot导入swagger2版本冲突问题,刘老师教编程

手把手教你解决spring boot导入swagger2版本冲突问题本文仅为个人理解,欢迎大家批评指错首先Spring Boot 3 和 Swagger 2 不兼容。在 Spring Boot 3 中,应该使用 Springdoc 或其他与 Spring Boot 3 兼容的 API 文档工具来替代 Swagger 2。 Swagger 2 的依赖底层使用的是 java…

Linux(Centos7)安装Docker 社区(ce)版

安装准备 查看Linux系统版本是否为centos7 cat /etc/os-release确保系统内核为3版本以上 uname -a安装Docker 如之前安装过请卸载 yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker…

srpingboot 初识

依赖管理父项目(一直网上找)spring-boot-dependencies 决定了当前 springboot 预先配置的所有依赖及版本<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.3.4.RELEAS…

windows配置环境变量

前言 环境变量的目的是为了让为了终端简化命令行操作,使系统能够找到所需的程序和工具或文件,并优化系统的运行环境。 比如我有一个文件 D:\doc\a.txt ,如果我们打开终端打开此文件,则需要输入D:\doc\a.txt但是如果我们将D:\doc配置为环境变量,我们则可以直接终端中输入 a…