MySQL的事务日志:

目录

redo(重做日志):

特点:

组成:

整体流程:

redo log buffer与redo log file之间的刷盘策略:

异步刷盘:

同步刷盘:

拆中策略:

undo(回滚日志):

存储结构:

undo页的重用:

回滚段与事务:

回滚段中的数据分类:

未提交的回滚数据:

已经提交但未过期的回滚数据:

事务已经提交并过期的数据:

生成过程:

类型分类:

insert undo log:

update undo log:

undo删除:

insert undo log:

update undo log:

总结:


事务的隔离由锁机制实现,而事务的原子性、一致性和持久性是由事务的redo日志和undo日志来保证。其中redo是指重做日志,是存储引擎生成的日志,记录的是“物理级别”上的页修改操作,提供再写入操作,回复提交事务修改的页操作,用于保证事务的持久性。undo日志是指回滚日志,是存储引擎层生成的日志,记录的是逻辑操作日志,回滚行记录到某个特定的版本,用于保证事务的原子性、一致性。

redo(重做日志):

InnoDB存储引擎是以页为单位来管理存储空间的,在访问页面之前,需要把磁盘上的页缓存到内存中的缓冲池里面才可以访问。所有的变更都必须先更新缓冲池中的数据,然后缓冲池中的脏页(内存中修改了而磁盘中还未修改的数据页)会一定的频率被刷入磁盘,通过缓冲池来优化CPU和磁盘之间的交互。

InnoDB存储引擎的事务采用了WAL技术,WAL技术的思想是先写日志,再写磁盘,只有当日志写入成功,才算事务提交成功,而这里的日志指的是redo日志。当事务提交成功之后,还没有进行刷盘时,发生了宕机,就可以通过redo日志来进行恢复数据。

优点是:降低了刷盘的频率(不用去维持实时刷新磁盘),占用的空间非常小(存储表空间id,页号,偏移量以及需要更新的值,所以存储空间很小,而且刷盘速度快)。

特点:

redo日志是顺序写入磁盘的,在执行事务的过程中,每执行一条语句,就可能产生若干条redo日志,这些日志是按照产生的顺序写入磁盘的,使用顺序IO,效率比随机IO快。

事务执行过程中,redo不断记录,在事务执行过程中,是一直不断地往redo顺序记录,直到事务提交。

组成:

重做日志的缓冲(redo log buffer),保存在内存中,是易丢失。服务器启动时就向操作系统申请了一大片重做日志的缓冲的连续内存空间,也就是redo日志缓冲区,这片内存空间被分成很多连续的redo log block,一个占用512字节。

重做日志文件(redo log file),保存在硬盘中,是持久的。

整体流程:

先将原数据从磁盘中读入内存中,修改数据的内存拷贝。

生成一条重做日志并写入redo log buffer,记录的是数据被修改后的值。

当事务提交时,将redo log buffer中的内存刷新到redo log file,对redo log file采用追加写的方式。

定期将内存中修改的数据刷新到磁盘中。

redo log buffer与redo log file之间的刷盘策略:

重做日志缓冲刷盘到重做日志文件不是真正的刷到磁盘中去,只是刷入到文件系统缓存中,真正的写入由系统决定。而此时InnoDB就存在一个问题,如果系统宕机了,那么数据也会丢失。

所以针对这种情况,给出了一个innodb_flush_log_at_trx_commit参数来控制commit提交事务时,如何将重做日志缓冲中的日志刷新到重做日志文件中。

异步刷盘:

1.当innodb_flush_log_at_trx_commit=0时,表示每次事务提交时不进行刷盘操作。

InnoDB中有一个后台线程,每隔1秒,会把重做日志缓冲中的内容写道文件系统缓存中,然后调用刷盘操作。如果崩溃的话,可能会丢失1秒内的已提交事务数据。事务提交之后,不需要等待刷盘。

当一个没有提交事务的重做日志记录,也可能会刷盘。因为在事务执行过程中重做日志记录会写入到重做日志缓冲中,而这些记录会被后台线程刷盘。

当重做日志缓冲占用的空间即将达到innodb_log_buffer_size的一半时,后台线程会主动刷盘。

如果事务最终未提交或者崩溃恢复时,会通过undo日志回滚已刷盘的的未提交数据,保证数据的原子性。

同步刷盘:

2.当innodb_flush_log_at_trx_commit=1时,表示每次事务提交时都将进行同步刷盘操作。(默认值)

只要事务提交成功,重做日志记录一定在硬盘中,不会有任何数据丢失。如果事务执行期间宕机,相对应的部分日志丢失,但是事务并没有提交,所以日志丢失也不会造成损失,可以保证持久性,数据不会丢失,但是效率最差,因为事务提交之后需要等待重做日志缓冲中的内容写入到文件系统缓存中同时还要进行刷盘。

拆中策略:

3.当innodb_flush_log_at_trx_commit=2时,表示每次事务提交时都只把重做日志缓冲内容写入到文件系统缓存中,不进行同步。由操作系统决定同步到磁盘文件中的时间。后台线程以一定的时间间隔进行一次将文件系统缓存中的内容写入到磁盘中。事务提交之后,需要将重做日志缓存中的内容写入到文件系统缓存中,不需要等待刷盘。性能介于异步刷盘和同步刷盘之间。

如果操作系统宕机,文件系统缓存可能会有数据丢失,就无法满足持久性。

undo(回滚日志):

在事务更新数据的前置操作要先写入一个回滚日志。

undo是逻辑日志,只是将数据库逻辑地恢复到原来的样子,但是数据结构和页本身在回滚之后可能不相同。

回滚日志也会产生重做日志,因为回滚日志也需要持久性的保护。

存储结构:

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

undo页的重用:

当开启一个事务需要写undo日志时,就得去undo log segment中找空闲的位置,当有空闲位置时,就去申请undo页,这样的话,每开启一个事务就申请一个页,很浪费存储空间。所以可以对undo页进行判断是否可以重用。

当事务提交时,并不会立刻删除undo页,因为undo页的重用一个undo页可能混杂着其他事务的undo log。undo log在事务提交后,会被放到一个链表中,然后判断undo页的使用空间是否小于3/4,如果小于,则表示当前的undo页可以被重用,就不会被回收,其他事务的undo log可以记录在当前的undo页后面,由于undo页是离散的,所以清理对应的磁盘空间时,效率不高。

回滚段与事务:

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

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

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

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

当事务提交时,InnoDB存储引擎会将undo log放到列表中,以方便之后的清除操作,还会判断undo log所在的页是否可以重用,若可以则分配给下一个事务使用。

回滚段中的数据分类:

未提交的回滚数据:

该数据所关联的事务未提交,用于实现读一致性,所以该数据不能被其他事务的数据覆盖。对应事务的活动状态或者部分提交状态。

已经提交但未过期的回滚数据:

该数据关联的事务已经提交,但是仍受到undo retention参数的保持时间的影响。也就是事务提交之后,undo日志未被清理线程清理,主要针对的是update undo log。

事务已经提交并过期的数据:

该数据关联的事务已经提交,而且数据保存时间已经超过undo retention参数指定的时间,属于已经过期的数据。也就是事务提交之后,undo日志不再被MVCC依赖,清理线程通过扫描链表清理了过期条目。当回滚段满了之后,会优先覆盖“事务已经提交并过期的数据”。

事务提交之后不能马上删除undo log以及undo log所在的页,因为可能还有在其他事务需要通过undo log来得到行之前的版本,事务提交时,会将undo log放入一个链表中。

生成过程:

InnoDB存储引擎中有几个隐藏的列:

DB_ROW_ID:如果没有主键且没有唯一索引,那么会自动添加一个隐藏列作为主键。

DB_TRX_ID:每个事务都会分配一个事务ID,当对某条记录进行变更时,就会将这个事务ID写入trx_id中。

DB_ROLL_PTR:回滚指针,指向undo log的指针。

当插入一条数据时,会生成一条undo log,记录着undo log的序号、插入主键的列和值等信息,在进行回滚时,直接通过主键把对应的数据删除即可。

更新操作会分更新主键和不更新主键的情况,

如果是不更新主键,就把此次更新之前的数据写入到新的undo log中,让回滚指针指向新的undo log,让新的undo log指向旧的undo log,可以参考链表的头插法。

如果是更新主键的操作,那么会把逻辑删除的标识从0置为1,这个改变也需要通过一个undo log进行记录头插到该记录的回滚指针后面,然后在此条记录后面插入一条新的记录且新的记录的回滚指针指向的是主键更新前的记录,新的记录会产生undo log且undo log序号会递增。

类型分类:

insert undo log:

仅处理insert操作新增的数据,用于事务回滚时删除新插入的数据。回滚时根据主键直接删除对应行。

update undo log:

记录update和delete操作修改前的数据状态,支持回滚与快照读。update:保存被修改字段的旧值,delete:存储整行数据的原始内容。

undo删除:

insert undo log:

因为insert操作记录,只对本事务可见,所以可以在事务提交后进行删除。

update undo log:

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

总结:

目标数据如果不在缓存池中,将磁盘中的数据页写入到内存缓冲池中,将原数据写入到undo日志中便于回滚,进行数据的更新操作,会将对应的数据写入到redo日志缓存当中,当提交事务时,根据设定的刷盘策略来进行刷盘,将内存中的脏页刷到磁盘当中。如果未提交或者事务崩溃,那么则根据undo日志进行一个数据回滚,恢复至原数据,保证数据的可靠性。

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

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

相关文章

JavaScript 中 throw error 与 throw new Error(error) 的用法及区别,分别适合什么场景使用?

JavaScript 中 throw error 与 throw new Error(error) 的用法及区别 在 JavaScript 中,throw 关键字用于抛出异常。当代码遇到某些错误或异常情况时,可以通过抛出错误来通知程序,方便后续的错误处理。尽管 throw 的使用看似简单&#xff0c…

鸿蒙自带组件效果大全

图形变换-视效与模糊-通用属性-ArkTS组件-ArkUI(方舟UI框架)-应用框架 - 华为HarmonyOS开发者 注意:找到需求效果之后先对一下版本 视距 图像效果 图片裁剪 颜色渐变 前景属性设置 外描边设置: 视效设置: 组件内容模糊 运动模糊 点击回弹效果…

ISP算法如何优化提升成像质量

ISP算法通过多维度技术协同优化成像质量,核心优化路径如下:一、降噪与细节增强‌AI驱动降噪‌深度学习模型实时识别噪点模式,暗光场景信噪比提升5倍以上,同时保留纹理细节。时空域联合降噪技术抑制运动模糊,鬼影消除率…

单例模式及优化

单例模式是一种创建型设计模式,其核心是确保一个类在程序中只能存在唯一实例,并提供一个全局访问点。这种模式适用于需要集中管理资源(如日志、配置、连接池)的场景,避免资源冲突和重复创建的开销。 一、介绍 类型 单例…

Dockerfile优化指南:利用多阶段构建将Docker镜像体积减小90%

更多如果你已经跟随我们之前的教程,亲手将自己的应用装进了Docker这个“魔法盒子”,那你可能很快就会遇到一个幸福但又尴尬的烦恼:你亲手构建的Docker镜像,竟然像一个塞满了石头和棉被的行李箱,臃肿不堪,笨…

英文PDF翻译成中文怎么做?试试PDF翻译工具

在全球化快速发展的时代,跨语言交流变得愈发频繁,无论是学术研究、商务合作还是日常学习,都离不开一个高效、准确的翻译工具。尤其是对于PDF文件的翻译需求,更是日益增长。今天,就让我们一起深入了解几款在PDF翻译领域…

macOS使用brew切换Python版本【超详细图解】

目录 一、更新Homebrew仓库 二、安装pyenv 三、将pyenv添加到bash_profile文件中 四、使.bash_profile文件的更改生效 五、安装需要的Python版本 六、设置全局使用的Python版本 七、检查Python版本是否切换成功 pyenv常用命令 一、更新Homebrew仓库 brew update 这个…

[矩阵置零]

初始思路分析 这段代码实现了将矩阵中元素为0的行和列全部置零的功能。主要思路是使用标记数组记录需要置零的行和列。以下是详细分析&#xff1a; 1. 初始化阶段 int m matrix.size(); int n matrix[0].size(); vector<bool> row(m), col(n);获取矩阵的行数m和列数n创…

redis-集成prometheus监控(k8s)

一. 简介&#xff1a; 关于redis的简介和部署&#xff0c;可以参考单独的文章redis-sentinel基础概念及部署-CSDN博客&#xff0c;这里就不细说了。这里只讲讲如何在k8s中部署export并基于prometheus做redis的指标采集。 二. 实现方式&#xff1a; 首先我们需要先部署exporter…

OVS:ovn为什么默认选择Geneve作为二层隧道网络协议?

首先确认 Geneve 是一种封装协议,可能提供比 VLAN 或 VXLAN 更灵活的扩展能力,这对 OVN 的多租户场景很重要。可能需要支持更多元数据字段,比如携带网络策略信息,这符合 SDN 集中控制的需求。 性能方面需要考虑封装效率和硬件支持情况,虽然 Geneve 头部稍大,但现代网卡的…

grep命令要点、详解和示例

grep技术要点 1) 工作模型&#xff08;3 件事&#xff09; 输入&#xff1a;从文件或标准输入&#xff08;-&#xff09;读入&#xff0c;一次按“行”处理&#xff08;除非用 -z 改成以 NUL 作为“行”分隔&#xff09;。匹配&#xff1a;把每一行拿去和模式&#xff08;patte…

nVidia Tesla P40使用anaconda本地重编译pytorch3d成功加载ComfyUI-3D-Pack

背景 自己用的是nVidia Tesla P40&#xff0c;垃圾佬专属卡 使用下面的由YanWenKun提供的ComfyUI-3D-Pack预安装环境&#xff0c;但在本地编译pytorch3d这一步出错&#xff0c;后面有出错信息&#xff0c;如果有和我一样的卡一样的问题&#xff0c;参看此文的解决方法 老版本…

网络基础——协议认识

文章目录网络基础网络的发展——引出一些概念协议认识初识协议协议分层协议分层的模型再谈协议为什么要有TCP/IP协议TCP/IP协议的宏观认识宏观理解TCP/IP协议和操作系统的关系协议的真正本质网络基础 本篇文章&#xff0c;我们将正式进入网络部分的学习。这是网络部分的第一篇…

云原生俱乐部-RH134知识点总结(2)

这一章的内容也会比较多&#xff0c;因为预期三篇文章更完RH134系列&#xff0c;所以每章安排的内容都比较多&#xff0c;并且RH134上面的都是重点&#xff0c;一点也不好写。昨天一天将RH124系列写完了&#xff0c;今天争取将RH134系列写完。至于我为什么要着急将这些写完&…

深度学习-计算机视觉-微调 Fine-tune

1. 迁移学习迁移学习&#xff08;transfer learning&#xff09;是一种机器学习方法&#xff0c;通过将源数据集&#xff08;如ImageNet&#xff09;上训练得到的模型知识迁移到目标数据集&#xff08;如特定场景的椅子识别任务&#xff09;。这种方法的核心在于利用预训练模型…

STL库——string(类函数学习)

ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 个人主页&#xff1a;励志不掉头发的内向程序员&#xff1b; 专栏主页&#xff1a;C语言&#xff1b; 文章目录 前言 一、STL简介 二、string类的优点 三、标准库中的string类 四、string的成员函数 4.1、构造…

登上Nature!清华大学光学神经网络研究突破

2025深度学习发论文&模型涨点之——光学神经网络光学神经网络的基本原理是利用光的传播、干涉、衍射等特性来实现神经网络中的信息处理和计算。在传统神经网络中&#xff0c;信息以电信号的形式在电子元件之间传输和处理&#xff0c;而在光学神经网络中&#xff0c;信息则以…

【java】对word文件设置只读权限

文件流输出时 template.getXWPFDocument().enforceCommentsProtection(); 文件输出时 //打开己创建的word文档 XWPFDocument document new XWPFDocument(new FileInputStream("output.docx")); //设置文档为只读 document.enforceReadonlyProtection(); //保存文…

Zookeeper 在 Kafka 中扮演了什么角色?

在 Apache Kafka 的早期架构中&#xff0c;ZooKeeper 扮演了分布式协调服务角色&#xff0c;负责管理和协调整个 Kafka 集群。 尽管新版本的 Kafka 正在逐步移除对 ZooKeeper 的依赖&#xff0c;但在许多现有和较早的系统中&#xff0c;了解 ZooKeeper 的作用仍然非常重要。 Zo…

什么叫做 “可迭代的产品矩阵”?如何落地?​

“可迭代的产品矩阵” 不是静态的产品组合&#xff0c;而是围绕用户需求与商业目标构建的动态生态。它以核心产品为根基&#xff0c;通过多维度延伸形成产品网络&#xff0c;同时具备根据市场反馈持续优化的弹性&#xff0c;让产品体系既能覆盖用户全生命周期需求&#xff0c;又…