MySQL Undo Log

总结自bojiangzhou

undo log称为撤销日志或回滚日志。在一个事务中进行增删改操作时,都会记录对应的 undo log。在对数据库进行修改前,会先记录对应的 undo log,然后在事务失败或回滚的时候,就可以用这些 undo log 来将数据回滚到修改之前的样子。

InnoDB 在内存维护了一个全局变量来表示事务ID,每当要分配一个事务ID时,就获取这个变量值,然后把这个变量自增1

在行记录格式中行记录格式,行记录中会有三个隐藏列:

  • DB_ROW_ID:如果没有为表显式的定义主键,并且表中也没有定义唯一索引,那么InnoDB会自动为表添加一个row_id的隐藏列作为主键。

  • DB_TRX_ID:事务中对某条记录做增删改时,就会将这个事务的事务ID写入trx_id中。

  • DB_ROLL_PTR:回滚指针,本质上就是指向 undo log 的指针。

Undo Log Type

每对一条记录做一次改动,就会产生1条或者2undo log。一个事务中可能会有多个增删改SQL语句,这些 undo log 会被从 0 开始递增编号,这个编号称为 undo no

insert

插入一条数据对应的undo操作其实就是根据主键删除这条数据就行了。所以 insert 对应的 undo log 主要是把这条记录的主键记录上。

比如我们开启了一个事务,向 account 中插入两条数据:

BEGIN; 
INSERT INTO account(id,card,balance) VALUES (1, 'AA', 0),(2, 'BB', 0);

假设这个事务的事务ID为100,这条INSERT语句会插入两条数据,就会产生两个 undo log。插入记录的时候,会在行记录的隐藏列事务ID中写入当前事务ID,并产生 undo log,记录中的回滚指针会保存 undo log 的地址。而同一个页中的多条记录会通过next_record连接起来形成一个单链表,这块可以参考前面的行记录格式和数据页结构相关的文章。

delete

删除一条数据大致可以分为两个阶段:

  • 阶段一

首先是用户线程执行删除时,会先将记录头信息中的 delete_mask 标记为 1,而不是直接从页中删除,因为可能其它并发的事务还需要读取这条数据。(后面讲MVCC的时候就知道为什么了)

  • 阶段二

提交事务后,后台有一个 purge 线程会将数据真正删除。

首先要知道,页中的数据是通过记录头信息中的 netx_record 连接起来的单向链表(假设这个链表称为数据链表)。页中还有另一个链表,称为垃圾链表,记录真正删除后,会从数据链表中移除,然后加入到垃圾链表的头部,以便重用空间。

所以阶段二就是将记录从数据链表移除,加入到垃圾链表的头部。

也就是说,删除操作在事务提交前,只会经历阶段一,就是将记录的 delete_mask 标记为 1

此时接着执行一条删除的SQL语句,将id=2的这条数据删除:

BEGIN;
INSERT INTO account(id,card,balance) VALUES (1, 'AA', 0),(2, 'BB', 0);
DELETE FROM account WHERE id = 2;

因为是在同一个事务中,所以记录中的隐藏列trx_id没变,记录头中的delete_mask则标记为1了。然后生成了一个新的 undo log,并保存了记录中原本的trx_idroll_pointer,所以这个新的 undo log 就指向了旧的 undo log,而记录中的 roll_pointer 则指向这个新的 undo log。注意 undo log 中的事务编号也在递增。

update

在更新一条记录时,要把被更新的列的旧值记下来,这样之后回滚时再把这些列更新为旧值就好了。

Undo Log存储

undo log 分类

前边介绍了几种类型的 undo log,它们其实被分为两个大类来存储:

  • TRX_UNDO_INSERT

类型为 TRX_UNDO_INSERT_REC 的 undo log 属于此大类,一般由 INSERT 语句产生,或者在 UPDATE 更新主键的时候也会产生。

  • TRX_UNDO_UPDATE

除了类型为 TRX_UNDO_INSERT_REC 的 undo log,其他类型的 undo log 都属于这个大类,比如 TRX_UNDO_DEL_MARK_REC 、 TRX_UNDO_UPD_EXIST_REC ,一般由 DELETE、UPDATE 语句产生。

之所以要分成两个大类,是因为不同大类的 undo log 不能混着存储,因为类型为TRX_UNDO_INSERT_REC的 undo log 在事务提交后可以直接删除掉,而其他类型的 undo log 还需要提供MVCC功能,不能直接删除。

undo 页面链表

undo log 是存放在FIL_PAGE_UNDO_LOG类型的页中,一个事务中可能会产生很多 undo log,也许就需要申请多个undo页,所以 InnoDB 将其设计为一个链表的结构,将一个事务中的多个undo页连接起来。

但是前面说了 undo log 分为两大类,不能混着存储,所以如果事务中产生了这两大类型的 undo log,会创建两个链表,一个用来存储 TRX_UNDO_INSERT 类别的 undo log,一个用来存储 TRX_UNDO_UPDATE 类别的 undo log。

如果事务中还修改了临时表,InnoDB规定对普通表和临时表修改产生的 undo log 要分开存储,所以在一个事务中最多可能会有4个 undo 页面链表。

需要注意的是这些链表并不是事务一开始就分配好的,而是在需要某个类型的链表的时候才会去分配。

回滚段

redo log 是存放在重做日志文件中的,而 undo log 默认是存放在系统表空间中的一个特殊段(segment)中,这个段称为回滚段(Rollback Segment),链表中的页面都是从这个回滚段里边申请的。

InnoDB定义了128个回滚段(Rollback Segment),也就有128 Rollback Segment Header,每个Rollback Segment Header页面都对应着一个回滚段。一个 Rollback Segment Header 页面中包含1024undo slot,每个 undo slot 存放了 undo 链表头部的 undo 页的页号。就有128*1024=131072undo slot,也就是说最多同时支持131072个并发事务执行。

在系统表空间的第5号页面中存储了这128Rollback Segment Header页面地址。

事务回滚

前面在一个事务中增删改产生的一系列 undo log,都有 undo no 编号的。在回滚的时候,就可以应用这个事务中的 undo log,根据 undo no 从大到小开始进行撤销操作,就将数据还原为原来的样子了。

但需要注意的是,undo log 是逻辑日志,只是将数据库逻辑地恢复到原来的样子。所有修改都被逻辑地取消了,但是数据结构和页本身在回滚之后可能大不相同。因为同时可能很多并发事务在对数据库进行修改,因此不能将一个页回滚到事务开始的样子,因为这样会影响其他事务正在进行的工作。

MVCC

另一篇博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

(2024,测试时训练(TTT),线性注意力,RNN,嵌套循环)学习(在测试时学习):具有表达性隐藏状态的 RNN

Learning to (Learn at Test Time): RNNs with Expressive Hidden States 公和众与号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0. 摘要 1. 简介 2. 方法 2.1 使用 TTT 更新隐藏状态 2.2 …

常用的JVM启动参数

JVM的启动参数有很多,但是我们平常能用上的并不是特别多,这里介绍几个我们常用的: 1. 堆设置: 。 -Xms:设置堆的初始大小。 。.-Xmx:设置堆的最大大小。 2. 栈设置: 。 -XsS:设置每个…

​​​防御第一次作业

1、拓扑图及实验要求: 2、配置: 配置终端及服务器IP地址: Pc2: Client1: Pc4: Client2: PC1: Server1: Server2: 防火墙基础配置: [fw1]int g …

光学、SAR卫星影像助力洞庭湖决堤抢险(附带数据下载)

​​ 点击下方全系列课程学习 点击学习—>ArcGIS全系列实战视频教程——9个单一课程组合系列直播回放 点击学习——>遥感影像综合处理4大遥感软件ArcGISENVIErdaseCognition 7月5日下午,湖南岳阳市华容县团洲乡团北村团洲垸洞庭湖一线堤防发生决口&#xff0…

怎样在 PostgreSQL 中优化对 UUID 数据类型的索引和查询?

文章目录 一、UUID 数据类型概述二、UUID 索引和查询的性能问题三、优化方案(一)选择合适的索引类型(二)压缩 UUID(三)拆分 UUID(四)使用覆盖索引(五)优化查询…

Meta发布Llama 2驱动的AI代码生成器:Code Llama,开源来袭!

Meta 刚刚了号称是编程领域 “最先进的大语言模型”—— Code Llama ,可根据 代码和自然语言提示 生成代码和有关代码的自然语言,支持多种主流编程语言, 包括 Python、C、Java、PHP、Typescript (Javascript)、C# 和 Bash 。 Code Llama 完全…

“Pandas数据处理与分析:实用技巧与应用“

目录 # 开篇 1. pandas的series的了解 1.1 pd.Series 创建 1.2 pd.series 的索引使用 1.3 pd.series 之字典/索引 1.4 pandas 转换数据类型 1.5 pandas 通过索引或者通过位置来取值 1.6 pandas 指定行取值 1.7 pands之Series 切片和索引 1.8 pands之Series 的索引和值…

vue2/3代码格式化问题,看着太难受了

1.原本的代码: 格式化后的代码: 太难受了! 2.原本的代码 格式化后的代码 格式化跟有病似的,看着非常难受! 有没有什么插件解决!?

C++ //练习 14.44 编写一个简单的桌面计算器使其能处理二元运算。

C Primer(第5版) 练习 14.44 练习 14.44 编写一个简单的桌面计算器使其能处理二元运算。 环境:Linux Ubuntu(云服务器) 工具:vim 代码块 /**********************************************************…

Cesium中实现全球体积云效果的一种方案

原生 Cesium 提供了一种积云的效果,云的物理特征和渲染性能都还不错,这种方案适合表达小范围相对离散的云朵,但是用来实现全球范围下相对连续、柔和渐变的云层比较困难。本文在体渲染的基础上,参考了开源社区中 shadertoy 和 thre…

java数组之线性查找、二分法查找

一、线性查找 思想:如果想在一个数组中查找是否有某个元素,最容易想到的办法就是遍历数组,将数组中元素与想要查找的元素逐个对比,如果相等表示找到了,如果不等,则表示没找到。这就是线性查找的思想。 案例…

如何在微信小程序中对接微信支付

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119qq.com] &#x1f4f1…

流模型flow

流模型 Flow 超详解,基于 Flow 的生成式模型,从思路到基础到公式推导到模型理解与应用(Flow-based Generative Model)_generative flows-CSDN博客

软考《信息系统运行管理员》-3.1信息系统设施运维的管理体系

3.1信息系统设施运维的管理体系 1 信息系统设施运维的对象 基础环境 主要包括信息系统运行环境(机房、设备间、配线室、基站、云计算中心 等)中的空调系统、供配电系统、通信应急设备系统、防护设备系统(如消防系统、安全系统) 等,能维持系统安全正常运转&#xf…

食物链之带权并查集解法

直接看题&#xff1a;https://www.acwing.com/problem/content/description/242/ 下面就是代码的实现了&#xff0c;因为自己与自己肯定是同类我们初始化为0. 下面是AC代码&#xff1a; #include<bits/stdc.h> using namespace std; int n,k; int fk,x,y; int fa[10001…

C++ STL IO流介绍

目录 一&#xff1a;IO流的继承关系&#xff1a; 二&#xff1a;输入输出功能 1. 基本用法 2. 格式化输入 3.非格式化输入 4. 格式化输出 三&#xff1a;流 1. 字符流 2. 向字符流中写入数据 3. 从字符流中读出数据 4. 清空字符流 5.完整的例子 四&#xff1a;文件…

RISC-V异常处理流程概述(2):异常处理机制

RISC-V异常处理流程概述(2):异常处理机制 一、异常处理流程和异常委托1.1 异常处理流程1.2 异常委托二、RISC-V异常处理中软件相关内容2.1 异常处理准备工作2.2 异常处理函数2.3 Opensbi系统调用的注册一、异常处理流程和异常委托 1.1 异常处理流程 发生异常时,首先需要执…

生物打印后的生物力学过程

生物打印后的生物力学过程 3D生物打印技术在组织工程领域展现出巨大的潜力&#xff0c;但打印后组织的生物力学特性对其最终成功至关重要。本文将详细介绍打印后组织的生物力学特性及其在组织工程中的应用。 1. 打印后水凝胶交联 原位交联可以在生物打印过程中提供足够的机械…

开发个人Go-ChatGPT--5 模型管理 (一)

开发个人Go-ChatGPT–5 模型管理 (一) 背景 开发一个chatGPT的网站&#xff0c;后端服务如何实现与大模型的对话&#xff1f;是整个项目中开发困难较大的点。 如何实现上图的聊天对话功能&#xff1f;在开发后端的时候&#xff0c;如何实现stream的响应呢&#xff1f;本文就…

SprintBoot创建遇到的问题

最近使用IDEA版本为2022.3.1&#xff0c;java版本为21.0.3&#xff0c;现在做一个创建SprintBoot3的一个大体流程 1.先下载Maven&#xff0c;解压到一个位置 maven下载 2.配置setting.xml文件 这路径自己配置&#xff0c;这里不多演示 代码如下&#xff1a; <mirror>&…