MySQL 用了哪种默认隔离级别,实现原理是什么?

MySQL 的默认隔离级别是 RR - 可重复读,可以通过命令来查看 MySQL 中的默认隔离级别。

RR - 可重复读是基于多版本并发控制(Multi-Version Concurrency Control,MVCC )实现的。MVCC,在读取数据时通过一种类似快照的方式将数据保存下来,不同事务的 session 会看到自己特定版本的数据,这样读锁和写锁就不冲突了。

在 InnoDB 存储引擎里,在有聚簇索引的情况下,每行数据都包含两个必要的隐藏列:

  • DB_TRX_ID:记录某条数据的上次修改它的事务ID(trx_id)
  • DB_ROLL_PTR:回滚指针,指向这条记录的上一个版本。我们每次对聚簇索引行进行修改时,都会把老版本写入到undo日志里,这个指针就指向了老版本的位置,当需要进行回滚操作时,事务就通过回滚指针以获取上一个版本的数据(注意:插入操作的undo日志没有回滚指针,因为它是新增的数据,没有老版本;而已删除的信息会在undo日志记录的头信息中存一个delete flag标记,当该标记为true时,表示已删除,则不返回数据)。

下图就是一个简洁的版本链概念,InnoDB 中的 undo 日志保存的就是一个版本链:

除了版本链,我们在实现 MVCC 还用到了另一个概念:read-view,一致性试图。我们在查询数据,当使用 select 语句时,InnoDB 会自动生成一个当前活动的(即未提交的)事务 ID 数组,这个 read-view 就是由查询时所有未提交事务 ID 组成的数组。数组中最小的事务 ID 为 min_id 和已创建的最大事务 ID 为 max_id 组成,查询的数据结果需要跟 read-view 做比较从而得到快照结果。

我们做查询时,会查询出当前 session 的 trx_id,通过和 read-view 比对:

  1. 若 trx_id 比 read-view 中的 min_id  小,则该版本是已经提交的事务生成,一定可见;
  2. 若 trx_id 比 read view 中的 max_id 大,则该版本是还未提交的事务生成,一定不可见;
  3. 当 trx_id 在 read-view 列表中,即 min_id <= trx_id <= max_id时,如果 trx_id 在 read-view 的数组中,则还未提交,不可见,但是当前事务是可见的;如果 trx_id 不在数组中,表明是已经提交的事务,则该版本可见。

当版本不可见时,需要通过 DB_ROLL_PTR 获取上一版本的 trx_id,再次比对,直到版本数据可见时,返回结果。

就以上比对的三种情况,用图示说明下:

transaction 100transaction 101select
update user set name = 'zhangsan' where id = 1
commit
update test set age = 18 where id = 2
select name from use where id=1

1)select 语句执行时,上次更新的 trx_id 为 100,read-view 中未提交的事务为 [101]。此时 read-view 的 min_id 为 101,trx_id 比它小,则该版本是已经提交的事务生成,所以返回 zhangsan。

2)假设当前 select 的 trx_id 为 102,read-view 中未提交的事务为 [101],则需要通过 DB_ROLL_PTR 获取上一版本的 trx_id 100,注意 trx_id 为 101 的事务是改变了另一张表的数据,所以 undo 日志里版本链指向的上一条数据 trx_id 为 100,还是会返回 zhangsan。

3)当 trx_id 在 read-view 中间时:

transaction 100transaction 101select
update user set name = 'zhangsan' where id = 1
commit
update test set name='wangwu' where id = 1
select name from use where id=1

此时 trx_id 为 101,read-view 为 [101],当前事务 ID 在数组中,所以不可见。需要用 DB_ROLL_PTR 找到上一条版本的位置 trx_id 为 100,还是会返回 zhangsan。

RC 隔离级别在查询时,同一个事务多次查询,每次会生成独立的 read-view。而 RR - 可重复读只在第一次查询时生成统一的 read view,之后的读取都复用之前的 read view。而 RU - 读未提交是可以读取还没提交的数据,没有 undo 版本的概念;可串行化隔离级别在每次读取时都需要加锁控制,没法并发,所以通过版本的概念去控制并发也就没有意义。

transaction 100transaction 101select
update user set name = 'zhangsan' where id = 1
commit
update test set age = 18 where id = 2
select name from use where id=1
update user set name = '666' where id = 1
select name from use where id=1

当使用 RC 级别时,两次 select 的 read-view 不一样,第一次查询时是 [101],第二次是 [100, 101]。而用 RR 级别时,会复用第一次查询的 read-view,故多次查询的结果是一样的。这也是 MySQL 的隔离级别默认用 RR - 可重复读的原因之一,不用重复生成 read-view,提升数据库的操作性能。

总结

每次 select 数据时生成 read view 列表,再配合 undo 日志中的版本链,让不同的事务读-写,写-读操作可以并发执行,进而实现 MVCC。

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

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

相关文章

特斯拉一面算法原题

来自太空的 X 帖子 埃隆马斯克&#xff08;Elon Musk&#xff09;旗下太空探索技术公司 SpaceX 于 2 月 26 号&#xff0c;从太空往社交平台 X&#xff08;前身为推特&#xff0c;已被马斯克全资收购并改名&#xff09;发布帖子。 这是 SpaceX 官号首次通过星链来发送 X 帖子&a…

在线上传解压PHP文件代码,压缩/压缩(网站一键打包)支持密码登录

在线上传解压PHP文件代码&#xff0c;压缩/压缩(网站一键打包)支持密码登录 资源宝分享&#xff1a;www.httple.net 如果你没有主机控制面板这个是最好选择&#xff0c;不需要数据库&#xff0c;上传当控制面板使用&#xff0c;无需安装任何扩展&#xff0c;安全高&#xff0c;…

在 Rust 中实现 TCP : 1. 联通内核与用户空间的桥梁

内核-用户空间鸿沟 构建自己的 TCP栈是一项极具挑战的任务。通常&#xff0c;当用户空间应用程序需要互联网连接时&#xff0c;它们会调用操作系统内核提供的高级 API。这些 API 帮助应用程序 连接网络创建、发送和接收数据&#xff0c;从而消除了直接处理原始数据包的复杂性。…

pyspark分布式部署随机森林算法

前言 分布式算法的文章我早就想写了&#xff0c;但是一直比较忙&#xff0c;没有写&#xff0c;最近一个项目又用到了&#xff0c;就记录一下运用Spark部署机器学习分类算法-随机森林的记录过程&#xff0c;写了一个demo。 基于pyspark的随机森林算法预测客户 本次实验采用的…

前端sql条件拼接js工具

因为项目原因&#xff0c;需要前端写sql&#xff0c;所以弄了一套sql条件拼接的js工具 ​ /*常量 LT : " < ", LE : " < ", GT : " > ", GE : " > ", NE : " ! ", EQ : " ", LIKE : " like &qu…

2024有哪些免费的mac苹果电脑深度清理工具?CleanMyMac X

苹果电脑用户们&#xff0c;你们是否经常感到你们的Mac变得不再像刚拆封时那样迅速、流畅&#xff1f;可能是时候对你的苹果电脑进行一次深度清理了。在这个时刻&#xff0c;拥有一些高效的深度清理工具就显得尤为重要。今天&#xff0c;我将介绍几款优秀的苹果电脑深度清理工具…

浅谈 Linux 孤儿进程和僵尸进程

文章目录 前言孤儿进程僵尸进程 前言 本文介绍 Linux 中的 孤儿进程 和 僵尸进程。 孤儿进程 在 Linux 中&#xff0c;就是父进程已经结束了&#xff0c;但是子进程还在运行&#xff0c;这个子进程就被称作 孤儿进程。 需要注意两点&#xff1a; 孤儿进程最终会进入孤儿院…

数据结构-带头双向循环链表

文章目录 一.头结点二.双链表1双链表的概念与结构2.与单链表相比 三.循环链表1.关于循环链表2.循环链表的优点 四.带头双向循环链表1.带头双向循环链表2.结构图3.实现 五.代码一览 一.头结点 在链表中设置头结点的作用是什么 标识链表:头结点是链表的特殊节点,它的存在能够明确…

springboot基于web的网上摄影工作室的开发与实现论文

网上摄影工作室 摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了网上摄影工作室的开发全过程。通过分析网上摄影工作室管理的不足&#xff0c;创建了一个计算机管理网上摄影工作室的方案。文章介绍了网上摄影工…

1.亿级积分数据分库分表:总体方案设计

项目背景 以一个积分系统为例&#xff0c;积分系统最核心的有积分账户表和积分明细表&#xff1a; 积分账户表&#xff1a;每个用户在一个品牌下有一个积分账户记录&#xff0c;记录了用户的积分余额&#xff0c;数据量在千万级积分明细表&#xff1a;用户每次积分发放、积分扣…

gitlab添加ssh公钥

一&#xff1a;生成公钥 桌面鼠标右击打开 Open Git Bash here (前提是安装了Git)&#xff1b; 2.输入命令 ssh-keygen -t rsa -C "123*****90qq.com"来生成新的密钥对,将其中的"123*****90qq.com"替换为你自己的电子邮件地址。 命令&#xff1a;ssh-keyg…

MWC 2024丨美格智能推出5G RedCap系列FWA解决方案,开启5G轻量化新天地

2月27日&#xff0c;在MWC 2024世界移动通信大会上&#xff0c;美格智能正式推出5G RedCap系列FWA解决方案。此系列解决方案具有低功耗、低成本等优势&#xff0c;可以显著降低5G应用复杂度&#xff0c;快速实现5G网络接入&#xff0c;提升FWA部署的经济效益。 RedCap技术带来了…

Linux之嫁衣神功

前言&#xff1a;此博客内容全部转载他人&#xff0c;无一原创&#xff0c;初衷转播优质内容 1 挂载的作用 扩展存储空间 将额外的存储设备连接到Linux系统中&#xff0c;扩展系统的存储容量。 实现数据共享 不同计算机之间可以共享文件和数据&#xff0c;实现更高效的协作…

强大!信息安全技术导图全汇总!共200多张(附下载)

从网络上搜集整理了200多张信息安全技术导图&#xff0c;文末有免费领取方式。 详细文件目录 APT 攻击/ APT 攻击.png APT攻防指南基本思路v1.0-SecQuan.png Red Teaming Mind Map.png Windows常见持久控制.png 发现与影响评估.jpg …

Unity的相机跟随和第三人称视角

Unity相机跟随和第三人称视角 介绍镜头视角跟随人物方向进行旋转的镜头视角固定球和人的镜头视角 思路跟随人物方向进行旋转的镜头视角固定球和人的镜头视角 镜头旋转代码人物移动的参考代码注意 介绍 最近足球项目的镜头在做改动&#xff0c;观察了一下实况足球的视角&#x…

html基本标签

<h1></h1> <p></p> h是标签从h1~h6&#xff0c;没用h7,h8 p是段落 <a href"https://www.educoder.net">Educoder平台</a> href可以指定链接进行跳转 <img src"https://www.educoder.net/attachments/download/2078…

跨境知识分享:什么是动态IP?和静态IP有什么区别?

对于我们跨境人来说&#xff0c;清楚地了解IP地址、代理IP等这些基础知识&#xff0c;并学会正确地使用IP地址对于保障店铺的安全性和稳定性至关重要&#xff0c;尤其是理解动态IP和静态IP之间的区别&#xff0c;以及如何利用这些知识来防止账号关联&#xff0c;对于每个电商卖…

深入理解分库、分表、分库分表

前言 分库分表&#xff0c;是企业里面比较常见的针对高并发、数据量大的场景下的一种技术优化方案&#xff0c;所谓"分库分表"&#xff0c;根本就不是一件事儿&#xff0c;而是三件事儿&#xff0c;他们要解决的问题也都不一样&#xff0c;这三个事儿分别是"只…

Nodejs 第四十二章(jwt)

什么是jwt? JWT&#xff08;JSON Web Token&#xff09;是一种开放的标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用间传递信息的一种方式。它是一种基于JSON的安全令牌&#xff0c;用于在客户端和服务器之间传输信息。 https://jwt.io/ JWT由三部分组成&…

Qt 自定义长条进度条(类似播放器进度条)

1.运行界面 2.步骤 其实很简单。 2.1绘制底图圆角矩形 2.2绘制播放进度圆角矩形 参考&#xff1a;painter绘图 3.源码 #pragma once#include <QWidget> #include <QLabel> #include <QHBoxLayout> #include <QMouseEvent> #include <QDebug&g…