mvcc介绍

前提:在介绍mvcc之前,先简单介绍一下mysql事务的相关问题,mvcc归根结底是用来解决事务并发问题的,当然这个解决不是全部解决,只是解决了其中的一部分问题!
mysql事务
一、事务的基本要素(ACID)
  1、原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
   2、一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。比如A向B转账,不可能A扣了钱,B却没收到。
   3、隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。比如A正在从一张银行卡中取钱,在A取钱的过程结束前,B不能向这张卡转账。
   4、持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

二、事务的并发问题
  1、脏读:事务A读取了事务B未提交的数据,然后B回滚操作,那么A读取到的数据是脏数据 ----解决的基础隔离级别:读已提交
  2、不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果 不一致。----解决的基础隔离级别:可重复读
  3、幻读:是针对数据插入操作来说的,假设在事务A中按照某个条件先后两次查询数据库,两次查询结果的条数不同(事务B在事务A两次查询期间插入符合查询条件的新数据),这种现象称为幻读。—解决的基础隔离级别:串行化(针对一张表的操作,每一个session依次完成自己的操作:行锁 + 间隙锁)MySQL事务隔离级别和实现原理
  小结:不可重复读与幻读的区别可以通俗的理解为:前者是数据变了,后者是数据的行数变了。不可重复读的和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。

三、MySQL事务隔离级别

MVCC多版本并发控制

前提概要
什么是MVCC
什么是当前读和快照读?
当前读,快照读和MVCC的关系
MVCC能解决什么问题,好处是?
MVCC实现原理
隐式字段
undo日志
Read View(读视图)
例子
MVCC相关问题
RR是如何在RC级的基础上解决不可重复读的?
RC,RR级别下的InnoDB快照读有什么不同?
一、前提概要
什么是MVCC?
MVCC,全称Multi-Version Concurrency Control,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问。

什么是当前读和快照读?
在学习MVCC多版本并发控制之前,我们必须先了解一下,什么是MySQL InnoDB下的当前读和快照读?

当前读
像select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读,它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

快照读
简单的select操作就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于多版本并发控制,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销;既然是基于多版本,即快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本

MVCC能解决什么问题,好处是?
数据库并发场景有三种,分别为:

读-读:不存在任何问题,也不需要并发控制
读-写:有线程安全问题,可能会造成事务隔离性问题,可能遇到脏读,幻读,不可重复读
写-写:有线程安全问题,可能会存在更新丢失问题
MVCC带来的好处是?
多版本并发控制(MVCC)是一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,读操作只读该session的数据库的快照。 所以MVCC可以为数据库解决以下问题

在并发读写数据库时,可以做到在读操作时不用阻塞写操作,写操作也不用阻塞读操作,提高了数据库并发读写的性能
二、MVCC的实现原理
它的实现原理主要是依赖记录中的 3个隐式字段,undo日志 ,Read View 来实现的。
隐式字段
每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID等字段

DB_TRX_ID
6byte,最近修改(修改/插入)事务ID:记录创建这条记录/最后一次修改该记录的事务ID
DB_ROLL_PTR
7byte,回滚指针,指向这条记录的上一个版本(存储于rollback segment里)
DB_ROW_ID
6byte,隐含的自增ID(隐藏主键),如果数据表没有主键,InnoDB会自动以DB_ROW_ID产生一个聚簇索引
实际还有一个删除flag隐藏字段, 既记录被删除并不代表真的删除,而是删除flag变了

如上图,DB_ROW_ID是数据库默认为该行记录生成的唯一隐式主键,DB_TRX_ID是当前操作该记录的事务ID,而DB_ROLL_PTR是一个回滚指针,用于配合undo日志,指向上一个旧版本

undo日志
undo log主要分为两种:

insert undo log
代表事务在insert新记录时产生的undo log, 只在事务回滚时需要,并且在事务提交后可以被立即丢弃
update undo log
事务在进行update或delete时产生的undo log; 不仅在事务回滚时需要,在快照读时也需要;所以不能随便删除
对MVCC有帮助的实质是update undo log ,undo log实际上就是存在rollback segment中旧记录链,它的执行流程如下:

一、 比如有个事务在persion表插入了一条新记录,记录如下,name为Jerry, age为24岁,隐式主键是1,事务ID和回滚指针,我们假设为NULL。为演示,插入提交后,该undo log被删除


二、 现在来了一个事务1对该记录的name做出了修改,改为Tom

在事务1修改该行(记录)数据时,数据库会先对该行加排他锁
然后把该行数据拷贝到undo log中,作为旧记录,既在undo log中有当前行的拷贝副本
拷贝完毕后,修改该行name为Tom,并且修改隐藏字段的事务ID为当前事务1的ID, 我们假设从1开始,之后递增,回滚指针指向拷贝到undo log的副本记录,既表示我的上一个版本就是它
事务提交后,释放锁

三、 又来了个事务2修改person表的同一个记录,将age修改为30岁

在事务2修改该行数据时,数据库也先为该行加锁
然后把该行数据拷贝到undo log中,作为旧记录,发现该行记录已经有undo log了,那么最新的旧数据作为链表的表头,插在该行记录的undo log最前面
修改该行age为30岁,并且修改隐藏字段的事务ID为当前事务2的ID, 那就是2,回滚指针指向刚刚拷贝到undo log的副本记录
事务提交,释放锁

记录版本链

从上面,我们就可以看出,同一记录的多次修改,会导致该记录的undo log成为一条记录版本线性表,既链表,undo log的链首就是最新的旧记录,链尾就是最早的旧记录

Read View(读视图)
什么是Read View?(对照表?)

什么是Read View,Read View是session进行快照读操作的时候生产的读视图(Read View),在该session执行的快照读的那一刻,会生成数据库系统当前的一个快照。
Read View主要是用来做可见性判断的, 即当执行快照读的时候,对该记录创建一个Read View读视图,把它比作条件用来判断当前session能够看到哪个版本的数据,既可能是当前最新的数据,也有可能是该行记录的undo log里面的某个版本的数据。
Read View:执行查询时【所有】未提交的事务Id数组(数组里最小的id为min_id)和已创建的最大事务id(max_id:未提交、已提交)组成


mvcc遵循一个可见性算法,查询时候,需要用read-view和undo log 做对比得到结果
比较规则:
依次比较记录版本链中每一条记录,符合规则就返回该条数据,不符合根据回滚指针取链路中的下一条数据;
trx_id为记录版本链里的DB_TRX_ID
1、如果trx_id < min_id(落在绿色部分),表示这个版本是已经提交的事务生成的,这个数据肯定是可见的;
2、如果trx_id > max_id (落在红色部分),表示这个版本是由将来的启动的事务生成的,是肯定不可见的;
3、如果min_id <= trx_id <= max_id (落在黄色部分),那就包括两种情况
a、若trx_id在未提交的事务Id数组里,表示这个版本是由未提交的事务产生的,不可见,当前自己的事务是可见的;
b、若trx_id不在未提交的事务Id数组里,表示这个版本是已经提交的事务生成的,可见

对于删除的情况,可以认为是update的特殊情况,会将版本链上最新的数据复制一份,然后将其trx_id修改成删除的trx_id,同时在该条记录的头信息(record_header)里的(delete_flag)标记位上写上true,来表示当前记录已经被删除,在查询时按照上面的规则查到对应的记录,如果delete_flag标记位等于true,意味着该条记录已被删除,则不返回数据

例子
默认RR级别
https://www.processon.com/view/link/5eef4a2d6376891e81dc7d28

三、MVCC相关问题
RC,RR级别下的InnoDB快照读有什么不同?
正是Read View生成时机的不同,从而造成RC,RR级别下快照读的结果的不同

在RR级别下的某个session对某条记录的第一次快照读会创建一个Read View, 将当前系统活跃的其他事务记录起来,此后再快照读的时候,还是使用的是同一个Read View,换一句话说,只要当前session在其他事务提交更新之前使用过快照读,那么之后的快照读使用的都是同一个Read View,所以对之后的修改不可见;
而在RC级别下的,每次快照读都会新生成一个Read View, 这就是我们在RC级别下的事务中可以看到别的事务提交的更新的原因
总之在RC隔离级别下,是每个快照读都会生成并获取最新的Read View;而在RR隔离级别下,则是同一个session中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。
可参考文档
mvcc https://www.jianshu.com/p/8845ddca3b23
bin log、redo log、undo log区别 https://www.cnblogs.com/wq-blogs/p/11867199.html
事务 https://blog.csdn.net/qq_38997379/article/details/89017287
详细解读mysql 的undo log https://blog.csdn.net/qq_39459385/article/details/84644005
详细分析MySQL事务日志(redo log和undo log)

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

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

相关文章

k8s CKA upgrade - Kubeadm 版本升级实测

升级版本最好是逐步去升级&#xff0c;不要跨越多个大版本&#xff0c;可能会出错 大体流程&#xff1a; 1.先确定升级版本 2.升级kubeadm 3.驱逐节点 4.升级kubelet和kubectl 5.重启kubelet服务 6.恢复节点&#xff0c;使其上线 1.查看现版本&#xff1a;升级版本 kubectl ge…

python从入门到精通(十五):python爬虫完整学习大纲

一、基础知识 爬虫的基本概念和工作原理。 HTTP 协议和网页结构。 Python 爬虫开发的基础库&#xff0c;如 requests、BeautifulSoup 等。 常见的反爬虫机制和应对方法。 二、爬虫逆向的技术 代理服务器和 IP 封锁突破。 用户代理和请求头模拟。 JavaScript 解析和执行。 验证码…

华为配置Hotspot2.0无线网络示例

配置Hotspot2.0无线网络示例 组网图形 图1 配置Hotspot2.0无线网络组网图 组网需求配置思路配置注意事项操作步骤配置文件 组网需求 某网络服务商在原有移动网络业务的基础上&#xff0c;新增部署WLAN网络接入业务&#xff0c;为用户提供更好的网络体验。但传统的WLAN网络业…

React/RN组件避免重复渲染的一些技巧

组件基础 回顾下React中创建组件的几种方式&#xff1a; ES5的React.createClass方式ES6的React.Component方式无状态的函数组件方式带hooks的函数组件方式 这里我们只讨论Component和函数组件。我们知道Component是否发生重渲染是由shouldComponentUpdate决定的&#xff0c;…

【每日一题】2024年3月汇编(上)

3.1【2369】检查数组是否存在有效划分 2369. 检查数组是否存在有效划分https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/ 1.这样的判断可以用动态规划来解决&#xff0c;用一个长度为(n1) 的数组来记录 是否存在有效划分&#xff0c;dp[i]…

乘法-逆矩阵

文章目录 1. 矩阵相乘-4种方式1.1 CAB1.2 AX 列组合1.3 XB 行组合 2. A,AB, A T A^T AT的逆3. 高斯消元法求 A − 1 A^{-1} A−1 1. 矩阵相乘-4种方式 1.1 CAB 假设我们要求得矩阵CAB &#xff0c;可以用如下公式表示 c i j ∑ k 1 N a i k b k j (1) c_{ij}\sum_{k1}^Na_…

Bean的作用域、Bean的自动装配、注解自动装配 (Spring学习笔记五)

1、Bean 的作用域 官网上显示有六种 1、Bean的作用域默认的是singleton&#xff08;单例模式的实现&#xff09; 也可以显示的设置&#xff08;单例模式的实现&#xff09; <!--用scope可以设置Bean的作用域--><bean id"user2" class"com.li.pojo.Us…

如何实现分词

分词&#xff08;Tokenization&#xff09;是自然语言处理&#xff08;NLP&#xff09;中的一个基本步骤&#xff0c;特别是在构建搜索引擎时&#xff0c;它将文本拆分成单词、短语或其他有意义的元素&#xff08;称为“词素”或“tokens”&#xff09;。对于中文文本来说&…

A*(AStar)算法总结

简介 A* 算法&#xff08;念做&#xff1a;A Star&#xff09;是一种常用的路径查找和图形遍历算法&#xff0c;具有较好的性能和准确度。让我为您简要介绍一下 A* 算法的原理和实现。 广度优先搜索&#xff1a; 广度优先搜索以广度作为优先级进行搜索。从起点开始&#xff0…

NCV8705MTADJTCG稳压器芯片中文资料规格书PDF数据手册引脚图图片价格功能

产品概述&#xff1a; NCV8705 是一款低噪音、低功耗和低泄漏线性电压稳压器。该器件具有卓越的噪音和 PSRR 规格&#xff0c;适用于使用视频接收器、成像传感器、音频处理器或需要外部洁净电源的任何部件的产品。NCV8705 使用创新的自适应接地电流电路 可确保轻负载调节下的超…

IDEA SpringBoot + Gradle无法运行测试问题

解决 i. 查看 build.gradle 中是否配置了 tasks.named(‘test’) { useJUnitPlatform() } ii. 打开IDEA 设置 &#xff08;Mac用户 Com &#xff0c; 可快速打开 / Win用户 Ctrl Alt s&#xff09; 检索Gradle 后&#xff0c;将Run tests using 选项 变更成 intelliJ IDEA…

http请求方法15种,附图可以下载保存备查。

一、http请求组成和流程 HTTP请求是客户端&#xff08;如浏览器&#xff09;向服务器发送的请求&#xff0c;以获取特定资源或执行特定操作。HTTP请求由以下几个部分组成&#xff1a; 请求行&#xff1a;包含请求方法、请求的URL和HTTP协议版本。常见的请求方法有GET、POST、P…

Rust 的 HashMap

在 Rust 中&#xff0c;HashMap 是一个从键&#xff08;key&#xff09;映射到值&#xff08;value&#xff09;的数据结构。它允许你以 O(1) 的平均时间复杂度存储、检索和删除键值对。HashMap 实现了 std::collections::HashMap 结构体&#xff0c;通常通过 use std::collect…

C#--StreamWriter和StreamReader对象及常用函数

目录 StreamReaderReadLine()Split&#xff08;&#xff09; StreamWriterWriteLine&#xff08;&#xff09;Flush()Close() StreamReader StreamReader 是 C# 中用于从流&#xff08;如文件、内存流等&#xff09;中读取文本数据的类。它提供了多种方法来读取不同类型的数据…

关于Canvas绘图和SVG绘图绘图的区别

当谈到Canvas绘图和SVG绘图时&#xff0c;它们是两种不同的绘图技术&#xff0c;各自具有不同的特点和应用场景。 区别&#xff1a; Canvas绘图&#xff1a;Canvas是HTML5中的一个元素&#xff0c;它提供了一个可以通过JavaScript进行绘图的区域。Canvas绘图是基于像素的&…

实景户外剧本杀小程序开发搭建

实景户外剧本杀小程序开发搭建需要以下步骤&#xff1a; 1. 确定需求和设计&#xff1a;首先需要明确实景户外剧本杀小程序的需求&#xff0c;包括场景、剧本、角色、玩法等方面的需求&#xff0c;并根据需求设计小程序的界面和功能。 2. 选择开发技术&#xff1a;根据需求选…

数据结构的概念大合集01(含数据结构的基本定义,算法及其描述)

概念大合集01 1、数据结构基础的定义2、数据结构2.1 数据元素之间关系的集合2.2数据结构的三要素2.2.1数据的逻辑结构2.2.2数据的存储&#xff08;物理&#xff09;结构2.2.3数据的运算 3、数据类型4、抽象数据类型类型&#xff08;ADT&#xff09;5、算法及其描述5.1算法的5个…

Qt文件以及文件夹相关类(QDir、QFile、QFileInfo)的使用

关于Qt相关文件读写操作以及文件夹的一些知识&#xff0c;之前也写过一些博客&#xff1a; Qt关于路径的处理&#xff08;绝对路径、相对路径、路径拼接、工作目录、运行目录&#xff09;_qt 相对路径-CSDN博客 C/Qt 读写文件_qt c 读取文本文件-CSDN博客 C/Qt读写ini文件_…

【C++】C++面向对象练习题

利用多态机制完成以下题目 现需要一个理财程序&#xff0c;其中包含四个类&#xff0c;分别为投资&#xff08;Investment&#xff09;、储蓄&#xff08;Saving)、基金&#xff08;Fund&#xff09;和理财人&#xff08;Person&#xff09;&#xff0c;储蓄和基金为两种具体投…

Docker学习之数据管理(超详解析)

Docker存储资源类型&#xff1a; 用户在使用 Docker 的过程中&#xff0c;势必需要查看容器内应用产生的数据&#xff0c;或者需要将容器内数据进行备份&#xff0c;甚至多个容器之间进行数据共享&#xff0c;这必然会涉及到容器的数据管理&#xff1a; &#xff08;1&#xff…