深入分析MySQL事务日志-Undo Log日志

news2024/12/22 9:23:12

文章目录

  • InnoDB事务日志-Undo Log日志
    • 2.1 Undo Log
      • 2.1.1 Undo Log与原子性
      • 2.1.2 Undo的存储格式
        • 1)insert类型Undo Log
        • 2)delete类型Undo Log
        • 3)update类型Undo Log
      • 2.1.3 Undo Log的工作原理
      • 2.1.4 Undo Log的系统参数
      • 2.1.5 Undo Log与Purge线程

InnoDB事务日志-Undo Log日志

事务的隔离性是通过锁实现,而事务的原子性、和持久性则是通过事务日志实现。在MySQL中,事务日志分为两类,一个是Redo Log,也叫重做日志,另一个是Undo Log,也叫回滚日志;其中Redo Log保证事务的持久性,Undo Log保证的是事务的原子性

2.1 Undo Log

2.1.1 Undo Log与原子性

事务的持久性是交由Redo Log来保证,原子性则是交由Undo Log来保证。如果事务中的SQL执行到一半出现错误,需要把前面已经执行过的SQL撤销以达到原子性的目的,这个过程也叫做"回滚",所以Undo Log也叫回滚日志。

Undo Log记录了数据在每个操作前的状态,这些记录包括旧的数据值和事务的 ID。如果事务执行过程中需要回滚,就可以根据Undo Log进行回滚操作。

每当我们要对一条记录做改动时(这里的改动可以指INSERT、DELETE、UPDATE),把回滚时所需的东西记下来。比如:

  • 当执行了一条insert语句时:至少要把这条记录的主键值记下来,之后回滚的时候只需要把这个主键值对应的记录删掉就好了。对于事务中的每个insert语句,在事务回滚时InnoDB都会完成一个delete操作。
  • 当执行了一条delete语句时:至少要把这条记录中的内容都记下来,这样之后回滚时再把由这些内容组成的记录插入。对于事务中的每个delete语句,在事务回滚时InnoDB都会完成一个insert操作。
  • 当执行了一条update语句时:至少要把修改这条记录前的旧值都记录下来,这样之后回滚时再把这条记录更新为旧值。对于事务中的每个update语句,在事务回滚时InnoDB都会完成一个反向的update操作。

另外,Undo Log 也是实现多版本并发控制的基础,通过保存旧版本的数据,InnoDB 可以在并发事务中提供隔离级别,如读已提交(Read Committed)、可重复读(Repeatable Read)等。

Tips:Undo Log主要保证事务的原子性,即通过记录修改前的状态,以提供回滚功能,其次Undo Log用于提供MVCC的快照读。

2.1.2 Undo的存储格式

Redo属于物理日志,即记录了数据库页的物理修改操作,比如页上的哪些字节被更改,具体到物理结构上。Undo属于逻辑日志,即记录了从逻辑角度如何撤销已经发生的变更的信息,第一步第二步该如何做等,通常包括了反向操作所需要的数据。

Tips:“Redo属于物理日志”意味着它详细记录了物理层面的数据页是如何被改变的;而“Undo属于逻辑日志”则表示它更多是从逻辑角度出发,记录了为实现某种目的(如回滚或访问历史版本)所需执行的操作步骤。这两者共同保障了MySQL数据库中事务处理的ACID特性。

在InnoDB中,所有表中都会有三个隐藏的列,分别为:DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR。

  • DB_TRX_ID:数据行版本号,也叫事务ID。当有新的数据修改或插入时的事务ID号,用于记录修改这条记录的事务ID和创建这条记录的事务ID。(记录这条数据是哪个事务修改的,哪个事务创建的)
  • DB_ROLL_PTR:删除行版本号,也叫回滚指针。指向Undo Log中这条记录的上一个版本,删除记录,记录当前事务ID。(记录这条数据是哪个事务删除的)
  • DB_ROW_ID:聚集索引。如果数据表没有主键,InnoDB会创建一个DB_ROW_ID作为聚集索引。

其中事务ID与回滚指针和Undo Log日志密切相关,另外在InnoDB中,Undo Log分为Insert Undo Log和update Undo Log两种类型,其中删除操作也是借助update Undo Log来完成的。

1)insert类型Undo Log

执行如下insert语句:

insert into user values(1,"小灰",20);

当事务开启后,执行的insert语句都会以“insert类型的undo log”记录在undo log日志中,本次事务插入的所有的数据行的版本号字段都为当前事务的ID。

如果需要进行事务回滚,根据undo log中记录的主键进行delete操作即可。

2)delete类型Undo Log

执行如下delete语句:

delete from user where id=1;

当事务开启后,InnoDB对于delete语句的流程是:

  • 1)将被删除的行以“update类型的undo log”记录到undo log日志中。
  • 2)将该行的事务ID设置为当前事务ID,回滚指针设置为被删除前那条记录的事务ID。
  • 3)将删除标记设置为1,表示该记录是被删除掉的记录。
  • 4)更改表空间。

3)update类型Undo Log

执行如下update语句:

update user set name="小绿" where id=1;

当事务开启后,InnoDB对于update语句的流程是:

  • 1)将被修改的行以“update类型的undo log”记录到undo log日志中。
  • 2)将该行的事务ID设置为当前事务ID,回滚指针设置为被删除前那条记录的事务ID。
  • 3)更改表空间。

当同一条数据被修改多次,那么Undo Log将通过数据的事务ID和回滚指针能够形成一个非常好的修改链路:

2.1.3 Undo Log的工作原理

InnoDBMySQL启动时,会在内存中构建一个BufferPool,而这个缓冲池主要存放两类东西,一类是数据相关的缓冲,如索引、锁、表数据等,另一类则是各种日志的缓冲,如Undo、Redo....等日志。当一条写SQL执行时,MySQL并不会直接去往磁盘中的ibd文件写数据,而是先修改内存中的Buffer Pool,这样性能就能得到极大的提升。

与Redo Log一样,Undo Log也存在内存缓冲区,即Undo Log Buffer。当一条写SQL执行时,不会直接去往磁盘中的xx.ibdata文件中的Undo Log写数据,而是会写在undo_log_buffer缓冲区中,因为工作线程直接去写磁盘太影响效率了,写进缓冲区后会由后台线程去刷写磁盘。

  • Undo Log完整的工作原理如下:

首先在操作表时,会将表数据从磁盘(.idb)加载到内存中(Buffer),对表的update/delete等操作InnoDB都会事先将修改前的数据备份到Undo Buffer中,这样当事务进行回滚时可以根据Undo Buffer中的内容进行事务的回滚操作,除此之外,Undo Buffer提供了数据的快照读取,在事务未提交之前,Undo 日志可以作为并发读写时的读快照,来保证事务的可重复读;

事务做到一半了,失败了,那就要将数据还原到未提交之前的状态,undo 就是记录这些事务步骤的。当然了redo 也记录了,但是redo里面东西太繁杂,不可能什么事都找它(主要是Redo和Undo的格式不一样,应用场景也不一样),于是就将事务步骤写入另外一个地方:undo,以后遇到回滚了就去查找因此在每一步操作时都会写入磁盘中的Undo Log;

引入Undo Log Buffer是来提升Undo Log的性能的,比较操作内存要比操作磁盘快多了,但由此也引入了另外一个问题,那就是既然内存中记录了Undo Log的值,为什么还要在磁盘中也记录Undo Log的值呢?难道Undo Log也要保证持久性?

并不是,在InnoDB中持久性由Redo保证。Undo之所以要写人磁盘是因为InnoDB对数据进行了多版本的控制(MVCC)。

观察如下案例:

session-01session-02
begin;
begin;
select * from user;
update user set name=‘小蓝’ where id=1;
commit;
select * from user; – 能否查询到修改的数据?

如果当前的事务隔离级别为RR(可重复读),那么在session-02事务中修改的数据是不能被查询出来。那数据库表中id=1的这一行数据的name值有没有被改为"小蓝"呢?答案是肯定的,因为事务都已经提交了,磁盘表中的name已经修改为了"小蓝"。这就引入了一个问题,并不是提交的数据就一定能被查询出来的,有时候需要查询旧数据。Undo Log正是保存那些旧版本的数据,让其在其他事务中可见。

2.1.4 Undo Log的系统参数

InnoDBundo log的管理采用段的方式,也就是回滚段(rollback segment) 。每个回滚段记录了 1024 个 undo log segment ,每个事务只会使用一个回滚段,当一个事务开始的时候,会制定一个回滚段,在事务进行的过程中,当数据被修改时,原始的数据会被复制到回滚段。

在MySQL5.5的时候,只有一个回滚段,那么最大同时支持的事务数量为1024个。在MySQL 5.6开始,InnoDB支持最大 128个回滚段,故其支持同时在线的事务限制提高到了 128*1024 。

我们可以查看InnoDB中Undo Log的有关系统参数,在MySQL5.5之前没有太多参数,如下:

mysql> show variables like 'innodb_max_undo_log_size';
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| innodb_max_undo_log_size | 1073741824 |
+--------------------------+------------+
1 row in set (0.00 sec)

mysql> show variables like 'innodb_rollback_segments';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_rollback_segments | 128   |
+--------------------------+-------+
1 row in set (0.00 sec)
  • innodb_max_undo_log_size:本地磁盘文件中,Undo-log的最大值,默认1GB
  • innodb_rollback_segments:指定回滚段的数量,默认为1个。

除开上述两个参数外,其他参数基本上是在MySQL5.6才有的,如下:

mysql> show variables like '%innodb_undo%';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_undo_directory    | ./    |
| innodb_undo_log_truncate | OFF   |
| innodb_undo_logs         | 128   |
| innodb_undo_tablespaces  | 0     |
+--------------------------+-------+
4 rows in set (0.00 sec)
  • innodb_undo_directory: 设置rollback segment文件所在的路径。这意味着rollback segment可以存放在共享表空间以外的位置,即可以设置为独立表空间。该参数的默认值为“/”,即MySQL的数据文件夹。
  • innodb_undo_logs: 设置rollback segment的个数,默认值为128,也就是之前的innodb_rollback_segments
  • innodb_undo_tablespaces: 设置构成rollback segment文件的数量,这样rollback segment可以较为平均地分布在多个文件中。设置该参数后,会在路径innodb_undo_directory看到undo为前缀的文件,该文件就代表rollback segment文件。
  • innodb_undo_log_truncate:是否开启Undo-log的在线压缩功能,即日志文件超过大小一半时自动压缩,默认OFF关闭。

MySQL5.5版本以后,Undo-log日志支持单独存放,并且多出了几个参数可以调整Undo-log的区域。

2.1.5 Undo Log与Purge线程

前面提到,事务提交后Undo Log日志并不会马上删除,因为其他事务很可能需要用到该数据。直接移除可能会导致其他事务读不到数据。那么对于废弃的undo log日志在什么时候删除呢?另外磁盘表中的被标记为删除的记录(数据空洞),也需要进行空间释放。这些数据都是由MySQL内部的线程——Purge线程来执行后台删除。

  • 针对于insert undo log,因为insert操作的记录,只对事务本身可见,对其他事务不可见。故该undo log在事务提交后就没有用,就会直接删除。
  • 针对于update undo log,该undo log需要支持MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log链表,有专门的purge线程进行删除。

有关于Purge线程的参数:

mysql> show variables like '%purge%';
+--------------------------------------+-------+
| Variable_name                        | Value |
+--------------------------------------+-------+
| gtid_purged                          |       |
| innodb_max_purge_lag                 | 0     |
| innodb_max_purge_lag_delay           | 0     |
| innodb_purge_batch_size              | 300   |
| innodb_purge_rseg_truncate_frequency | 128   |
| innodb_purge_threads                 | 4     |
| relay_log_purge                      | ON    |
+--------------------------------------+-------+
7 rows in set (0.01 sec)
  • innodb_max_purge_lag:当InnoDB存储引擎压力非常大时,Purge线程可能并不会工作,此时是否要延缓DML的操作,innodb_max_purge_lag控制Undo Log的数量,如果数量大于该值,就延缓DML的操作,默认为0,代表不延缓;
  • innodb_max_purge_lag_delay:表示当上面innodb_max_purge_lag的delay超时时间太大,超过这个参数时,将delay设置为该参数值,防止purge线程操作缓慢导致其他SQL线程长期处于等待状态。默认为0,一般不用修改。
  • innodb_purge_batch_size:用来设置每次purge操作需要清理的Undo Log page的数量。
  • innodb_purge_threads:Purge线程的数量(默认为4,最大为32)

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

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

相关文章

【Linux 报错】vim 保存文件时出现 E45: ‘readonly‘ option is set (add ! to override)

一、错误原因 该错误表明当前你尝试保存的是一个 只读文件,该文件权限设置为只读,具有只读的标识 系统为了防止你意外修改该只读文件,因此会阻止对只读文件的保存(他怕你修改了你还保存,破坏了只读属性) …

媒界:2025河南台球及配套设施展会3月举办

立足中原,辐射全国,壹肆柒中国国际台球产业博览会3月在郑州盛大举办; 2025中国(郑州)国际台球产业博览会(壹肆柒台球展) The 2025 China (Zhengzhou) International Billiards Industry Expo …

2021年的burpsuite安装。

安装burpsuite 很简单的。 1.要有java环境,也就是jdk,并且jdk版本要与burpsuite要对应。(如果你的bp安装不起,可能是你的jdk版本不对) 2.就是按照我都步骤走就行。 3.下载完文件之后,全程离线操作 说明一下…

spring boot 项目如何使用jasypt加密

1.首先&#xff0c;添加jasypt依赖 <dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.0</version></dependency> 2.然后winr&#xff0c;cmd调出窗…

Rapid品牌SSL证书通配符单域名申请窍门

RapidSSL最初以FreeSSL的名称引入数字世界&#xff0c;于2003年诞生&#xff0c;扎根于以技术为中心的加利福尼亚州山景城。如今&#xff0c;它是GeoTrust旗下一家值得骄傲的子公司&#xff0c;其战略定位是满足市场对经济高效的SSL证书解决方案的需求。 Rapid属于Geotrust品牌…

Redis篇(初识Redis)

目录 一、数据库 二、NoSQL 三、认识Redis 三、关系数据库与非关系数据库对比 1. 结构化与非结构化 2. 关联和非关联 3. 查询方式 4. 事务 5. 存储方式 6. 扩展性 7. 总结 7.1. 图形梳理 7.2. 表格梳理 7.3. 优缺点 关系型数据库 非关系型数据库 四、再次认识R…

LeetCode142. 环形链表 II(2024秋季每日一题 28)

给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个节点。 如果链表无环&#xff0c;则返回 null。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再次到达&#xff0c;则链表中存在环。 为了表示给定链表中的环&#xff0c;评测系统内部使用整数…

C++:STL详解(二)string类的模拟实现

✨ Blog’s 主页: 白乐天_ξ( ✿&#xff1e;◡❛) &#x1f308; 个人Motto&#xff1a;他强任他强&#xff0c;清风拂山冈&#xff01; &#x1f4ab; 欢迎来到我的学习笔记&#xff01; &#x1f525;&#x1f525;&#x1f525;&#x1f525;&#x1f525;本文参考文章&…

合同管理中的常见陷阱,你是否也中招了?

在合同管理中&#xff0c;很多企业常常会掉进一些意想不到的“陷阱”。这些问题可能在日常工作中看似无关紧要&#xff0c;但一旦忽视&#xff0c;往往会引发一系列严重的后果。合同信息管理混乱&#xff0c;导致重要条款被遗漏&#xff0c;签署文件时出现纰漏&#xff1f;合同…

Pygame中Sprite实现逃亡游戏4

在《Pygame中Sprite实现逃亡游戏3》中实现了玩家跳跃飞火的效果&#xff0c;接下来通过精灵类的碰撞检测来判断飞火是否击中玩家、飞火是否击中飞龙以及飞龙是否抓住玩家。 1 飞火是否击中玩家的判断 判断飞火是否击中玩家的代码如图1所示。 图1 判断飞火是否击中玩家的代码 …

大数据-144 Apache Kudu 基本概述 数据模型 使用场景

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

企业私有网盘怎么搭建?整理国内外主流 18 家方案厂商

目前市场上主流的企业网盘有360亿方云、坚果云、百度企业网盘、联想企业网盘、燕麦云智能企业云盘、腾讯企业网盘等等。就创立时间和用户量来看&#xff0c;联想企业网盘、360亿方云可以说第一梯队的存在。 企业需要的不仅仅是文档存储、分享和协作的简单管理工具&#xff0c;还…

AI无人直播新标杆,一站式直播解决方案:打造专属舞台!

AI无人直播新标杆&#xff0c;一站式直播解决方案&#xff1a;打造专属舞台&#xff01; 在数字化浪潮的汹涌澎湃中&#xff0c;AI技术正以前所未有的速度渗透至各行各业&#xff0c;其中&#xff0c;直播行业作为数字内容传播的重要阵地&#xff0c;正经历着一场由AI引领的深刻…

pr视频剪辑、福昕剪辑……四款剪辑视频大比拼

最近入了视频剪辑的坑&#xff0c;我最近在尝试不同的视频剪辑软件&#xff0c;想找到最适合我的那一款。今天&#xff0c;我就来跟大家分享一下我使用福昕视频剪辑、爱拍视频剪辑、Adobe Premiere&#xff08;简称PR&#xff09;和Shotcut这四款软件时的一些体验和感受。希望我…

移动硬盘突然打不开:深度剖析、恢复策略与预防措施

突发困境&#xff1a;移动硬盘的沉默拒绝 在日常的数字生活中&#xff0c;移动硬盘作为数据存储与传输的重要工具&#xff0c;扮演着不可或缺的角色。然而&#xff0c;当您急需访问存储在移动硬盘中的重要文件时&#xff0c;却遭遇了“突然打不开”的尴尬境地&#xff0c;这无…

C++ 3 个有序点的方向(Orientation of 3 ordered points)

给定三个点 p1、p2 和 p3&#xff0c;任务是确定这三个点的方向。 平面中有序三重点的方向可以是 逆时针 顺时针 共线 下图显示了 (a,b,c) 的不同可能方向 如果 (p1, p2, p3) 的方向共线&#xff0c;则 (p3, p2, p1) 的方向也共线。 如果 (p1, p2, p3) 的方向是顺时针&a…

idea不想提交前端代码,只提交.java和.xml文件配置

1.按图创建.gitignore文件 &#xff08;忽略文件&#xff09; 2.该文件的内容 直接cp /.gitignore *.DS_Store Thumbs.db *.sw? .#* *# *~ *.sublime-* # Build Artifacts .gradle/ build/ target/ bin/ dependency-reduced-pom.xml # Eclipse Project Files .classpath .pro…

Python办公自动化案例:将Excel数据批量保存到Word表格中

案例:将excel数据批量保存到Word表格中 要将Excel数据批量保存到Word表格中,可以使用Python的openpyxl库来读取Excel文件,以及python-docx库来创建和编辑Word文档。以下是一段示例代码,以及代码解释和一些注意事项。 准备好的Excel数据: 1.安装所需库 首先,确保你已经…

Electron-vue asar 局部打包优化处理方案——绕开每次npm run build 超级慢的打包问题

背景 因为组员对于 Electron 打包过程存在比较迷糊的状态&#xff0c;且自己也没主动探索 Electron-vue 打包细节&#xff0c;导致每次打包过程都消耗 5-6 分钟的时间&#xff0c;在需要测试生产打包时&#xff0c;极其浪费时间&#xff0c;为此针对 Electron-vue 打包的几个环…

如何使用ssm实现学生考勤管理系统的设计与实现+vue

TOC ssm703学生考勤管理系统的设计与实现vue 绪论 课题背景 身处网络时代&#xff0c;随着网络系统体系发展的不断成熟和完善&#xff0c;人们的生活也随之发生了很大的变化。目前&#xff0c;人们在追求较高物质生活的同时&#xff0c;也在想着如何使自身的精神内涵得到提…