MySQL系列—12.Undo log

news/2024/9/19 3:34:24 标签: mysql, 数据库

1、概念

DML 操作导致数据变化 , 将变化前的记录写入 Undo 日志。

作用

用于记录更改前的一份 copy ,在操作出错时,可以用于回滚、撤销还原,只将数据库
逻辑地恢复到原来的样子
插入一条记录时,至少要把这条记录的主键值记下来,之后回滚的时候只需要把这个主键值对应的记录删掉就好了。(对于每个INSERT,InnoDB存储引擎会完成一个DELETE)
删除了一条记录,至少要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入到表中就好了。(对于每个DELETE,innoDB存储引擎会执行一个INSERT)
修改了一条记录,至少要把修改这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值就好了。(对于每个UPDATE,InnoDB存储引擎会执行一个相反的UPDATE,将修改前的行放回去)

存储位置

undo 存储在回滚段 ( Rollback Segment) ,每个回滚段记录了 1024 undo log segment

参数

innodb_undo_directory
设置 rollback segment文件所在的路径。这意味着 rollback segment可以存放在共享表空间以外的位置,即可以设置为 独立表空间。该参数的默认值为“./"”,表示当前InnoDB存储引擎的目录。
innodb_undo_tablespaces
设置构成 rollback segment文件的数量,设置该参数后,会在路径 innodb_undo_directory看到 undo为前缀的文件,该文件就代表 rollback segment文件。

回滚段与事务

    每一个事务只会使用一个回滚段,一个回滚段在同一个时刻可能会服务于多个事务。
    当一个事务开始的时候,会制定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数据会被复制到回滚段。
    在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够用,事务会在段中请求扩展下一个盘区,如果所有已分配的盘区都被用完,事务会覆盖最初的盘区或者在回滚段允许的情况下扩展新的盘区来使用。
    回滚段存在于undo表空间中,在数据库中可以存在多个undo表空间,但同一时刻只能使用一个undo表空间。

purge线程作用
( 1 ) 清理 undo 页和清除 page 里面带有 Delete_Bit 标识的数据行
( 2 )InnoDB 中,事务中的 Delete 操作实际上并不是真正的删除掉数据行,而是一种 Delete Mar
k 操作,在记录上标识 Delete_Bit ,而不删除记录。是一种 " 假删除 ", 只是做了个标记,真正的
删除工作需要后台 purge 线程去完成。

回滚段中的数据分类

    未提交的回滚数据(uncommitted undo information):该数据所关联的事务并未提交,用于实现读一致性,所以该事务不能被其他事务的数据所覆盖。
    已经提交但未过期的回滚数据(committed undo information) :该数据关联的事务已经提交,但是仍然受到undo retention参数的保持时间的影响。
    事务已经提交并过期的数据(expired undo information) :事务已经提交,而且数据保存时间已经超过undo retention参数指定的时间,属于已经过期的数据。当回滚段满了之后,会优先覆盖"事务已经提交并过期的数据"。

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

undo的类型

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

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

详细生成过程

对于InnoDB引擎来说,每个行记录除了记录本身的数据之外,还有几个隐藏的列:

    DB_ROW_ID:如果没有为表显式的定义主键,并且表中也没有定义唯一索引,那么InnoDB会自动为表添加一个row_id的隐藏列作为主键。(之前索引的创建过程中讲过)
    DB_TRX_ID:每一个事务都会分配一个事务ID,当对某条记录发生变更时,就会将这个事务的事务ID写入trx_id中。
    DB_ROLL_PTR:回滚指针,本质上就是undo 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;

这下面是把id=1的记录,改为id=2。这里并不是简单的将id为1改为2,而是先将id=1的那个记录删除掉,然后再生成一条记录id=2

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

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

undo log是如何回滚的

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

    通过undo no=3的日志把id=2的数据删除
    通过undo no=2的日志把id=1的数据的deletemark还原成0
    通过undo no=1的日志把id=1的数据的name还原成Tom
    通过undo no=0的日志把id=1的数据删除

2、redo & undo

下面是redo log + undo log的简化过程,便于理解两种日志的过程:

假设有 A B 两个数据,值分别为 1 , 2.
1. 事务开始 ; begin
2. 记录 A = 1 undo log
3. 修改 A = 3
4. 记录 A = 3 redo log
5. 记录 B = 2 undo log
6. 修改 B = 4
7. 记录 B = 4 redo log
8. redo log buffer 写入磁盘 redo log
9. 事务提交

3、CR流程

1. 什么时候会进行 Crash Recovery?
- 实例崩溃之后重启
- innodb_fast_shutdown为1 值关闭实例后重新启动
2. 检测实例是不是干净地关闭的
- 打开 Redo Logs 和系统表空间文件 (ibdataN)
- 读取并从中找到最大的 Checkpoint LSN
- 从最近的 Checkpoint 开始往后扫描 Redo Log
- 如果能够找到 Redo Log 记录,说明还有数据页的更改没有刷新到数据文件上,启动 Crash Re
covery
3.损坏页修复
- 检查双写缓冲区中的所有 128 个页
- 如果页头和页尾的 LSN 不匹配或页面校验和无效,则使用双写缓冲区中的页进行还原
- 如果该页在双写缓冲区中的版本也被破坏,则 server crash
4.前滚 Redo ,提交未提交事务
- 从最近的 Checkpoint 往后扫描到的 Redo Log 记录将被应用到各个数据文件中
- 使用 Undo Log 回滚未提交的 'ACTIVE' 状态的事务         
- 处于 PREPARE 状态的事务,如果打开了 binlog 且在 binlog 有找到对应事务的日志则重新提
交,否则回滚

http://www.niftyadmin.cn/n/5664910.html

相关文章

【自学笔记】支持向量机(2)——核函数

引入 核函数的功能是将一组数据映射到更高维的特征空间,这样可以让在低维无法线性分类的数据能够在高维空间下被分类。   可以证明,如果原始数据是有限的维度,那么一定存在一个高维特征空间使得样本线性可分。 文章内容由《机器学习》相关内…

深度学习-点击率预估-研究论文2024-09-14速读

深度学习-点击率预估-研究论文2024-09-14速读 1. Deep Target Session Interest Network for Click-Through Rate Prediction H Zhong, J Ma, X Duan, S Gu, J Yao - 2024 International Joint Conference on Neural Networks, 2024 深度目标会话兴趣网络用于点击率预测 摘…

JAVA基础:正则表达式,String的intern方法,StringBuilder可变字符串特点与应用,+连接字符串特点

1 String中的常用方法2 1.1 split方法 将字符串按照指定的内容进行分割,将分割成的每一个子部分组成一个数组 分割内容不会出现在数组中 实际上该方法不是按照指定的简单的符号进行分割的,而是按照正则表达式进行分割 1.2 正则表达式 用简单的符号组合…

linux-系统管理与监控-设备管理

Linux 系统管理与监控:设备管理 在 Linux 系统中,设备管理是操作系统管理硬件资源的重要部分。通过设备管理,系统能够与计算机的硬件组件(如存储设备、网络接口、输入输出设备等)进行交互,并提供一个抽象的…

企业架构如何推动组织中成功的数字化转型

在当今的数字世界中,成功数字化转型的需求比以往任何时候都更加重要。公司越来越多地参与数字化转型,以保持相关性和竞争力。然而,数字化转型不仅仅是技术更新。它需要一种战略方法来整合业务流程、模型和目标。这就是企业架构发挥作用的地方…

基于open-gpu-kernel-modules的p2p vram映射bar1提高通信效率

背景 bar1 Base Address Register 1 用于内存映射的寄存器,定义了设备的内存映射区域,BAR1专门分配给gpu的一部分内存区域,允许cpu通过pcie总线直接访问显存VRAM中的数据。但bar1的大小是有限的,在常规的4090上,bar1只…

dcmtk的自动输入数据纠错模式对DICOMDIR读取的影响

软件版本 dcmtk 3.6.7 自动纠错的全局变量 输入数据的自动纠错是一个全局变量,定义在dcmtk/dcmdata/dcobject.h中,如下所示: /** This flags defines whether automatic correction should be applied to input* data (e.g.\ stripping …

【C语言】带你手把手拿捏指针(3)(含转移表)

文章目录 一、字符指针变量二、数组指针变量1.数组指针变量是什么2.数组指针变量的初始化 三、二维数组传参的本质四、函数指针变量1. 函数指针变量的创建2.函数指针的使用3.案例解析: 五、typedof关键字六、函数指针数组和转移表1.函数指针数组2.转移表 一、字符指…