Mysql-事务日志undo log

server/2025/2/20 22:19:35/

undo log 的作用 

事务需要保证 原子性,也就是事务中的操作要么全部完成,要么什么也不做。但有时候事务执行到一半会出现一些情况,比如:

  • 情况一:事务执行过程中可能遇到各种错误,比如服务器本身的错误操作系统错误 ,甚至是突然 断电 导致的错误。

  • 情况二:程序员可以在事务执行过程中手动输入 ROLLBACK 语句结束当前事务的执行。

以上情况出现,我们需要把数据改回原先的样子,这个过程称之为 回滚 ,这样就可以造成一个假象:这个事务看起来什么都没做,所以符合 原子性 要求。

总而言之,undo log记录的就是操作的逆操作,插入一条记录,undo 记录的就是delete操作

Undo日志的作用

作用1:回滚数据

undo是逻辑日志,只是将数据库逻辑恢复到原来的样子,但对具体的数据结构和页是不会坐修改的,因为其它事务也可能会在相同的页进行数据操作,如果在数据结构和页层面进行回滚,会影响到其它事务正在进行的操作。

  • 作用2:MVCC

 undo的另一个作用是MVCC,即在InnoDB存储引擎中MVCC的实现是通过undo来完成。当用户读取一行记录时,若该记录以及被其他事务占用,当前事务可以通过undo读取之前的行版本信息,以此实现非锁定读取。  

 undo的存储结构

回滚段与undo页

InnoDB对undo log的管理采用段的方式,也就是 回滚段(rollback segment) 。每个回滚段记录了 1024undo log segment ,而在每个undo log segment段中进行 undo页 的申请。

  • InnoDB1.1版本之前 (不包括1.1版本),只有一个rollback segment,因此支持同时在线的事务限制为 1024 。虽然对绝大多数的应用来说都已经够用。

  • 从1.1版本开始InnoDB支持最大 128个rollback segment ,故其支持同时在线的事务限制提高到 了 128*1024

mysql> show variables like 'innodb_undo_logs';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| innodb_undo_logs | 128   |
+------------------+-------+

 

 undo的页是可以重用,并不会为每一个事务都单独分配一个页,当事务提交时,并不会立刻删除undo 页,因为这个页可能夹杂着其它事务的undo log ,undo log 在事务commit之后,会被放到一个链表中,然后判断该页的使用空间,如果小于4分之3的话,就不会被回收,其它事务的undo log 可以记录到当前undo 页的后面

 回滚段与事务

  1. 每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务

  2. 当一个事务开始的时候,会制定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数据会被复制到回滚段

  3. 在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够 用,事务会在段中请求扩展下一个盘区,如果所有已分配的盘区都被用完,事务会覆盖最初的盘 区或者在回滚段允许的情况下扩展新的盘区来使用。

  4. 回滚段存在于undo表空间中,在数据库中可以存在多个undo表空间,但同一时刻只能使用一个 undo表空间。

  5. 当事务提交时,InnoDB存储引擎会做以下两件事情:

    • 将undo log放入列表中,以供之后的purge操作

    • 判断undo log所在的页是否可以重用,若可以分配给下个事务使用

回滚段中的数据分类

事务提交后不能马上删除undo log及undo log所在的页。这是因为可能还有其他事务需要通过undo log来得到行记录之前的版本。故事务提交时将undo log放入一个链表中(MVCC版本链),是否可以最终删除undo log以undo log所在页由purge线程来判断。

  1. 未提交的回滚数据(uncommitted undo information):该数据所关联的事务并未提交,用于实现读一致性,所以该数据不能被其他事务的数据覆盖。

  2. 已经提交但未过期的回滚数据(committed undo information):该数据关联的事务已经提交,但是仍受到undo retention参数的保持时间的影响。

  3. 事务已经提交并过期的数据(expired undo information):事务已经提交,而且数据保存时间已经超过 undo retention参数指定的时间,属于已经过期的数据。当回滚段满了之后,就优先覆盖“事务已经提交并过期的数据"。

undo的类型

在InnoDB存储引擎中,undo log分为:

  • insert undo log

    insert undo log是指insert操作中产生的undo log。因为insert操作的记录,只对事务本身可见,对其他事务不可见(这是事务隔离性的要求),故该undo log可以在事务提交后直接删除。不需要进行purge操作。

  • update undo log

    update undo log记录的是对delete和update操作产生的undo log。该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。

undo log的生命周期

简要生成过程

以下是undo+redo事务的简化过程

假设有两个数值,分别为A=1和B=2,然后将A修改为3,B修改为4

只有Buffer Pool的流程:

修改数据和查询数据,都是不存在就从磁盘中加载进buffer pool,更新数据时就先更新buffer pool中的数据,然后定时刷入磁盘中
 

有了Redo Log和Undo Log之后:

在更新Buffer Pool中的数据之前,我们需要先将该数据事务开始之前的状态写入Undo Log中。假设更新到一半出错了,我们就可以通过Undo Log来回滚到事务开始前。并将修改的数据同步到redo log 中


 

详细生成过程


当我们执行INSERT时:

​​​​​​​begin;
INSERT INTO user (name) VALUES ("tom"); 

 插入的数据都会生成一条insert undo log,并且数据的回滚指针会指向它。undo log会记录undo log的序号、插入主键的列和值...,那么在进行rollback的时候,通过主键直接把对应的数据删除即可。

当我们执行UPDATE时:  

对应更新的操作会产生update undo log,并且会分更新主键和不更新主键的,假设现在执行:

UPDATE user SET name="Sun" WHERE id=1;

这时会把老的记录写入新的undo log,让回滚指针指向新的undo log,它的undo no是1,并且新的undo log会指向老的undo log(undo no=0)。  

 UPDATE user SET id=2 WHERE id=1;

 

对于更新主键的操作,会先把原来的数据deletemark标识打开,这时并没有真正的删除数据,真正的删除会交给清理线程去判断,然后在后面插入一条新的数据,新的数据也会产生undo log,并且undo log的序号会递增。

可以发现每次对数据的变更都会产生一个undo log,当一条记录被变更多次时,那么就会产生多条undo log,undo log记录的是变更前的日志,并且每个undo log的序号是递增的,那么当要回滚的时候,按照序号依次向前推,就可以找到我们的原始数据了

undo log是如何回滚的


以上面的例子来说,假设执行rollback,那么对应的流程应该是这样:

  1. 通过undo no=3的日志把id=2的数据删除

  2. 通过undo no=2的日志把id=1的数据的deletemark还原成0

  3. 通过undo no=1的日志把id=1的数据的name还原成Tom

  4. 通过undo no=0的日志把id=1的数据删除

undo log的删除

  • 针对于insert undo log

    因为insert操作的记录,只对事务本身可见,对其他事务不可见。故该undo log可以在事务提交后直接删除,不需要进行purge操作。

  • 针对于update undo log

    该undo log可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,等待purge线程进行最后的删除。

小结 

undo log是逻辑日志,对事务回滚时,只是将数据库逻辑地恢复到原来的样子。

redo log是物理日志,记录的是数据页的物理变化,undo log不是redo log的逆过程。

 

 


http://www.ppmy.cn/server/168953.html

相关文章

Java零基础入门笔记:(4)方法

前言 本笔记是学习狂神的java教程,建议配合视频,学习体验更佳。 【狂神说Java】Java零基础学习视频通俗易懂_哔哩哔哩_bilibili 第1-2章:Java零基础入门笔记:(1-2)入门(简介、基础知识)-CSDN博客 第3章…

DST Get Log Page相关NVMe Command

Admin Command 1. Device Self-Test(DST)设备自检命令 参考SQE结构: Namespace Test Action 在NSID字段中如果设置为00000000h表示不包括NS,DST操作只包括Controller; 00000001~FFFFFFFEh表示指定NSID,…

力扣-二叉树-700 二叉搜索树中的搜索

思路 根据左右大小关系&#xff0c;寻找节点 代码 class Solution { public:TreeNode* searchBST(TreeNode* root, int val) {if(root->val val){return root;}if(root->val < val){if(root->right) return searchBST(root->right, val);}else{if(root->…

无人机常见的开源飞控项目

开源飞控软件项目为无人机等无人载具的开发和应用提供了丰富的资源和灵活的解决方案&#xff0c;以下是一些常见的开源飞控软件项目&#xff1a; 1、PX4 简介&#xff1a;PX4 是一个高度模块化、可扩展的开源飞行控制平台&#xff0c;被广泛应用于各种类型的无人机&#xff0…

MoE硬件部署

文章目录 MoE硬件部署硬件需求**专家硬件映射&#xff1a;模块化计算单元****路由硬件加速&#xff1a;门控网络专用单元****内存与通信优化****能效控制策略****实例&#xff1a;假设部署Mixtral 8x7B到自研AI芯片** 资源分配硬件资源预分配&#xff08;编译时&#xff09;运行…

【愚公系列】《Python网络爬虫从入门到精通》008-正则表达式基础

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…

Qt笔记31-69

06QMainWindow 知识点1&#xff1a;QMainWindow概述 QMainWindow是一个为用户提供主窗口程序的类&#xff0c;包含一个菜单栏&#xff0c;多个工具栏&#xff0c;多个铆接部件&#xff0c;一个状态栏及一个中心部件 知识点2&#xff1a;菜单栏 菜单栏类QMenuBar 菜单类QMen…

【Java 面试 八股文】并发编程篇

并发编程篇 1. 线程和进程的区别&#xff1f;2. 并行和并发有什么区别&#xff1f;3. 创建线程的方式有哪些&#xff1f;4. runnable 和 callable 有什么区别5. 线程的 run()和 start()有什么区别&#xff1f;6. 线程包括哪些状态&#xff0c;状态之间是如何变化的7. 新建 T1、…