Mysql系列(四)彻底理解MVCC+行锁+表锁+间隙锁

2023-11-10

一. 什么是MVCC

MVCC(Multi-Version Concurrency Control),即多版本并发控制。不使用锁,主要是用来提高数据库的并发性能;算是一种概念,不同的数据库有不同的实现方式,本文主要介绍mysql的innodb引擎中的实现方式。

在mysql的innodb中,前面我们有篇文章《Mysql系列(二)Mysql事务四大隔离级别详解&演示》分析了4种隔离级别,以及每种隔离级别下导致的问题,脏读、不可重复读、幻读。其中不可重复读、幻读就是使用MVCC来解决的。

二.什么是行锁、表锁、间隙锁

首先锁的存在,目的是为了在并发场景下,保持数据的安全、一致。
并发场景有:

  • 读-读 :此并发场景不需要进行并发控制,也就是不需要加锁。
  • 读-写 :此并发场景需要并发控制,不然就会出现脏读,幻读,不可重复读的问题。
  • 写-写 :此并发场景需要并发控制,不然就会出现更新丢失的问题。

进行并发控制,常规手段就是加锁,不管是咋java业务代码中,还是mysql数据库本身,都有实现自己的锁,其中mysql的锁有以下几种:

  • 行锁:锁住表中的一行;比如 update user set name=‘张三’ where id=1;会锁住id=1的那一行数据,其他事务再想更新,就只能等前一个事务释放锁。
  • 表锁:锁住整个表,比如update user set name=‘张三’;由于没有加where条件,此更新sql会对整个表进行更新,也就是会锁住整个表。
  • 间隙锁:比如事务A执行update user set name=‘张三’ where id >1 and id<4; 假如表中只有id=1、2 两条数据,A事务还没提交,那么此时事务B再次插入一条id=3的数据,理论上是允许的,但是实际上是B只能等A提交,因为事务A执行的是id>1and id<4,范围涵盖了id=3的,也即是把id=3的这个间隙也给锁了,叫做间隙锁

除了这3种锁,还有乐观锁、悲观锁、记录锁、自增锁、意向锁;

三. MVCC与各种锁的关系

既然可以使用行锁、表锁、间隙锁来保证数据操作的安全性,那么还要MVCC的出现是为何呢? 实际是因为在性能方面还有优化的空间

虽然使用锁可以保证数据安全,但是毕竟加了锁就意味着并发性能的降低,因此,能不使用锁就尽量不使用锁。在某些场景下,MVCC可以在比使用锁更快。

在读-读、读-写、写-写这3种并发场景中,读-写 可以不使用锁,而是使用MVCC来实现数据的并发操作以及安全一致性

因此,mysql是同时使用了MVCC+行锁、表锁、间隙锁来保证了数据安全,又尽可能大的实现了性能最优化。

四. MVCC的实现原理

4.1 多版本

那么不使用锁,MVCC是如何更高效的解决读-写这种并发场景下的数据安全呢?
我们知道,事务在执行失败时,会将数据回滚为上个版本,而MVCC叫做多版本并发控制,核心概念就在版本上,也就是说数据库存储了多个版本的数据。

多个版本整体上分为两类:最新版本历史版本
这也牵扯出来另外两个概念:

  • 快照读:读取的是数据库种历史版本的数据;
    常规的select * from user ;属于是快照读;
  • 当前读:读取的是数据库种最新版本的数据;当前读的操作有:
    select * from user in share mode(共享锁),;
    select * from user for update;
    update, insert ,delete(排他锁)

那么多个版本,mysql是如何存储的呢?

innodb存储引擎中,我们存在表中的数据,除了我们设置的业务字段,另外还有3个默认字段,如下图末尾3个:
在这里插入图片描述

  • DB_TRX_ID: 事务id,存的是创建事务的id,或者最后一次更新事务的id;
  • DB_ROW_ID: 主键id,建表时如果没设置主键,则此字段会成为主键发挥作用;
  • DB_ROLL_PTR: 回滚指针,指向上一个版本的数据,如果没有上个版本,则为null。

其中,DB_ROLL_PTR结合undo log实现。

4.2 undo log

undo log称为回滚日志,是InnoDB MVCC事务特性的重要组成部分,存在形式就是一种日志文件。

undo log的数据结构,非常复杂,可以简单理解为链表,链表头部存储最新版本,尾部存储最早版本。通过遍历链表,就可以找到对应版本的数据。
在这里插入图片描述
大多数对数据的变更操作包括INSERT/DELETE/UPDATE,其中,

  • INSERT操作使用insert_undo,因为新插入就只有一个版本,因此产生的Undo日志可以在事务提交后直接删除;
  • 而对于UPDATE/DELETE则需要维护多版本信息,在InnoDB里,UPDATE和DELETE操作产生的Undo日志被归成一类,即update_undo;mvcc使用的undolog,就是update_undo。

只有undolog,还不足以实现mvcc,因为既然undolog维护了那么多版本,遍历的时候,应该去找哪一个版本呢?这里必然牵扯到一种规则,这种规则在不同的数据库隔离级别下是不一样的。

innodb具体实现的时候,使用了一种叫做readview的定西。

4.2 readview

readview称为读视图,是事务在进行快照读的时候产生的,算是一种数据结构。

readview中包含3个参数:

  • trx_list :系统活跃的(事务在执行,还没有提交)事务id列表;
  • up_limit_id :trx_list列表中最小的事务id;
  • low_limit_id :ReadView生成时刻系统尚未分配的下一个事务ID,也就是目前已出现过的事务ID的最大值+1;比如当前事务id已经分配到了4,那么low_limit_id的值就是5;

每个事务在进行自己的快照读时,都会产生自己事务对应的readview。

例如下图中:
在这里插入图片描述
有4个事务同时在执行,事务id分别为1,2,3,4;其中,1,2,3还没有提交,4已经提交,那么当事务2在进行快照读时,产生一个readview,其trx_list存的就是活跃的1,2,3,如下图:
在这里插入图片描述
此时,最小的事务id是1,最大的事务id是5 (尚未分配的下一个id),当前最新的事务id是4 (事务4的id)。

可见性算法
上图中右侧黄色部分就是本次查询到底该取哪个版本数据的规则,也叫可见性算法;

查找过程:
遍历undolog的最新数据到最老数据,逐个判断每条log的事务id,当作DB_TRX_ID,然后使用上图中黄色可见性算法比对,最终确定当前遍历的数据是不是目标数据。

读视图的产生时机
在不同的隔离级别下,readview产生的时机是不同的:

  • RC :每次进行快照读的时候,都会产生新的readview;
  • RR :只有在第一次进行快照读的时候,才会产生readview,之后的操作都会使用第一次生成的readview。如果此事务中间发生了update等当前读操作,也会生成新的readview。

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Mysql系列(四)彻底理解MVCC+行锁+表锁+间隙锁 的相关文章

随机推荐

  • 服务器上创建Python虚拟环境

    应用场景 不同的项目 或者同一项目的不同版本 需要安装不同的Python解释器和依赖库 对于有python版本依赖的程序来说 为了安全可靠的管理环境 需要创建不同版本的 独立 隔离 的虚拟环境 virtualenv 是一个创建隔绝的Pyth
  • Java设计与实现“秒杀”活动之抢粽子【完整版】

    五月榴花妖艳烘 绿杨带雨垂垂重 五月新丝缠角粽 金盘送 生绡画扇盘双凤 正是浴兰时节动 正值端午佳节 实习公司也是例行放假三天以及给每一位员工发放了节日小礼品 过完端午又将迎来618活动专场 秒杀抢单活动也是此起彼伏 从而产生刺激性消费 由
  • 使用HiBurn烧录鸿蒙.bin文件到Hi3861开发板

    使用HiBurn烧录鸿蒙 bin文件到Hi3861开发板 鸿蒙官方文档的 Hi3861开发板第一个示例程序 中描述了 如何使用DevEco Device Tool工具烧录二进制文件到Hi3861开发板 本文将介绍如何使用HiBurn工具烧录
  • 网站服务器放本地还是云上,服务器放本地还是云上安全

    服务器放本地还是云上安全 内容精选 换一换 在弹性云服务器上安装完成后输入公网IP 无法连接目的虚拟机 端口无法访问工具 源端网络未连通目的端 目的端安全组未开放8084端口 目的端网络ACL禁用了8084端口 登录源端服务器后 在源端服务
  • Leetcode 计算质数 -- 埃氏筛、线性筛解析

    0 题目描述 leetcode原题链接 204 计数质数 1 埃氏筛 很直观的思路是我们枚举每个数判断其是不是质数 枚举没有考虑到数与数的关联性 因此难以再继续优化时间复杂度 介绍一个常见的算法 该算法由希腊数学家厄拉多塞 Eratosth
  • C语言/实现MD5加密

    本文详细视频讲解 已经发布到B站 https www bilibili com video BV1uy4y1p7on 更多仔细 请关注公众号 一口Linux 一 摘要算法 摘要算法又称哈希算法 它表示输入任意长度的数据 输出固定长度的数据
  • C语言头文件路径相关问题总结说明

    聊聊系统路径位置 绝对路径与相对路径 正斜杠 与 反斜杠 使用说明 by 矜辰所致 目录 前言 一 C语言中的头文件引用 二 KEIL 中的头文件路径 2 1 IncudePaths 指定的路径 绝对路径和相对路径 正斜杠 与 反斜杠 与双
  • SpringBoot Sleuth Zipkin Dubbo日志链路追踪全流程(2)

    SpringBoot SpringCloud Sleuth Zipkin Dubbo日志链路追踪全流程 看这篇文章之前 你最好看一下 之前的文章 SpringBoot SpringCloud Sleuth Zipkin Http Log4j
  • RC电路(一):微分

    1 充放电时间常数 在模拟 数字电路中 常常用到由电阻 和电容 组成的 电路 和 的取值不同 会导致输出波形和输入波形之间的关系也不同 由此也会产生不同的应用 当 时 电容电压 0 63E 当 时 电容电压 0 86E 当 时 电容电压 0
  • 通用嵌入式系统测试平台 ETest简介

    通用嵌入式系统自动化测试平台 通用嵌入式系统测试平台 Embedded System Interface Test Studio 简称 ETest 是针对嵌入式系统进行实时 闭环 非侵入式测试的自动化测试平台 适用于嵌入式系统在设计 仿真
  • 《阵列信号处理及MATLAB实现》绪论、矩阵代数相关内容总结笔记

    第一章 绪论 1 1 研究背景 1 1 1 阵列信号处理简介 将一组传感器按照一定方式布置在空间的不同位置 形成传感器阵列 用传感器阵列来接收空间信号 相当于对空间分布的场信号采样 得到信号源的空间离散观测数据 通过对阵列接受的信号进行处理
  • Lex和Yacc应用方法(一).初识Lex

    Lex和Yacc应用方法 一 初识Lex 草木瓜 20070301 Lex Lexical Analyzar 词法分析生成器 Yacc Yet Another Compiler Compiler编译器代码生成器 是Unix下十分重要的词法分
  • Feign的使用

    基于Feign远程调用 Feign说明 Feign是一个声明式的http客户端 其作用是帮助我们优雅的实现http请求的发送 官网地址 https github com OpenFeign feign Feign的使用 修改服务的pom x
  • MVC中的项目案例

    我们先一起来看看超期的效果图吧 以上就是超期的效果图 我来解析一下 超期操作的模态窗体弹出的条件与归还一样 应选择需要超期的书籍 再弹出模态窗体 模态窗体弹出 数据自动回填上去 罚款金额 超期天数 0 2 获取当前时间为罚款时间 罚款成功后
  • 解决python3在import cv2时报错问题

    在安装了ros 在import cv2时会报错 如下 import cv2 ImportError opt ros kinetic lib python2 7 dist packages cv2 so undefined symbol Py
  • CMake(七):函数和宏

    回顾到目前为止涉及的材料 CMake的语法已经开始看起来很像一门编程语言 它支持变量 if then else逻辑 循环和包含要处理的其他文件 毫无疑问 CMake还支持常用的函数和宏编程概念 就像它们在其他编程语言中的角色一样 函数和宏是
  • vistual studio 2017中导入pthread.h的配置方法

    1 下载pthread h的相关库文件 下载路径 https www mirrorservice org sites sourceware org pub pthreads win32 pthreads w32 2 9 1 release
  • 从技术小白到编程大神的技术书籍推荐

    本人算不上大神 也非计算机专业出身 本着一股热爱技术的精神 研究过各种计算机技术 对于知识的索取方式 比较习惯看书 当然 随着认识的加深 以及新技术的层出不穷 也常接触各种技术文档 早些时候阅读过很多不错的计算机书籍 对于计算机底层的深入认
  • spring boot 提示:程序包不存在,解决方法总结

    背景 之前出现过这样的问题 打包安装父项目就好了 今天改了一下代码 重新编译的时候 又出现了这样的情况 决定深度挖掘一下这里面的问题 spring boot 提示 程序包不存在 解决方法总结 spring boot 提示 程序包不存在 解决
  • Mysql系列(四)彻底理解MVCC+行锁+表锁+间隙锁

    文章目录 一 什么是MVCC 二 什么是行锁 表锁 间隙锁 三 MVCC与各种锁的关系 四 MVCC的实现原理 4 1 多版本 4 2 undo log 4 2 readview 一 什么是MVCC MVCC Multi Version C