深入分析MySQL事务日志-Undo Log日志
文章目录
- 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的工作原理
InnoDB在MySQL启动时,会在内存中构建一个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-01 | session-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的系统参数
InnoDB对undo 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)
相关文章:
深入分析MySQL事务日志-Undo Log日志
文章目录 InnoDB事务日志-Undo Log日志2.1 Undo Log2.1.1 Undo Log与原子性2.1.2 Undo的存储格式1)insert类型Undo Log2)delete类型Undo Log3)update类型Undo Log 2.1.3 Undo Log的工作原理2.1.4 Undo Log的系统参数2.1.5 Undo Log与Purge线程…...
828华为云征文 | 在Huawei Cloud EulerOS系统中安装Docker的详细步骤与常见问题解决
前言 Docker是一种轻量级的容器技术,广泛用于应用程序的开发、部署和运维。在华为云的欧拉(Huawei Cloud EulerOS)系统上安装和运行Docker,虽然与CentOS有相似之处,但在具体实现过程中,可能会遇到一些系统…...
什么是数据增强中的插值法?
一、插值法的概念 在数据增强中,插值法是一种重要的技术,它通过数学模型在已知数据点之间估计未知数据点的值。这种方法可以帮助我们在不增加实际数据的情况下,通过生成新的数据点来扩展数据集。插值法基于这样的假设:如果已知的数…...
springboot实战学习(9)(配置mybatis“驼峰命名“和“下划线命名“自动转换)(postman接口测试统一添加请求头)(获取用户详细信息接口)
接着学习。之前的博客的进度:完成用户模块的注册接口的开发以及注册时的参数合法性校验、也基本完成用户模块的登录接口的主逻辑的基础上、JWT令牌"的组成与使用以及完成了"登录认证"(生成与验证JWT令牌)具体往回看了解的链接…...
之前做了抵押贷款,现在房市不景气,马上贷款要到期了该怎么办?
面对房贷的重压,特别是对于那些正承受高息贷款之苦的现有房产业主而言,探索有效的减负策略显得尤为重要。今天,我们共同探讨几种智慧策略,旨在帮助您巧妙减轻房贷的经济负担。 一、优化贷款结构:低息置换的魔力 当前&a…...
poi生成的ppt,powerPoint打开提示内容错误解决方案
poi生成的ppt,powerPoint打开提示内容错误解决方案 最近做了ppt的生成,使用poi制作ppt,出现一个问题。微软的powerPoint打不开,提示错误信息 通过xml对比工具发现只需要删除幻灯片的某些标签即可解决。 用的是XML Notepand 分…...
基于stm32物联网身体健康检测系统
在当今社会,由于经济的发展带来了人们生活水平不断提高,但是人们的健康问题却越来越突出了,各种各样的亚健康随处可在,失眠、抑郁、焦虑症,高血压、高血糖等等侵袭着人们的健康,人们对健康的关注达到了一个…...
BeautifulSoup4在爬虫中的使用
一、Beautiful Soup4简介 Beautiful Soup 提供一些简单的python函数来处理导航、搜索等功能。 它是一个工具箱,是python的一个库,最主要的功能是从网页获取数据。 二、Beautiful Soup4安装 在cmd下安装 pip install beautifulsoup4三、BeautifulSou…...
Laya2.x出包alipay小游戏
小游戏开发者工具,支付宝官方已经出了,不说了。 1.LAYA2.X打出得小游戏包中my-adapter.js这个文件需要替换,或者自行修改,替换3.x得; 2.unity导包出得模型文件命名需要注意,避免太长,路径也不…...
Vue极简入门
1.注册路由,如果是子路由,就加一个children import Vue from vue import Router from vue-router import Main from ../views/Main.vue import Login from ../views/Login.vueimport UserProfile from "../views/user/Profile.vue" import Us…...
系统敏感信息搜索工具(支持Windows、Linux)
目录 工具介绍 使用说明 search模块 browser模块 下载地址 工具介绍 可以快速搜索服务器中的有关username,passsword,账号,口令的敏感信息还有浏览器的账户密码。 使用说明 search模块 searchall64.exe search -p 指定路径 searchall64.exe search -p 指定路径 -s &q…...
Fyne ( go跨平台GUI )中文文档-容器和布局 (四)
本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章: Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…...
文心智能体 恐怖类游戏
智能体名称:孤岛惊魂 链接:文心智能体平台AgentBuilder | 想象即现实 (baidu.com)https://agents.baidu.com/center/agent/preview/MFhBvA0K9EXXVdjHCcUumadWmWesKvw2 角色与目标设定 🧑🏻 角色:孤岛惊魂是一位虚拟…...
智慧城市运营模式--政府和社会资本合作
1、主要特征 政府和社会资本合作模式是政府与社会资本长期合作提供公共产品和服务的一种创新模式,主要集中在纯公共领域和准公共领域,通过建立“利益共享、风险共担”的长期合作伙伴关系,在增加公共产品和服务供给数量和提升质量的同时,达到减少财政资金支出、降低企业投资…...
【Python报错已解决】ValueError: cannot convert float NaN to integer
🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 专栏介绍 在软件开发和日常使用中,BUG是不可避免的。本专栏致力于为广大开发者和技术爱好者提供一个关于BUG解决的经…...
ClickHouse 与 Quickwit 集成实现高效查询
1. 概述 在当今大数据分析领域,ClickHouse 作为一款高性能的列式数据库,以其出色的查询速度和对大规模数据的处理能力,广泛应用于在线分析处理 (OLAP) 场景。ClickHouse 的列式存储和并行计算能力使得它在处理结构化数据查询时极具优势&…...
Facebook Marketplace无法使用的原因及解决方案
Facebook Marketplace是一项广受欢迎的买卖平台,然而,有时候用户可能会遇到无法访问或使用该功能的问题。通常,这些问题可以归结为以下几类原因: 地理位置限制: Facebook Marketplace并非在全球每个地区都可用。在某些…...
uboot — uboot命令的使用
uboot的命令繁多,下文只对工作中常用到的命令进行记录,其余命令待用到时再查查资料也不迟 一、环境变量操作命令 1、printenv 打印环境变量 2、setenv 修改环境变量/新建环境变量 3、saveenv 保存环境变量/删除环境变量(给环境变量赋空值…...
基础漏洞——SSRF
目录 一.原理 二.引起ssrf的函数 三.这些函数具体作用 (1)File_get_content() (2)Fsockopen() (3)Curl_exec() 四.常见的业务场景(可能出现的漏洞的地方,漏洞挖掘)…...
报错解决方案
大模型-报错解决方案 百度千帆大模型 仅个人笔记使用,感谢点赞关注 百度千帆大模型 未开通付费模型 qianfan.errors.APIError: api return error, req_id: code: 17, msg: Open api daily request limit reached 可能的原因: 未开通所调用服务的付费权限࿰…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
佰力博科技与您探讨热释电测量的几种方法
热释电的测量主要涉及热释电系数的测定,这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中,积分电荷法最为常用,其原理是通过测量在电容器上积累的热释电电荷,从而确定热释电系数…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
