MySQL-事务日志
事务的隔离性由 锁机制
实现
事务的原子性、一致性、隔离性 由事务的 redo日志 和 undo 日志来保证
- redo log 称为
重做日志
,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。 - undo log 称为
回滚日志
,回滚行记录到某个特定的版本,用来保证事务的原子性、一致性。
1、redo日志
- InnoDB存储引擎是
以页为单位
来管理存储空间的。在正真访问页之前,需要把磁盘上
的页缓存到内存中的buffer pool
后才能访问。所有的变更都必须先更新缓冲池
中的数据,然后缓冲池中的脏页
会以一定频率被刷新到磁盘(checkpoint机制
)。
1.1、redo日志的好处
- 降低了刷新磁盘的频率
- 占用的空间非常小
存储表空间ID、页号、偏移量以及需要更新的值,所需的存储空间是很小的,刷新磁盘块
1.2、redo日志的特点
- 是顺序写入磁盘的
在事务执行过程中,每执行一条语句就可能产生若干条redo日志,这些日志是按照 产生的顺序写入磁盘的,使用顺序IO效率比随机IO快
- 事务执行过程中,redo log 不断记录
redo log 和 bin log 的区别在于 redo log 是存储引擎产生的,而bin log 是数据库层产生的。
比如一个事务对表做大量行的记录插入操作,在这个过程中,一致不断往redo log 顺序记录,而bin log 不会记录,直到事务提交,才会写入到bin log文件中
1.3、redo的组成
重做日志的缓冲
(redo log buffer),保存在内存中,是易丢失的。 参数设置 :innodb_log_buffer_size
默认16M
,最大值是4096M 最小值为1M
mysql> show variables like 'innodb_log_buffer_size';
+------------------------+----------+
| Variable_name | Value |
+------------------------+----------+
| innodb_log_buffer_size | 16777216 |
+------------------------+----------+
1 row in set (3.29 sec)
在服务器启动时就向操作系统申请一大片 redo log buffer 的连续内存空间,即redo日志缓冲区。这片内存空间被划分为若干个连续的 redo log block。一个 redo log block 占用 512字节大小。
重做日志文件
(redo log file),保存在硬盘中,是持久的
1.4、redo的执行整体流程
- 以更新事务举例,如下所示
①:先将原始数据从磁盘读入内存,修改数据的内存拷贝
②:生成一条重做日志并写入redo log buffer,记录数据被修改后的值
③:当事务commit时,将redo log buffer 中的内容刷新到 redo log file,对redo log file 采用追加写的方式
④:定期将内存中修改的数据刷新到磁盘中
write-ahead log(预先日志持久化):在持久化一个数据页之前先将内存中相应的日志页持久化
1.5、redo log 刷盘策略
- 参数设置:
innodb_flush_log_at_trx_commit
,支持以下三种策略:- 设置为0:表示每次事务提交时不进行刷盘操作。(系统默认master thread 每隔1s进行一次重做日志的同步)
- 设置为1:表示每次事务提交时都将进行同步,刷盘操作(默认值)
- 设置为2:表示每次事务提交时都只把redo log buffer 内容写入page cache,不进行同步。
mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
1 row in set (1.64 sec)
1.6、写入 redo log buffer 过程
1.6.1、Mini-Transaction
MySQL对底层页面一次原子性访问的过程称为一个 Mini-Transaction,简称 mtr。
例如:向某个索引对应的B+树中插入一条记录的过程就是一个Mini-Transaction。一个所谓的mtr 可以包含一组redo日志,在进行崩溃恢复时这一组redo日志作为一个不可分割的整体。
- 一个事务可以包含若干条语句,每一条语句其实由若干个mtr组成,每个mtr又可以包含若干条redo日志。如下图所示
1.6.2、日志写入log buffer
向log buffer 中写入redo日志的过程是顺序的,也就是先往前边的block中写,当该block的空闲空间用完之后再往下一个block中写。当往log buffer中写入redo 日志时,设计者提供一了一个 buf_free的全局变量,该变量指明后续写入的redo日志应该写入到log_buffer中的哪个位置。如下图所示
- 一个mtr执行过程中可能产生若干条redo日志,这些redo日志是一个不可分割的组。并不是没生成一条redo日志就将其插入到log buffer 中,而是每个mtr运行过程中产生的日志先暂时存放到一个位置,当该mtr结束的时候将过程中产生的一组redo日志全部复制到 log buffer中。
1.6.3、redo log block的结构图
- 一个redo log block是由 日志头(12字节)、日志体(492字节)、日志尾(8字节)组成。
1.7、redo log file
1.7.1、相关参数设置
innodb_log_group_home_dir
:指定redo log 文件组所在的路径,默认值为./
,表示再数据库的数据目录下。MySQL的默认数据目录(var/lib/mysql)下默认有两个名为ib_logfile0 和 ib_logfile1的文件,log buffer 中的日志默认情况下就是刷新到这两个磁盘文件中。此redo日志文件位置还可以修改。
mysql> show variables like 'innodb_log_group_home_dir';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_group_home_dir | ./ |
+---------------------------+-------+
1 row in set (3.70 sec)
innodb_log_files_in_group
:指明redo log file 的个数,默认 2个,最大100个。
mysql> show variables like 'innodb_log_files_in_group';
+---------------------------+-------+
| Variable_name | Value |
+---------------------------+-------+
| innodb_log_files_in_group | 2 |
+---------------------------+-------+
1 row in set (0.00 sec)
- innodb_flush_log_at_tx_commit : 控制redo log 刷新到磁盘的策略,默认为 1
mysql> show variables like 'innodb_flush_log_at_trx_commit';
+--------------------------------+-------+
| Variable_name | Value |
+--------------------------------+-------+
| innodb_flush_log_at_trx_commit | 1 |
+--------------------------------+-------+
1 row in set (1.64 sec)
- innodb_log_file_size:单个redo log 文件设置大小,默认值为48M。最大值为512G(指整个redo log 系列文件之和)。
mysql> show variables like 'innodb_log_file_size';
+----------------------+----------+
| Variable_name | Value |
+----------------------+----------+
| innodb_log_file_size | 50331648 |
+----------------------+----------+
1 row in set (0.00 sec)
1.7.2、日志文件组
- redo日志文件以日志文件组的形式出现。文件以ib_logfile[正整数]的形式命名,每个redo日志文件都是一样大小。
- redo日志写入顺序依次执行,当最后一个文件写满后会从第一个接续写。
1.7.3、checkpoint
在整个日志文件组中还有两个重要的属性,分别时 write pos 、checkpoint
- write pos 是记录当前位置,一边写一边后移
- checkpoint 是当前要擦除的位置,也是往后推移
- 每次刷盘 redo log 记录到日志文件组中,write pos 位置就会后移更新。每次MySQL加载日志文件组恢复数据时,会清空加载过的 redo log 记录,并把checkpoint后移更新。write pos 和checkpoint 之间还空闲的部分可以写入新的redo log 记录。
2、undo日志
- undo log是事务的原子性保证。在事务中更新数据 的前置操作其实就是要先写入一个 undo log
2.1、undo log 的理解
- 事务需要保证原子性,也就是事务的操作要么全部完成,要么都不做,但有时候事务执行到一半会出现以下情况:
- 事务执行过程中会遇到各种错误,如:服务器本身错误,操作系统错误等
- 在事务执行过程中手动rollback操作结束当前事务的执行
2.2、undo log 的作用
- 回滚数据
- 并发版本控制(MVCC)
2.3、undo 的存储结构
2.3.1、回滚段与undo页
-
innodb对undo log管理采用段的方式 即回滚段(rollback segment)。每个回滚段记录了 1024个undo log segment,而每个undo log segment段中进行undo页的申请。
- 在innodb1.1版本之前,只有一个rollback segment,因此支持同时在线的事务限制为1024.
- innodb1.1开始支持最大128个 rollback segment,故其支持同时在线的事务限制提高到了 128*1024。
-
通过查询参数 innodb_rollback_segments
mysql> show variables like 'innodb_rollback_segments';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| innodb_rollback_segments | 128 |
+--------------------------+-------+
1 row in set (0.01 sec)
- innodb_undo_directory:设置rollback segment 文件所在路径。
mysql> show variables like 'innodb_undo_directory';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_undo_directory | ./ |
+-----------------------+-------+
1 row in set (0.13 sec)
- innodb_undo_tablespaces: 设置构成rollback segment文件的数量,这样rollback segment 可以较为平均的分布在多个文件中。设置该参数后会在路径innodb_undo_directory看到undo为前缀的文件,该文件就表示rollback segment文件。
mysql> show variables like 'innodb_undo_tablespaces';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| innodb_undo_tablespaces | 2 |
+-------------------------+-------+
1 row in set (0.12 sec)
undo页的重用
- 当我们开启一个事务需要写入undo log的时候,就得先去undo log segment中找到一个空闲的空间,当有空位的时候就去申请undo页,在这个申请到的undo页中进行undo log 的写入。
- undo log 在commit后会被放到一个链表中,然后判断undo页的使用空间是否小于3/4。如果小于则表示当前的undo页可以被重用,不会被回收掉,其他事务的undo log 可以记录在当前undo页的后面。
- 由于undo log 是 离散的 ,在清理对应磁盘空间时,效率不高。
2.3.2、回滚段与事务
- 每个事务只会使用一个回滚段,一个回滚段在同一时刻可能会服务于多个事务
- 当一个事务开始的时候,会制定一个回滚段,在事务进行过程中,当数据被修改时,原始的数据会被复制到回滚段。
- 在回滚段中,事务会不断填充盘区,直到事务结束或所有的空间被用完。如果当前的盘区不够用,事务会在段中请求下一个盘区,如果占用盘区被用完,事务会覆盖最初盘区或者在回滚段允许的情况下拓展新的盘区来使用。
- 回滚段存在于 undo表空间中,在数据库中可以存在多个表空间,但同一时刻只能使用一个undo表空间。
- 当事务提交时,innodb存储引擎会做以下两件事情:
- 将undo log 放入列表中以供之后的purge操作
- 判断undo log 所在的页是否可以重用,若可以分配给下一个事务使用
2.3.3、回滚段中数据分类
- 未提交的回滚数据:该数据所关联的事务并未提交,用于实现读一致性,所以数据不能被其他事务覆盖
- 已经提交但未过期的回滚数据:该数据关联的事务已经提交,但是仍收到 undo retention参数的保持时间的影响。
- 已经提交并过期的回滚:事务已经提交,而且数据保存时间已经超过 undo retention参数指定的时间,属于已经过期的数据。当回滚段满后,会优先覆盖事务已经提交并过期的数据。
2.4、undo的类型
- insert undo log:指在inset操作中产生的undo log。因为insert操作的记录,只对事务本省可见,对其他事务不可见,故该 undo log 可以在事务提交后直接删除,不需要进行purge操作。
- update undo log:指对delete和update操作产生发的undo log。该undo log 可能需要提供MVCC机制,因此不能在事务提交时就进行删除。提交时放入undo log 链表,等待purge线程进行最后的删除。
purge线程:
主要作用就是清理undo页和清除page里面带有delete_bit标识的数据行。在innodb中,事务中的delete操作实际上并不是真正的删除掉数据行,而是一种delete mark操作,在记录上标识delete_bit,而不删除记录,是一种“假删除”,知识做了相关标记,真正的删除工作需要后台的purge线程去完成。
相关文章:

MySQL-事务日志
事务的隔离性由 锁机制 实现 事务的原子性、一致性、隔离性 由事务的 redo日志 和 undo 日志来保证 redo log 称为 重做日志,提供再写入操作,恢复提交事务修改的页操作,用来保证事务的持久性。undo log 称为 回滚日志,回滚行记录…...
PySide6 GUI 学习笔记——常用类及控件使用方法(常用类坐标点QPoint)
控件是PySide设计好的能承载用户输入、输出的小窗体,将多个控件有机整合,能形成用户所需要的界面。而每一个控件,都有属于自己的属性、方法、信号、槽函数和事件(event),且控件与控件之间又有继承关系。 G…...

算法练习——字符串
一确定字符串是否包含唯一字符 1.1涉及知识点 c的输入输出语法 cin>>s; cout<<"NO"; 如何定义字符串 切记:在[]中必须加数字——字符串最大长度,不然编译不通过 char s[101]; 如何获取字符串长度 char s[101];cin>>s;i…...
Flutter 中的 SliverOverlapInjector 小部件:全面指南
Flutter 中的 SliverOverlapInjector 小部件:全面指南 Flutter 是一个功能丰富的 UI 框架,由 Google 开发,允许开发者使用 Dart 语言构建跨平台的移动、Web 和桌面应用。在 Flutter 的滚动视图系统中,SliverOverlapInjector 是一…...
7个Python爬虫入门小案例
大家好,随着互联网的快速发展,数据成为了新时代的石油。Python作为一种高效、易学的编程语言,在数据采集领域有着广泛的应用。本文将详细讲解Python爬虫的原理、常用库以及实战案例,帮助读者掌握爬虫技能。 一、爬虫原理 爬虫&a…...
linux 利用 ~$() 构造数字
2024.6.1 题目 <?php //flag in 12.php error_reporting(0); if(isset($_GET[x])){$x $_GET[x];if(!preg_match("/[a-z0-9;|#\"%&\x09\x0a><.,?*\-\\[\]]/i", $x)){system("cat ".$x.".php");} }else{highlight_file(__F…...

七大获取免费https的方式
想要实现https访问最简单有效的的方法就是安装SSL证书。只要证书正常安装上以后,浏览器就不会出现网站不安全提示或者访问被拦截的情况。下面我来教大家怎么去获取免费的SSL证书,又如何安装证书实现https访问。 一、选择免费SSL证书提供商 有多家机构提…...

JVM(Java虚拟机)笔记
面试常见: 请你谈谈你对JVM的理解?java8虚拟机和之前的变化更新?什么是OOM,什么是栈溢出StackOverFlowError? 怎么分析?JVM的常用调优参数有哪些?内存快照如何抓取?怎么分析Dump文件?谈谈JVM中,类加载器你的认识…...

秒杀基本功能开发(显示商品列表和商品详情)
文章目录 1.数据库表设计1.商品表2.秒杀商品表3.修改一下秒杀时间为今天到明天 2.pojo和vo编写1.com/sxs/seckill/pojo/Goods.java2.com/sxs/seckill/pojo/SeckillGoods.java3.com/sxs/seckill/vo/GoodsVo.java 3.Mapper编写1.GoodsMapper.java2.GoodsMapper.xml3.分别编写Seck…...
centos 记录用户登陆ip和执行命令
centos 记录用户登陆ip和执行命令 在/etc/profile 文件末尾添加如下代码: #!/bin/bash USER_IPwho -u am i 2>/dev/null | awk {print $NF} | sed -e s/[()]//g HISTDIR/usr/share/.history if [ -z "$USER_IP" ]; then USER_IPhostname fi…...
JZ2440笔记:DM9000C网卡驱动
在厂家提供的dm9dev9000c.c上修改, 1、注释掉#ifdef MODULE #endif 2、用模块化函数修饰入口出口函数 3、在dm9000c_init入口函数,增加iobase (int)ioremap(0x20000000,1024);irq IRQ_EINT7; 4、一路进入,在dmfe_probe1中注释掉if((db…...
【数据结构】二叉树:简约和复杂的交织之美
专栏引入: 哈喽大家好,我是野生的编程萌新,首先感谢大家的观看。数据结构的学习者大多有这样的想法:数据结构很重要,一定要学好,但数据结构比较抽象,有些算法理解起来很困难,学的很累…...

信号稳定,性能卓越!德思特礁鲨系列MiMo天线正式发布!
作者介绍 礁鲨系列天线,以其独特的外观设计和强大的性能,成为德思特Panorama智能天线家族的最新成员。这款天线不仅稳定提供5G、WIFI和GNSS信号,更能在各类复杂环境中展现出卓越的性能。它的设计灵感来源于海洋中的礁鲨,象征着力量…...
编程学习技巧——实战
目录 学习思路待续、更新中 学习思路 实战大小项目 翻阅官网手册——学习技术,调试问题 待续、更新中 1 顿号、: 先使用ctrl. ,再使用一遍切回 2 下标: 21 2~1~ 3 上标: 2 0 2^{0} 20 $2^{0}$ 4 竖线 | : | ; | 5 空格: &emsp ; 6 换行: &nbs…...

GPU学习(1)
一、为什么要GPU 我们先看一个基本的神经网络计算 YF(x)AxB 这就是一次乘法一次加法 ,也叫FMA,(fused multiply-add) 如果矩阵乘,就是上面的那个式子扩展一下,所以又用了这张老图 比如你要多执行好几个yAxB,可能比较简…...

TQSDRPI开发板教程:UDP收发测试
项目资源分享 链接:https://pan.baidu.com/s/1gWNSA9czrGwUYJXdeuOwgQ 提取码:tfo0 LWIP自环教程:https://blog.csdn.net/mcupro/article/details/139350727?spm1001.2014.3001.5501 在lwip自环的基础上修改代码实现UDP的收发测试。新建一…...

opencv进阶 ——(九)图像处理之人脸修复祛马赛克算法CodeFormer
算法简介 CodeFormer是一种基于AI技术深度学习的人脸复原模型,由南洋理工大学和商汤科技联合研究中心联合开发,它能够接收模糊或马赛克图像作为输入,并生成更清晰的原始图像。算法源码地址:https://github.com/sczhou/CodeFormer…...

虚拟机改IP地址
使用场景:当你从另一台电脑复制一个VMware虚拟机过来,就是遇到一个问题,虚拟的IP地址不一样(比如,一个是192.168.1.3,另一个是192.168.2.4,由于‘1’和‘2’不同,不是同一网段&#…...

MySQL(二)-基础操作
一、约束 有时候,数据库中数据是有约束的,比如 性别列,你不能填一些奇奇怪怪的数据~ 如果靠人为的来对数据进行检索约束的话,肯定是不行的,人肯定会犯错~因此就需要让计算机对插入的数据进行约束要求! 约…...

vue3学习使用笔记
1.学习参考资料 vue3菜鸟教程:https://www.runoob.com/vue3/vue3-tutorial.html 官方网站:https://cn.vuejs.org/ 中文文档: https://cn.vuejs.org/guide/introduction.html Webpack 入门教程:https://www.runoob.com/w3cnote/webpack-tutor…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...