浅谈 MySQL 的 Undo log 日志

news2025/1/11 6:58:21

undo log 存储在类型为 FIL_PAGE_UNDO_LOG 页中。 可以从系统表空间中分配空间,也可以从 undo tablespace 中分配空间。 FIL_PAGE_UNDO_LOG 类型页主要分为四部分:

  • File Header,所有页都有的结构
  • Undo Page Header
    • TRX_UNDO_PAGE_TYPE,存储什么类型的 undo log,分类后面会介绍。 不同类型的 undo log 不能存储在同一个页中。 TRX_UNDO_INSERT_REC 类型的放一个页面中,其他类型的放一个页面中。
    • TRX_UNDO_PAGE_START,本页中 undo log 开始的偏移量。
    • TRX_UNDO_PAGE_FREE,本页中,空闲位置开始的偏移量,与最后一条 undo log 的末尾偏移量一样。
    • TRX_UNDO_PAGE_NODE,12 字节,包括4部分内容
      • Pre Node Page Number 和 Pre Node Offset 组成了指向前一个 FIL_PAGE_UNDO_LOG 页的指针;
      • Next Node Page Number 和 Next Node Offset 组成了指向后一个 FIL_PAGE_UNDO_LOG 页的指针;
  • 用于存放 undo log 日志记录的空间
  • File Trailer,所有页都有的结构

01-INSERT 对应的 undo log 记录格式

插入区分乐观插入、悲观插入,

  • 乐观插入,指要插入页的空间充足,足以容纳新插入的记录。
  • 悲观插入,指要插入页的空间不足,需要页分裂。

不管如何,是将一条记录插入。 它对应的回滚操作,就是删除这条插入的记录,TRX_UNDO_INSERT_REC:

  • end of record
  • undo type,TRX_UNDO_INSERT_REC,说明为 INSERT 语句的 undo log。
  • undo no,序列号。
  • table id,可以从 information_schema.INNODB_TABLES 中查询到。
  • 主键各列信息,{<len, value>}。INSERT 相对应的回滚日志是删除插入的记录,所以这里要记录的信息需要包含如何定位到这条记录。
  • start of record

其中,start of record 和 end of record 是两个指针,指向了 undo log 记录开始、结束的位置。

02-DELETE 对应的 undo log 记录格式

在介绍 记录 和 页 时有提到,数据页中所有的记录通过 next_record 串联起来,形成一个链表。 所有的被标记为删除(即 delete_mask 为1)的记录也会通过 next_record 串联起来,形成垃圾链表。 数据页的 Page Header 中有一个 PAGE_FREE 属性,指向垃圾链表的头部。

首先,我们要先搞明白 DELETE 语句的执行过程。删除分为两个阶段:

  1. 在聚簇索引上根据 id 找到对应的记录,将其 delete_mask 置为1(同时也会修改隐藏列 DB_TRX_ID 和 DB_ROLL_PTR)。此阶段也被称为 delete mark 阶段。
  2. 当执行删除语句的事务提交后,有专门的线程()将 delete_mask 标记为1的记录从正常记录中移除,加入到垃圾链表中(头插)。 同时需要修改一些页面的其他信息,比如页面中的用户记录数量 PAGE_N_RECS、上次插入记录的位置 PAGE_LAST_INSERT、垃圾链表头节点的指针 PAGE_FREE、页面中可重用的字节数量 PAGE_GARBAGE、还有页目录的一些信息等等。 此阶段也被称之为 purge 阶段。

delete mask 阶段对应的 undo log 类型为 TRX_UNDO_DEL_MARK_REC:

  • end of record
  • undo type,TRX_UNDO_DEL_MARK_REC,说明为 delete mask 阶段的 undo log。
  • undo no,序列号。
  • table id
  • info bits
  • old trx_id
  • old roll_pointer,和 old trx_id 一块,记录了修改 delete_mask 前,记录上的值。
  • 主键各列信息,{<len, value>},主要为了定位记录。
  • index_col_info len,记录了当前、以及下部分内容占用的空间。
  • {<pos, len, value>},保存了记录中的列(在某个索引中),其在索引中的位置、空间占用、实际值。 这部分内容主要在 purge 阶段使用。
  • start of record

03-UPDATE 对应的 undo log 记录格式

UPDATE 语句的处理方式根据是否更新主键分为两种不同的方案:

  1. 不更新主键。 根据是否改变记录的大小,又可以进一步分为:

    • 就地更新,记录大小不发生变化。 对记录中的每个列来说,其大小都不发生改变。
    • 先删除,再插入。 对记录中的每一列来说,任一列的大小发生了变化。 执行的操作是,先删除、再插入。 删除是彻底删除,并不是 DELETE 中分两阶段的删除。 与 purge 阶段不同的事,并非是某个特定线程去删除,而是由用户线程同步删除。

    针对不更新主键的情况,undo log 类型为 TRX_UNDO_UPD_EXIST_REC(省略了 end of record 之类的共有的信息):

    • old trx_id
    • old roll_pointer
    • 主键各列信息,{<len, value>},主要为了定位记录。
    • n_updated,记录了共有多个列被更新了。
    • {<pos, old_len, old_value>} 记录了被更新的列的旧值
    • index_col_info len,记录了当前、以及下部分内容占用的空间。
    • {<pos, len, value>},保存了记录中的列(在某个索引中),其在索引中的位置、空间占用、实际值。
  2. 更新主键。分为两步处理:

    1. 对旧记录进行 delete_mask 阶段的操作。
    2. 插入新的记录。

    所以,这种情况会产生两条 undo log 记录。

04-版本链

在学习 InnoDB 行记录格式时,我们知道在聚簇索引中记录的数据部分 InnoDB 会自动插入三列:DB_ROW_ID\DB_TRX_ID\DB_ROLL_PTR。 其中 DB_ROW_ID 不是必需的,只在没有指定主键且没有唯一列时插入。 其余两列与事务及一致性读视图相关:

  • DB_TRX_ID,每次一个事务对某条聚簇索引记录改动时,都会将事务的 ID 赋给隐藏的 DB_TRX_ID 列
  • DB_ROLL_PTR,每次一个事务对某条聚簇索引记录改动时,旧版本会被写入到 undo log 中,该隐藏列就像一个指针,通过它来找到之前的版本。

对某条记录的每次修改(UPDATEDELETE),都会在 undo log 中记录一个旧版本,旧版本中也包括 DB_ROLL_PTR 列、事务 ID 列。 因此,undo log 中记录的所有版本会形成一个链表,值越旧,它就在链中越靠近末尾的位置,该记录的最新值,记录在聚簇索引中的记录上。

我们借用《MySQL 是怎样运行的:从根儿上理解 MySQL》中的一幅图,加深下对版本链的理解。

图中所示的是插入、并删除一条记录后,形成的版本链。

在读未提交事务隔离级别下,直接读取记录的最新版本即可; 在串行级别下,需要使用锁来保证。 所以,版本链主要应用于读提交和可重复读事务隔离级别。 它要解决的核心问题就是,版本链中的哪些版本是当前事务可见的。

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

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

相关文章

十一、docker相关问题解决方案

&#x1f33b;&#x1f33b;一、创建tomcat失败报348 问题二、端口监听问题&#xff0c;没安装命令三、非正常关闭电脑导致虚拟机无法启动一、创建tomcat失败报348 问题 创建失败问题&#xff1a; docker: Error response from daemon: OCI runtime create failed: container…

通用vue组件化搜索组件页面

一、组件化封装 1.首先创建一个form文件夹&#xff0c;将搜索框组件的内容全部写在这个里面&#xff0c;然后再在需要的页面直接引入相应的组件即可 2.首先先在goods.vue文件里面写对应的文本数组formItems&#xff0c;将所定义的类型IFormItem引用进去&#xff0c;这个里面写…

coresight(五) rom table

五、 rom table 在一个soc中&#xff0c;有多个coresight组件&#xff0c;但是软件怎么去识别这些coresight组件&#xff0c;去获取这些coresight组件的信息了&#xff1f;这个时候&#xff0c;就需要靠coresight组件中&#xff0c;一个重要的组件&#xff0c;这个组件就是rom …

CMD有哪些有趣的命令?

程序员宝藏库&#xff1a;https://gitee.com/sharetech_lee/CS-Books-Store 用惯Linux和macOS的同学都会对各种各样强大的命令印象深刻&#xff0c;然而再转向Windows时就开始不屑一顾&#xff0c;认为Windows上没有Linux上那些超级便捷好用的命令。 其实&#xff0c;Windows下…

ROS安装及rosdep update问题解决

ROS安装&#xff1a; 参考链接&#xff1a;详细介绍如何在ubuntu20.04中安装ROS系统&#xff0c;以及安装过程中出现的常见错误的解决方法&#xff0c;填坑&#xff01;&#xff01;&#xff01;_慕羽★的博客-CSDN博客_ubuntu20.04安装ros rosdep update问题解决&#xff1a…

Linux Shell 脚本编程基础

Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核,不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序.Shel编程语言具有普通编程语言的很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应…

Selenium用法详解【窗口表单切换】【JAVA爬虫】

简介本文主要讲解java 代码利用Selenium如何实现控制浏览器进行窗口切换和页面内的不同表单之间的切换操作。切换操作窗口切换在 selenium 操作页面的时候&#xff0c;可能会因为点击某个链接而跳转到一个新的页面&#xff08;打开了一个新标签页&#xff09;&#xff0c;这时候…

电子词典流程图

简易流程&#xff1a; 详细介绍 服务端&#xff08;TCP并发&#xff09; 一.分支线程负责处理客户端发送的信息 1.登陆与注册信息 登陆&#xff08;l&#xff09;;注册&#xff08;e&#xff09; (1)登陆根据接收的用户名&#xff0c;密码在用户注册表中遍历是否符合&#xff…

ORB-SLAM2 --- ORBmatcher::SearchBySim3函数

目录 1.函数作用 2.函数流程 3.函数解析 3.1 准备工作&#xff1a;内参&#xff0c;计算Sim3的逆 3.2 记录已经匹配的特征点 3.3 通过Sim变换&#xff0c;寻找 pKF1 中特征点和 pKF2 中的新的匹配 3.4 通过Sim变换&#xff0c;寻找 pKF2 中特征点和 pKF1 中的新的匹…

Jenkins远程SSH部署SpringBoot项目

1.前置环境 前置环境配置&#xff1a;jdk、maven、git 2.在Jenkins配置git凭据 请查看往期文章&#xff1a; https://blog.csdn.net/RookiexiaoMu_a/article/details/122655272?spm1001.2014.3001.5501 3.安装Publish over SSH插件 4.配置SSH Servers 安装完Publish over…

C++蓝桥杯贪心算法

目录 &#x1f33c;一&#xff0c;1812: [NewOJ Week 5] 排列变换 &#x1f33c;二&#xff0c;1827: [NewOJ Week 8] 升降数字 &#x1f33c;三&#xff0c;剑指offer 10-II 青蛙跳台阶问题 &#x1f33c;四&#xff0c;P1223 排队接水 &#x1f33c;五&#xff0c;P5650…

npm常用命令

目录1. 构建项目2. 安装包3. 查看安装目录4. 卸载包5. 更新包6. 查看已安装的包7. 使用国内npm镜像源8. 使用yarn1. 构建项目 npm init # 全部使用默认配置 npm init --yes2. 安装包 # 全局安装 npm install 包名 -g # 本地安装 npm install 包名 # 一次安装多个 npm install…

ROS移动机器人开发——硬件引脚

我们使用的32开发板为冰达机器人官方的开发板&#xff0c;类型为STM32RCT6。32章节的目的为&#xff0c;将官方所给源码转化为 官方标准库函数来进行使用 —————————————— 需求提出&#xff1a; 电源 1. 3.3V-200ma供电 2. 输入 9-12.6V 5A 控制&#xff1a…

(十三)JAVA基础语法

目录 前言: 一、包 二、权限修饰符 三、final关键字 四、常量 五、枚举 六、抽象类 七、抽象类:模板方法模式 八、接口 前言: ①包: 在编写Java程序时&#xff0c;随着程序架构越来越大&#xff0c;类的个数也越来越多&#xff0c;这时就会发现管理程序中维护类名称也…

利用OpenCV的函数calcHist()计算出图像的直方图数据后绘制图像的直方图

利用OpenCV的函数calcHist()计算出图像的直方图数据后绘制图像的直方图 在上一篇博文 https://www.hhai.cc/thread-200-1-1.html 中已经对OpenCV的直方图计算函数calcHist()进行了详细介绍。 这篇博文介绍如何用直方图数据绘制直方图。 OpenCV是没有统计图绘制的相关函数的&a…

Verilog语法笔记(夏宇闻第三版)-循环语句

目录 forever语句: repeat语句: while语句: for语句: 在Verilog HDL中存在着四种类型的循环语句&#xff0c;用来控制执行语句的执行次数。 1) forever 连续的执行语句。 2) repeat 连续执行一条语句 n 次。 3) while 执行一条语句直到某个条件不满足。如果一开始条件即…

数据异动分析方法论

注&#xff1a;本文首发于公众号&#xff1a;书剑双修&#xff0c;欢迎关注。 数据异动分析是一类典型的数据分析问题&#xff0c;也是分析师日常工作中会频繁遇到的问题。很多的数据分析面试过程中&#xff0c;都会对这个方面进行考察&#xff0c;以此来判断分析师思考问题的全…

使用IIS服务器搭建一个网站

1、什么是IISIIS全称为Internet Information Services&#xff0c;是一种Web服务组件。通过在自己电脑上安装好IIS服务&#xff0c;就可以把你自己的电脑当作一个网站的服务器。2、搭建一个IIS2.1、开启windows的IIS服务Step1、控制面板——程序——程序和功能——启用或关闭wi…

微软的COM、DOM和COM+

纯粹的为了记录一下 COM 组件对象模型&#xff08;COM&#xff09;&#xff0c;是微软公司为了计算机工业的软件生产更加符合人类的行为方式开发的一种新的软件开发技术。在COM构架下&#xff0c;人们可以开发出各种各样的功能专一的组件&#xff0c;然后将它们按照需要组合起…

大数据NiFi(九):NiFi集群页面的添加、配置处理器操作

文章目录 NiFi集群页面的添加、配置处理器操作