当前位置: 首页 > news >正文

MySQL—redo log、undo log以及MVCC

MySQL—redo log、undo log以及MVCC

  首先回忆一下MySQL事务的四大特性:ACID,即原子性、一致性、隔离性和持久性。其中原子性、一致性、持久性实际上是由InnoDB中的两份日志保证的,一份是redo log日志,一份是undo log日志;而隔离性则依赖于锁和MVCC。

一、redo log

  重做日志,记录的是事务提交时数据页的物理修改,是用来实现事务的持久性。
  该日志文件由两部分组成:重做日志缓冲( redo log buffer )以及重做日志文件( redo log file ),前者在内存中,后者在磁盘中。

1. 应用场景

  我们知道,在InnoDB引擎中的内存结构中,主要的内存区域就是缓冲池,在缓冲池中缓存了很多的数据页。 当我们在事务中执行多个增删改的操作时,InnoDB引擎会先操作缓冲池中的数据,如果缓冲池没有对应的数据,则会通过后台线程将磁盘中的数据加载出来,存放在缓冲池中,然后将缓冲池中的数据修改,修改后的数据页我们称为脏页。 而脏页则会在一定的时机,通过后台线程刷新到磁盘中,从而保证缓冲池与磁盘数据的一致性。 然而缓冲池的脏页数据并不是实时刷新的,而是一段时间之后才将缓冲池的数据刷新到磁盘中,假如刷新到磁盘的过程出错了,而提示给用户事务提交成功,这样数据没有持久化下来,违背了事务的持久性。redo log的作用就是,当事务提交之后会把所有修改信息都存到该日志文件中,用于在刷新脏页到磁盘发生错误时, 进行数据恢复使用。

2. 工作流程

在这里插入图片描述
  当对缓冲池的数据进行增删改之后,会首先将数据页变化记录在redo log buffer中。在事务提交时,会将redo log buffer中的数据刷新到redo log磁盘文件中。之后,如果刷新缓冲池的脏页到磁盘时,发生错误,此时就可以借助于redo log进行数据恢复,这样就保证了事务的持久性。 而如果脏页成功刷新到磁盘,此时redo log就没有作用了,就可以删除了,所以磁盘中存在两个redo log文件并且是循环写的。

3. 优点

  可能有人会问,那为什么每一次提交事务,要刷新redo log buffer到磁盘中呢,而不是在事务提交时直接将buffer pool中的脏页刷新到磁盘呢?
  因为在业务操作中,我们操作数据一般都是随机的,如果此时刷新磁盘,是随机IO,性能比较低。而redo log在往磁盘文件中写入数据时,由于是日志文件,所以是顺序IO。顺序IO的效率要远大于随机IO。 这种先写日志的方式,称之为 WAL ( Write-Ahead Logging )。

二、undo log

  回滚日志,用于记录数据被修改前的信息 , 作用包含两个:

  • 提供回滚(保证事务的原子性和一致性)
  • MVCC(多版本并发控制)

  undo log和redo log记录物理日志不一样,它记录的是逻辑日志。可以认为当delete一条记录时,undo log中会记录一条对应的insert记录,反之亦然,当update一条记录时,它记录一条对应相反的update记录。如此一来,当执行事务回滚时,就可以从undo log中的逻辑记录读取到相应的内容并进行回滚。从而保证了事务的原子性和一致性。
  undo log采用段的方式进行管理和记录,存放在InnoDB存储引擎的rollback segment回滚段中。undo log在事务执行时产生,事务提交时,并不会立即删除undo log,因为这些日志可能还用于MVCC。

三、MVCC

  全称Multi-Version Concurrency Control,即多版本并发控制。指维护一个数据的多个版本,使得读写操作没有冲突。MVCC的具体实现,依赖于数据库记录中的隐式字段、undo log日志、readView。

1. 隐式字段

  在一张表中,每行数据除了我们设置的字段以外,InnoDB还会自动地添加三个隐藏字段:

隐藏字段含义
DB_TRX_ID最近修改事务ID,记录插入这条记录或最后一次修改该记录的事务ID(从1开始自增)
DB_ROLL_PTR回滚指针,指向这条记录的上一个版本,用于配合undo log,指向上一个版本
DB_ROW_ID隐藏主键,如果表结构没有指定主键,将会生成该隐藏字段

  上述的前两个字段是肯定会添加的,是否添加最后一个字段取决于当前表有没有主键,如果有主键,则不会添加该隐藏字段。

2. undo log

  当执行insert的时候,产生的undo log日志只在回滚时需要,在事务提交后,可被立即删除。而执行update、delete的时候,产生的undo log日志不仅在回滚时需要,在快照读时也需要,不会立即被删除。
  下面我们介绍一下undo log版本链的生成。假设有一张表的原始数据为
在这里插入图片描述
然后,有四个并发事务同时在操作这张表。

A. 第一步
在这里插入图片描述

  当事务2执行第一条修改语句时,会记录undo log日志,记录数据变更之前的样子(左图);然后更新记录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本(右图)。

在这里插入图片描述

B. 第二步

在这里插入图片描述

  当事务3执行第一条修改语句时,也会记录undo log日志,记录数据变更之前的样子(左图);然后更新记录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本(右图)。

在这里插入图片描述

C. 第三步

在这里插入图片描述

  当事务4执行第一条修改语句时,也会记录undo log日志,记录数据变更之前的样子(左图);然后更新记录,并且记录本次操作的事务ID,回滚指针,回滚指针用来指定如果发生回滚,回滚到哪一个版本(右图)。

在这里插入图片描述

  最终我们发现,不同事务或相同事务对同一条记录进行修改,会导致该记录的undolog生成一条记录版本链表,链表的头部是最新的旧记录,链表尾部是最早的旧记录。

3. readView

  首先我们先介绍两个概念,当前读和快照读。

  • 当前读
      读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。对于我们日常的操作,如:select … lock in share mode(共享锁),select …for update、update、insert、delete(排他锁)都是一种当前读。
  • 快照读
      简单的select(不加锁)就是快照读,快照读,读取的是记录数据的可见版本,有可能是历史数据,不加锁,是非阻塞读。在不同的事务隔离级别下,生成快照读的时机不同。
    • Read Committed:每次select,都生成一个快照读。
    • Repeatable Read:开启事务后仅在第一个select语句快照读。
    • Serializable:快照读会退化为当前读。

  ReadView(读视图)是快照读SQL执行时MVCC提取数据的依据,记录并维护系统当前活跃的事务(未提交的)id。ReadView中包含了四个核心字段:

字段含义
m_ids当前活跃的事务ID集合
min_trx_id最小活跃事务ID
max_trx_id预分配事务ID,当前最大事务ID+1(因为事务ID是自增的)
creator_trx_idReadView创建者的事务ID

而在readView中也规定了版本链数据的访问规则(trx_id代表undolog版本链中记录的事务ID):

条件是否可以访问说明
trx_id ==creator_trx_id可以访问该版本成立,说明数据是当前这个事务更改的
trx_id < min_trx_id可以访问该版本成立,说明数据已经提交
trx_id > max_trx_id不可以访问该版本成立,说明该事务是在readView生成后才开启
min_trx_id <= trx_id<= max_trx_id如果trx_id不在m_ids中,是可以访问该版本的成立,说明数据已经提交

4. 实现原理

  前面我们说过,在不同隔离级别下生成readView的时机不同。

4.1 RC隔离级别

  RC隔离级别下,在事务中每一次执行快照读时生成ReadView。
在事务5中执行了两次select操作,每一次都会生成一个readView,第一条select语句执行时,事务3、4、5都未提交,第二条select语句执行时,事务4、5未提交。

在这里插入图片描述

两个readView我们到底会获得什么样的数据呢?先来看第一次快照读具体的读取过程:

在这里插入图片描述

代入trx_id=4,发现右图中四条均不满足;代入trx_id=3,发现同样不满足;代入trx_id=2,在②处满足,因此这条查询语句拿到的结果就是

在这里插入图片描述

再来看第二次快照读具体的读取过程:

在这里插入图片描述

代入trx_id=4,发现右图中四条均不满足;代入trx_id=3,在②处满足,因此这条查询语句拿到的结果就是

在这里插入图片描述

4.2 RR隔离级别

  RR隔离级别下,仅在事务中第一次执行快照读时生成readView,后续复用该readView。 这也印证了RR是可重复读,在一个事务中,执行两次相同的select语句,查询到的结果应是一样的。

在这里插入图片描述
同样的分析方式,可以看出两次select语句拿到的都是

在这里插入图片描述

  综上所述,MVCC的实现原理就是通过InnoDB表的隐藏字段、undo log版本链、readView来实现的。而MVCC+锁,则实现了事务的隔离性。

关于MVCC还想了解更多的朋友们可以参考 MVCC详解!

相关文章:

MySQL—redo log、undo log以及MVCC

MySQL—redo log、undo log以及MVCC 首先回忆一下MySQL事务的四大特性&#xff1a;ACID&#xff0c;即原子性、一致性、隔离性和持久性。其中原子性、一致性、持久性实际上是由InnoDB中的两份日志保证的&#xff0c;一份是redo log日志&#xff0c;一份是undo log日志&#xff…...

13 list的实现

注意 实现仿cplus官网的list类&#xff0c;对部分主要功能实现 实现 文件 #pragma once #include <assert.h>namespace mylist {template <typename T>struct __list_node{__list_node(const T& x T()): _prev(nullptr), _next(nullptr), _data(x){}__lis…...

如何用client-go获取k8s因硬盘容量、cpu、内存、gpu资源不够引起的错误信息?

在Kubernetes中&#xff0c;你可以使用client-go库来获取Pod的状态和事件&#xff0c;这些信息可能包含了由于资源不足引起的错误信息。 以下是一个基本的示例&#xff0c;展示如何使用client-go来获取Pod的状态和事件&#xff1a; package mainimport ("flag"&quo…...

IDEA编译安卓源码TVBox(2)

一、项目结构&#xff1a;主要app和player app结构 二、增加遥控器按键选台 修改LivePlayActivity.java 1、声明变量 public String channelId "";public Timer timer new Timer();public Toast mToast;2、定义方法 private void mToastShow(String s){mToast …...

【C#】.net core 6.0 使用第三方日志插件Log4net,配置文件详细说明

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是《C#》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌握。…...

第十四届蓝桥杯省赛真题 Java 研究生 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: 特殊日期试题 B: 与或异或试题 C: 棋盘试题 D: 子矩阵试题 E : \mathrm{E}: E: 互质数的个数试题 F: 小蓝的旅行计划试题 G: 奇怪的数试题 H: 太阳试题 I: 高塔试题 J \mathrm{J} J : 反异或 01 串 发现宝藏 前些天发现了一个巨牛的人…...

adb shell input text 输入中文

由于adb 不支持中文输入&#xff08;不支持 Unicode&#xff09;&#xff0c;需要使用虚拟键盘绕一圈。 可以直接参考和使用&#xff1a; https://github.com/senzhk/ADBKeyBoard # 通用方式 adb shell am broadcast -a ADB_INPUT_TEXT --es msg 赞 # mac/linux 支持 base64…...

Rudolf and the Ball Game

传送门 题意 思路 暴力枚举每一个妆台的转换条件 code #include<iostream> #include<cstdio> #include<stack> #include<vector> #include<algorithm> #include<cmath> #include<queue> #include<cstring> #include<ma…...

计算机毕业设计-基于大数据技术下的高校舆情监测与分析

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、研究背景与意义1.1背景与意义1.2 研究内容 二、舆情监测与分析的关键技术2.1 robot协议对本设计的影响2.2 爬虫2.2.1 工作原理2.2.2 工作流程2.2.3 抓取策略2.3 scrapy架构2.3.1 scrapy&#xff1a;开源爬虫架…...

WPF使用LiveCharts画图时,横坐标转换成时间

一、背景 使用LiveCharts画图时&#xff0c;横坐标通常为数值类型&#xff0c;要转换成时间等自定义类型&#xff0c;需要用到Formatter进行类型转换。 示例使用MVVM模式编写 二、View代码 关键是设置LabelFormatter属性 <lvc:CartesianChart Series"{Binding Series…...

Qt客户端开发的技术难点

在Qt客户端开发中&#xff0c;可能会遇到一些技术难点&#xff0c;这些难点可能与UI设计、性能优化、跨平台兼容性等方面有关。以下是一些可能的技术难点&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作…...

杰理AD155儿童玩具语音集成电路

一、杰理AD155集成电路是由杰理科技设计、开发和销售的一款产品&#xff0c;AD15系列 SoC 芯片支持以下特性&#xff1a; 工作电压&#xff1a;2.0V-5.5V主频可达120MHz的32bitCPU,片上集成20K字节SRAM&#xff0c;8K字节ICache支持最多2路解码同时运行&#xff0c;支持F1A/A/…...

git bash 命令行反应慢、卡顿(定位出根本原因)

参考该博主&#xff1a; https://blog.csdn.net/weixin_50212044/article/details/131575987?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-131575987-blog-130024908.235v43pc_blog_bottom_relevance_base4&spm1001.210…...

Android 启动service(Kotlin)

一、使用startForegroundService()或startService&#xff08;&#xff09;启用service **Activity //启动service val intent: Intent Intent(ServiceActivitythis,MyService::class.java) //Build.VERSION_CODES.O 26 // Android8以后&#xff0c;不允许后台启动Service i…...

Windows蓝牙驱动开发之模拟HID设备(一)(把Windows电脑模拟成蓝牙鼠标和蓝牙键盘等设备)

by fanxiushu 2024-03-14 转载或引用请注明原作者 把Windows电脑模拟成蓝牙鼠标和蓝牙键盘&#xff0c;简单的说&#xff0c;就是把笨重的PC电脑当成鼠标键盘来使用。 这应该是一个挺小众的应用&#xff0c;但有时感觉也应该算比较好玩吧&#xff0c; 毕竟实现一种一般人都感觉…...

LlamaParse: 高效的PDF文件RAG解析工具

LlamaParse: 高效的PDF文件RAG解析工具 通过Thomas Reid的深入探索&#xff0c;LlamaParse成为了目前我所见最优秀的RAG实现用PDF解析器。基于AI的技术&#xff0c;尤其在处理像SEC Q10这样的复杂文件时表现出色&#xff0c;这些文件通常包含文本、数字及其组合构成的表格&…...

platform设备注册驱动模块的测试

一. 简介 上一篇文章编写了 platform设备注册代码&#xff0c;文章地址如下&#xff1a; 无设备树platform驱动实验&#xff1a;platform设备注册代码实现-CSDN博客 本文继续无设备树platform驱动实验&#xff0c;本文对编译好的 设备注册程序进行测试&#xff0c;测试所实…...

鸿蒙Harmony应用开发—ArkTS声明式开发(容器组件:ListItemGroup)

该组件用来展示列表item分组&#xff0c;宽度默认充满List组件&#xff0c;必须配合List组件来使用。 说明&#xff1a; 该组件从API Version 9开始支持。后续版本如有新增内容&#xff0c;则采用上角标单独标记该内容的起始版本。该组件的父组件只能是List。 使用说明 当List…...

Docker:常用命令

文章目录 docker作用常用指令 docker 作用 Docker 是一种容器化平台&#xff0c;可以让开发者打包应用程序及其依赖项&#xff0c;并以容器的形式进行发布、交付和运行。 Docker 的一些主要作用&#xff1a; 应用程序隔离&#xff1a;Docker 使用容器技术&#xff0c;将应用程…...

如何搭建“Docker Registry私有仓库,在CentOS7”?

1、下载镜像Docker Registry docker pull registry:2.7.1 2、运行私有库Registry docker run -d -p 5000:5000 -v ${PWD}/registry:/var/lib/registry --restartalways --name registry registry:2.7.1 3、拉取镜像 docker pull busybox 4、打标签&#xff0c;修改IP&#x…...

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出&#xff1a;JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中&#xff0c;随机数的生成看似简单&#xff0c;却隐藏着许多玄机。无论是生成密码、加密密钥&#xff0c;还是创建安全令牌&#xff0c;随机数的质量直接关系到系统的安全性。Jav…...

04-初识css

一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

Mysql8 忘记密码重置,以及问题解决

1.使用免密登录 找到配置MySQL文件&#xff0c;我的文件路径是/etc/mysql/my.cnf&#xff0c;有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

区块链技术概述

区块链技术是一种去中心化、分布式账本技术&#xff0c;通过密码学、共识机制和智能合约等核心组件&#xff0c;实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点&#xff1a;数据存储在网络中的多个节点&#xff08;计算机&#xff09;&#xff0c;而非…...