MySQL知识点总结(四)——MVCC

MySQL知识点总结(四)——MVCC

  • 三个隐式字段
    • row_id
    • trx_id
    • roll_pointer
  • undo log
  • read view
  • MVCC与隔离级别的关系
  • 快照读和当前读

MVCC全称是Multi Version Concurrency Control,也就是多版本并发控制。它的作用是提高事务的并发度,通过MVCC机制,数据库可以不通过加锁,也能保证事务的隔离性。MySQL的InnoDB存储引擎也有自己的MVCC机制的实现,通过MVCC机制保证了“读已提交”和“可重复读”两个隔离级别下的隔离性。

要理解MVCC,就要理解InnoDB里面的三样东西:“数据行记录中的三个隐式字段”、“undo log”、“read view”。理解了这三个东西,也就是理解了MVCC。

在这里插入图片描述

三个隐式字段

当我们使用InnoDB作为我们某个库表的存储引擎时,我们添加到该库表中的数据行记录,InnoDB都会默认给该行记录添加三个隐式字段,这三个隐式字段分别是“row_id”、“trx_id”、“roll_pointer”。

在这里插入图片描述

row_id

这个是InnoDB为每一个行记录生成的一个唯一的id,它和主键一样,都可以唯一标识一条行记录。当我们没有给我们的库表定义主键、也没有定义唯一索引时,InnoDB就会拿它来作为库表的主键。

于是,InnoDB中库表主键的选取,首先看库表是否有显式定义主键列,如果有,那么当前库表的主键就是我们显式定义的主键列;如果没有定义主键,但是我们定义了唯一索引,那么当前库表的主键就是我们定义的唯一索引(多个唯一索引,选其中一个);如果我们没有定义主键列,也没有定义唯一索引,那么InnoDB就会把row_id作为当前库表的主键。

在这里插入图片描述

trx_id

“trx_id”是事务id,记录的是当前行记录是被哪个事务修改提交的。

InnoDB会为每个开启的事务分配一个递增的id,用于唯一标识一个事务,当某个事务修改了某个行记录时,就会在这个行记录的trx_id隐式字段中记录当前事务的id。

在这里插入图片描述

roll_pointer

roll_pointer是回滚指针,当一个事务对某库表的一条行记录进行修改时,会把该行记录先拷贝到undo log日志中作为一个历史版本,然后再对该行记录进行修改,并且使用一个roll_pointer指针指向undo log中该行记录的历史版本。

在这里插入图片描述

undo log

undo log是InnoDB的回滚日志,用于事务回滚。每次对库表进行增删改,InnoDB都会把涉及到的行记录的历史版本拷贝到undo log中,然后使用行记录中的隐式字段“roll_pointer”指向undo log中该行记录的最近的版本,这样,undo log就形成了一个链表,沿着roll_pointer回滚指针,我们可以不断的往前追溯某个行记录的历史版本。

在这里插入图片描述

有了undo log,就可以实现事务的可重复读,只要当前事务通过某种机制记住该行记录哪个历史版本对于自己是可见的,然后每次读取该行记录时都读取这个历史版本,就可以实现可重复读,其他事务也可以照常进行更新操作,不会被阻塞。

而这个机制就是“read view”,read view记录了当前活跃的事务id,也就是已开启但还未提交的事务对于的事务id。有了“read view”,当前事务读取某库表的行记录时,就可以沿着roll_pointer指针往前进行遍历,拿到该行记录的每个版本对应的trx_id字段,在read view中进行比对,如果发现trx_id在read view中是存在的,那说明这个版本是当前某个活跃事务修改(但未提交)的,因此对于当前事务尚不可见,直到遍历到某个版本,发现在read_view中不存在,那么就可以读取这个版本。

在这里插入图片描述

read view

“read view”是一种快照,它不仅记录了当前有哪些事务正处于活跃状态,还记录了当前活跃事务中最小的id,以及下一个开启的事务将会被分配的事务id。

在这里插入图片描述

比如当前活跃的事务对应的事务id是5、4、3,那么read view就会通过一个列表trx_ids记录[3,4,5]。通过trx_ids可以得知,当最小的活跃事务id是3,InnoDB用一个变量up_limit_id记录这个3,然后下一个开启的事务被分配的事务id是6,InnoDB用一个变量low_limit_id记录这个6。

在这里插入图片描述

这样,通过read view不但可以得知当前活跃事务,也可以知道在当前事务开启前已经提交的最新事务是多少,比如这里的read view记录的时[3,4,5],那就可以知道在当前事务开启以前,最新提交的事务是2,那么trx_id小于等于2(trx_id < up_limit_id)的行记录对于当前事务都是可见的。

除此以外,也可以知道下一个要开启的事务被分配的事务id是多少,比如这里比如这里的read view记录的时[3,4,5],那就可以知道下一个要开启的事务会被分配事务id为6。如果在当前事务开启之后,又开启了其他事务,并且提交了修改,那么被修改的行记录的trx_id就是大于等于6的(trx_id >= low_limit_id),对于当前事务来说是不可见,只能沿着roll_pointer往前追溯,读取历史版本。

因此,当一个事务读取某库表的某行记录时,这个可见性的判断逻辑就是这样:

  1. 判断当前记录的trx_id是否小于up_limit_id:如果是,那么当前行记录对于当前事务是可见的;如果不是,执行下一步的判断逻辑(步骤2)。
  2. 判断trx_id是否大于等于low_limit_id:如果是,那么当前行记录对于当前事务是不可见的,只能沿着roll_pointer指针往前遍历,读取当前行记录的上一个历史版本,并且回到步骤1重新比对;如果不是,那么执行下一步的判断逻辑(步骤3)。
  3. 判断trx_id是否在trx_ids列表中:如果是,那么表示当前行记录是当前某个活跃的事务修改的,执行下一步判断逻辑(步骤4);如果不是,那么表示当前行记录是在当前事务开启并生成read view前就已经提交了的,那么对于当前事务来说可见,读取该版本的行记录。
  4. 判断trx_id是否是当前事务自己的id:如果是,那么表示是自己做的修改,还是可见的;否则对于当前事务来说也是不可见,只能沿着roll_pointer指针往前遍历,读取当前行记录的上一个历史版本,并且回到步骤1重新比对。

在这里插入图片描述

MVCC与隔离级别的关系

我们知道隔离级别从低到高有四个:读未提交、读已提交、可重复读、串行化。在InnoDB中,读已提交和可重复读这两个隔离级别就是通过MVCC保证的。

在读已提交隔离级别下,事务的每次SQL都会生成一个新的read view,这是它可以读到其他事务最新提交的修改的原因。比如现在有一个事务A读取某库表id为5的这一条记录,读到【name】字段的值“zhagnsan”。此时,另一个事务B修改了该库表id为5的这一行记录的【name】字段为“lisi”,并提交了。此时事务A再次读取该库表id为5的这一行记录,在读取前,会重新生成read view,由于事务B已经提交了,活跃事务列表trx_ids中就不包含事务B的事务id了,因此事务B修改id为5的行记录的【name】字段为“lisi”,是可以被事务A读到的,这就是不可重复读问题出现的原因。

在这里插入图片描述

而在可重复读隔离级别下,read view只在当前事务开启后,第一次发起读操作时生成一遍,后续就不再生成。也就是说,在可重复读隔离级别下,一个事务的read view一旦生成,后续就不再改变,即使中间有某个活跃的事务修改数据并提交了,当前事务的read view也不会发生变化,再次发起读操作时也不会再重新生成read view,因此read view的trx_ids中还是记录着这个已提交的事务的事务id,因此该修改对于当前事务就不可见,不会被当前事务读取到。

在这里插入图片描述

快照读和当前读

上面这种通过MVCC读取一个行记录的历史版本的做法,就是快照读,也就是说我们读到的是数据的历史版本。

而当前读则是保证读到的一定是当前行记录的最新版本,那什么时候会触发快照读,什么时候会触发当前读呢?

当一个事务开启以后,一般的select语句都是快照读,只有显式地添加“lock in share mode”或者“for update”的select语句才会进行当前读,因为这两个语句是加锁的语句,都已经要加锁了,就没有必要走MVCC的逻辑了。

除此以外,“update”、“insert”、“delete”等SQL也会触发当前读,因为增删改这种写操作必然是要基于最新的行记录的,如果对一个历史版本的数据进行修改是毫无意义的,并且写操作是需要保证绝对的隔离性的,否则就会发送更新丢失,因此写操作也会加锁,那么就会触发当前读。

在这里插入图片描述

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

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

相关文章

微信小程序课设(基于云开发)

微信小程序通过Laf云平台接入ChatGPT实现聊天&#xff0c;回答方式采用流式回答。 以下是图片展示其页面 回答次数通过卡密兑换 以下是对话页面的代码 <!--pages/content/content.wxml--><view class"container"><view class"div" hidde…

Android学习之路(29) Gradle初探

前言: 大家回想一下自己第一次接触Gradle是什么时候&#xff1f; 相信大家也都是和我一样&#xff0c;在我们打开第一个AS项目的时候&#xff0c; 发现有很多带gradle字样的文件&#xff1a;setting.gradle, build.gradle,gradle.warpper,以及在gradle文件中各种配置&#xff…

前端vue/react项目压缩图片工具@yireen/squoosh-browser

想要在前端项目中压缩图片&#xff0c;然后再上传到后端保存&#xff0c;就需要一个压缩工具的帮助&#xff0c;暂时有两个依赖库可以选择&#xff1a;image-conversion和yireen/squoosh-browser&#xff0c;看了官方仓库地址和更新时间等详情&#xff0c;发现还是yireen/squoo…

简单说说mysql的日志

今天我们通过mysql日志了解mysqld的错误日志、慢查询日志、二进制日志&#xff0c;redolog, undolog等。揭示它们的作用和用途&#xff0c;让我们工作中更能驾驭mysql。 redo 日志 如果mysql事务提交后发生了宕机现象&#xff0c;那怎么保证数据的持久性与完整性&#xff1f;…

课时13:变量基础_变量场景

2.1.1 变量场景 学习目标 这一节&#xff0c; 我们从 数据存储、变量场景、小结 三个方面来学习。 数据存储 数据存储 所谓的数据存储&#xff0c;我们从三方面来理解这句话&#xff1a;1、数据保存到哪里 -- 各种媒介&#xff0c;CPU、内存、磁盘、磁带、网盘...2、数据保…

HTML音频标签

新增的语义化的标签&#xff1a; 即直接给了一个具象化的盒子。 新增的多媒体标签&#xff1a; 视频格式&#xff1a; 当都不支持的时候会显示文字。 video仍然是可以看成一个盒子。 音频格式&#xff1a; 新增的input 表单控件&#xff1a; 新增的表单属性&#xff1a; 提示文…

WebSocket学习笔记以及用户与客服聊天案例简单实现(springboot+vue)

一&#xff1a;介绍&#xff1a; 二&#xff1a;http协议与websocket对比&#xff1a; 三&#xff1a;websocket协议&#xff1a; 四&#xff1a;实现&#xff1a; 4.1客户端&#xff1a; 4.2服务端&#xff1a; 五&#xff1a;案例&#xff1a; 环境&#xff1a;做一个书店…

【JSON2WEB】04 amis低代码前端框架介绍

1 什么是 amis amis 是一个低代码前端框架&#xff0c;它使用 JSON 配置来生成页面&#xff0c;可以减少页面开发工作量&#xff0c;极大提升效率。 看到amis一句话的介绍&#xff0c;感觉就是JSON2WEB要找的前端框架。 amis是百度开源的框架&#xff0c;毕竟是大厂&#xff0c…

有限合伙协议书(模板)上

第一章 合伙的目的和合伙经营范围 第一条 合伙目的&#xff1a;为了适应市场经济的发展&#xff0c;满足市场需求&#xff0c;按照《合伙企业法》规范企业行为&#xff0c;合伙人本着公平、平等、互利的原则&#xff0c;成立 聚源企业管理中心&#xff08;有限合伙&am…

回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小二乘支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小二乘支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小二乘支持向量机的数据多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于OOA-LSSVM鱼鹰算法…

C#入门详解_01_课程简介、C#语言简介、开发环境和学习资料的准备

文章目录 1. 课程简介2. C#语言简介3.开发环境与学习资料 1. 课程简介 开设本课程的目的 传播C#开发的知识&#xff0c;让更多的人有机会接触到软件开发行业引导有兴趣或者想转行的朋友进入软件开发行业 课程内容 完整讲述C#语言在实际软件开发中的应用采用知识讲述加实例程序…

全面认识DOS系统

目录 一、DOS系统的功能 1.执行命令和程序&#xff08;处理器管理&#xff09; 2.内存管理 3.设备管理 4.文件管理 5.作业管理 二、文件与目录 三、文件类型与属性 1.系统属性&#xff08;S&#xff09; 2.隐含属性&#xff08;H&#xff09; 3.只读属性&#xff08…