当前位置: 首页 > news >正文

InnoDB之Undo log格式

1. 前言

InnoDB有两大日志模块,分别是redo log和undo log。为了避免磁盘随机写,InnoDB设计了redo log,数据写入时只写缓冲页和redo log,脏页由后台线程异步刷盘,哪怕系统崩溃也能根据redo log恢复数据。但是我们漏了一种情况没有考虑,如果事务执行到一半系统崩溃了,redo log没刷盘还好,相当于本次事务的修改全部停留在内存里,重启后相当于什么也没做。但是,如果redo log已经刷盘了,MySQL重启后依然会根据redo log恢复页面,相当于本次事务执行到一半的状态,不符合原子性。为了保证原子性,MySQL必须撤销本次事务的所有修改,让本次事务「看起来什么都没做」,这就是undo log要负责的事情。

2. 事务回滚

事务回滚的需求是存在的,除了上述情况系统崩溃时的执行了一半的事务需要回滚,很多时候,开发者也经常需要通过命令ROLLBACK手动回滚事务。事务回滚后,该事务看起来什么都没做一样,它是符合原子性的。

如何实现事务回滚呢?想当然,肯定要把事务中修改的数据先记下来,比如:

  • insert一条记录,就把主键记下来,回滚时删除该记录即可。
  • delete一条记录时,把整条记录记下来,回滚时重新插入即可。
  • update一条记录时,把对应列修改前的值全部记下来,回滚时修改回来即可。
  • select不会修改记录,无需处理。

InnoDB其实也就是按照这个思路去设计的,每次对记录的修改,都会记一条日志,把回滚该条记录的必要数据给记录下来,这个日志就是undo log。

3. undo log格式

undo log是针对记录的,一般每对一条记录进行一次改动,都会生成1到2条undo log。一个事务在执行过程中,可能会修改很多记录,也就会生成若干条undo log,每个事务生成的undo log都会有一个唯一编号undo no,从0开始依次递增,undo no越小代表日志越早生成。

另外,undo log只针对聚簇索引,只有聚簇索引记录才有trx_idroll_pointer隐藏列,二级索引是不会生成undo log的,MySQL在事务回滚时,会自动撤销对二级索引的变更。

roll_pointer隐藏列占用7个字节,组成如下:

属性长度说明
is_insert1比特是否是TRX_UNDO_INSERT大类
rseg id7比特回滚段id,最多128个回滚段
Page Number4字节undo log所在页号
Offset2字节undo log所在页号的偏移量

和redo log一样,InnoDB也设计了很多不同类型的undo log,增删改操作对应的undo log类型都不一样。

3.1 insert undo log

插入一条记录,对应的回滚操作就是删除该条记录,对应的undo log最需要记录的就是tableId和主键信息。InnoDB设计了TRX_UNDO_INSERT_REC类型的undo log来回滚insert操作。

属性说明
end of record本条undo log结束,下一条开始的位置
undo typeundo log类型
undo noundo log序号
table id表对应的id
主键信息
<len,value>列表主键各列的长度以及对应的值
start of record上一条undo log结束,本条开始的位置

重点关注主键信息,假设表的主键是BIGINT类型的id,我们插入了一条id=10000的记录,那么主键信息存储的内容就是<8,10000>,如果主键包含多列,需要把每个列的长度和值都记录下来。

3.2 delete undo log

删除一条记录,对应的回滚操作就是把这条记录再重新插入回去,难道undo log要把一条用户记录完整的给记录下来吗?这未免也太浪费空间了,其实完全不需要这么做,这还得说回InnoDB删除记录的流程。

记录头信息里会有next_record属性,把记录按照主键串联成一条单向链表。页内被删除的记录也会根据该属性串联成一条单向链表,只不过这条链表的空间是可以被重用的,也称作「垃圾链表」。索引页Page Header里有PAGE_FREE属性,指向这条垃圾链表的头节点。记录头信息里还有delete_mark属性,用来标记记录是否被删除。
image.png
当我们要删除一条记录时,实际上会有两个阶段:

  • 阶段1

将记录的delete_mark标记为1,记录undo log,写入trx_idroll_pointer。事务提交前,记录一直处于这种中间状态,既不是正常记录,也不是已删除记录。只有将记录从正常链表中移除,加入到垃圾链表里,记录才算真正删除,其它事务也访问不到了。
image.png
为啥不直接删除记录,而是停留在中间状态?

这条记录还需要为MVCC服务,其它事务可能还需要访问。

  • 阶段2

事务提交后,会有专门的线程来将记录真正的删除掉,这个过程称作「purge」。将记录从正常链表中移除,加入到垃圾链表,InnoDB采用头插法,PAGE_FREE会指向该记录,记录占用的空间也可以被重用了。与此同时,InnoDB还会修改Page Header里的PAGE_N_RECSPAGE_GARBAGE、Page Directory等信息。
image.png
综上所述,事务提交前,只会经历阶段1,事务提交后也就不存在回滚了。所以针对delete操作,只需要把阶段1回滚即可,又因为阶段1记录其实并没有真正删除,所以undo log其实没必要保存完整记录。InnoDB设计了TRX_UNDO_DEL_MARK_REC类型的undo log。

属性说明
end of record本条undo log结束,下一条开始的位置
undo typeundo log类型
undo noundo log序号
table id表对应的id
info bits记录头信息的前4个比特位和record_type值
old trx_id旧的事务id
old roll_pointer旧的回滚指针
主键信息
<len,value>列表主键各列长度和值
index_col_info len索引列信息总长度
索引各列信息
<pos,len,value>索引各列的位置、长度和值
start of record上一条undo log结束,本条开始的位置
  • 与insert不同的是,delete和update操作对应的undo log会记录下旧的trx_idroll_pointer,这样就可以找到上一次对记录修改时的undo log,这些undo log串联起来就是传说中的「版本链」,服务于MVCC。
  • 根据主键信息定位到具体的记录,用户回滚时恢复。
  • 索引各列信息主要用于purge阶段。

3.3 update undo log

update操作就比较复杂了,根据是否更新主键,InnoDB的处理方式也是不同的。
一、不更新主键
在不更新主键的前提下,如果更新后记录各列的长度与更新前相同,那么就可以「就地更新」,也就是直接在原有记录上进行更新,同时记录下undo log。

注意:是每个列的长度都和更新前相同,而非记录总长度和更新前相同。

就地更新的条件还是比较苛刻的,如果更新后列的长度发生变化,那么InnoDB会采用「先删除旧记录,再插入新记录」的方式来做更新,这里的“删除”是真的将记录删除并移入垃圾链表,而非仅仅打删除标记。
为什么会这么做呢?

在索引页里记录与记录之间是紧密无间的存储在一起的,中间没有空间,如果更新后记录占用的空间变大压根就没法存储,只能删掉重新申请空间插入一条。

总之,针对这种不更新主键的情况,InnoDB设计了TRX_UNDO_UPD_EXIST_REC类型的undo log。

属性说明
end of record本条undo log结束,下一条开始的位置
undo typeundo log类型
undo noundo log序号
table id表对应的id
info bits记录头信息的前4个比特位和record_type值
old trx_id旧的事务id
old roll_pointer旧的回滚指针
主键信息
<len,value>列表主键各列长度和值
n_updated更新的列的数量
<pod,ole_len,old_val>列表更新列的旧值
index_col_info len索引列信息总长度
索引各列信息
<pos,len,value>索引各列的位置、长度和值
start of record上一条undo log结束,本条开始的位置

二、更新主键
针对update操作更新了主键的情况,InnoDB分为两个阶段来处理:

  • 将旧记录进行delete mark操作,服务于MVCC。
  • 根据更新后各列的值构建一条新记录并插入。

这两个阶段,对应两条undo log,也就是上面说的TRX_UNDO_DEL_MARK_RECTRX_UNDO_INSERT_REC

4. 对覆盖索引查询的影响

聚簇索引记录会有trx_idroll_pointer隐藏列,通过undo log里的roll_pointer串联形成版本链,即一条记录存在多个版本,在select时会判断哪些版本对当前事务可见。
但是undo log只针对聚簇索引,二级索引没有roll_pointer,也不会生成undo log。我们又知道,InnoDB有个查询优化叫「覆盖索引查询」,即直接扫描二级索引返回结果,不再根据主键回表查询,可以大大提高数据查询的效率。

这时就存在一个问题,覆盖索引查询时,无法判断二级索引记录是否对当前事务可见!
InnoDB的解决方案是,在Page Header里有一个属性叫PAGE_MAX_TRX_ID,它代表修改当前页的最大事务id,如果PAGE_MAX_TRX_ID小于当前活跃的最小事务id,代表修改当前页的事务都提交了,可以直接使用覆盖索引查询,无需回表。反之,就需要回表根据聚簇索引的trx_idroll_pointer以及对应的undo log来判断哪些二级索引记录是对当前事务可见的。

相关文章:

InnoDB之Undo log格式

1. 前言 InnoDB有两大日志模块&#xff0c;分别是redo log和undo log。为了避免磁盘随机写&#xff0c;InnoDB设计了redo log&#xff0c;数据写入时只写缓冲页和redo log&#xff0c;脏页由后台线程异步刷盘&#xff0c;哪怕系统崩溃也能根据redo log恢复数据。但是我们漏了一…...

一问学习StreamAPI终端操作

Java Stream管道流是用于简化集合类元素处理的java API。 在使用的过程中分为三个阶段&#xff1a; 将集合、数组、或行文本文件转换为java Stream管道流管道流式数据处理操作&#xff0c;处理管道中的每一个元素。上一个管道中的输出元素作为下一个管道的输入元素。管道流结果…...

在屎山代码中快速找到想要的代码法-锁表法(C#)

由于本人水平有限&#xff0c;文中有写得不对的地方请指正&#xff0c;本文的方法有些投机取巧&#xff0c;实在是没招的情况下可以酌情使用&#xff0c;如有侵权&#xff0c;请联系删除。 前几天接到一个需求&#xff0c;要在医嘱签署时对检验项目进行分方操作&#xff0c;分…...

网页设计html期末大作业

网页设计html期末大作业网页设计期末大作业-自制网站大一期末作业&#xff0c;外卖网站设计网页设计期末大作业-精美商城-首页框架网页设计期末大作业-自制网站 有导航栏&#xff0c;轮播图&#xff0c;按钮均可点进去&#xff0c;如下图所示 点我下载资源》》》》 大一期末…...

实战打靶集锦-006-Stapler

**写在前面&#xff1a;**记录博主的一次打靶经历。 目录1. 主机发现2. 端口发现3. 服务枚举4. 服务探查4.1 FTP探查4.1.1 匿名登录4.1.2 Elly用户4.1.3 John用户4.1.4 EXP搜索4.2 dnsmasq探查4.2.1 基础信息获取4.2.2 EXP搜索4.3 WEB应用探查4.3.1 浏览器访问4.3.2 目录扫描4.…...

致远OAA6版安装

准备工作&#xff0c;操作系统winserver2019&#xff0c;sqlserver2019。致远OA安装包0.SeeyonInstall.zip相关下载&#xff1a;winserver2019下载地址&#xff1a;cn_windows_server_2019_updated_july_2020_x64_dvd_2c9b67da.iso magnet:?xturn:btih:22A410DEA1B0886354A34D…...

python实用脚本(六)—— pandas库的使用(生成、读取表格)

本期主题&#xff1a; python的pandas使用 往期链接&#xff1a; python实用脚本&#xff08;一&#xff09;—— 批量修改目标文件夹下的文件名python实用脚本&#xff08;二&#xff09;—— 使用xlrd读取excelpython实用脚本&#xff08;三&#xff09;—— 通过有道智云AP…...

字符集、ASCII、GBK、UTF-8、Unicode、乱码、字符编码、解码问题等

编码解码一、背景二、字符的相关概念三、字符集3.1 ASCII[ˈski]3.1.1 ASCII的编码方式3.1.2 EASCII3.2 GBK3.2.1 GB 2312-803.2.2 GBK的制订3.2.3 GBK的实现方式3.3 Unicode&#xff08;统一码、万国码&#xff09;3.3.1 Unicode的出现背景3.3.2 Unicode的编写方式3.3.3 Unico…...

Java 布隆过滤器

你在么&#xff1f;在&#xff01;一定在么&#xff1f;不在&#xff01;一定不在么&#xff1f; 你想要100%的准去性&#xff0c;还是99%的准确性附带较高的速度和较小的资源消耗。 任何算法&#xff0c;任何经营收到的背后&#xff0c;都是时间效益 资源消耗 准确性的平衡&am…...

vscode连接服务器(腾讯云)

文章目录1. vscode远程总是报错2. vscode能连上腾讯云但密码不对或者登录后不能打开文件或文件夹1. vscode远程总是报错 报错如图所示 Could not establish connection to *** 过程试图写入的管道不存在。 在百度、csdn找了好久都是说删掉.ssh文件下的某个文件但我压根没有&a…...

IOS崩溃文件符号化实践

1.背景与项目难点 1.1 背景 由于公司之前使用的友盟要收费&#xff0c;filebase服务由谷歌提供&#xff0c;存在数据合规风险。需要实现稳定性分析功能&#xff0c;通过支持app崩溃信息实时采集、实时上报、实时自动解析并定位出代码问题&#xff0c;帮助研发同学及时定位崩溃…...

设计模式之适配器模式与桥接模式详解和应用

目录1 适配器模式1.1 定义1.2 应用场景1.3 适配器角色1.4 类适配器1.5 对象适配器1.5 接口适配器1.6 实战1.7 源码1.8 适配器与装饰器的对比1.9 适配器模式的优缺点1.10 总结2 桥接模式2.1 原理解析2.2 角色2.3 通用写法2.4 应用场景2.5 业务场景中的运用2.6 源码2.7 桥接模式优…...

Winform控件开发(14)——NotifyIcon(史上最全)

前言: 先看个气泡提示框的效果: 代码如下: 在一个button中注册click事件,当我们点击button1时,就能显示气泡 private void button1_Click(object sender, EventArgs e){notifyIcon1.Visible = true;notifyIcon1...

Verilog 学习第四节(从计数器到可控制线性序列机——LED实验进化六部曲)

从计数器到可控制线性序列机——LED实验进化六部曲一&#xff1a;让LED灯按照亮0.25s&#xff0c;灭0.75s的状态循环亮灭二&#xff1a;让LED灯按照亮0.25s&#xff0c;灭0.5s&#xff0c;亮0.75s&#xff0c;灭1s的状态循环亮灭三&#xff1a;让LED灯按照指定的亮灭模式亮灭&a…...

操作SSH无密登录配置

例如小编有三台服务器需要相互访问&#xff0c;就需要配置三台&#xff0c;这三台分别是hadoop102,hadoop103 , hadoop1041.打开三个服务器&#xff0c;分别生成hadoop102&#xff0c;hadoop103 , hadoop104的公钥和私钥输入命令&#xff0c;然后一直回车&#xff0c;这时候什么…...

Websocket详细介绍

需求背景 在某个资产平台&#xff0c;在不了解需求的情况下&#xff0c;我突然接到了一个任务&#xff0c;让我做某个页面窗口的即时通讯&#xff0c;想到了用websocket技术&#xff0c;我从来没用过&#xff0c;被迫接受了这个任务&#xff0c;我带着浓烈的兴趣&#xff0c;就…...

大数据书单(100本)

大数据书单&#xff08;100本&#xff09; 序号 书名 作者 出版社 1 Hadoop权威指南:大数据的存储与分析(第4版)(修订版)(升级版) Tom White 清华大学出版社 2 Hive编程指南 卡普廖洛 (Edward Capriolo) / 万普勒 (Dean Wampler) / 卢森格林 (Jason Rutherglen) / 曹坤 人民邮…...

python实战应用讲解-【语法基础篇】初识Python(附示例代码)

目录 前言 Python基础 基本概念: 为什么使用Python? Python2.x与3.x版本区别...

【2023保研夏令营】网安、CS(西交、华师、科、南等)

文章目录一、基本情况二、投递和入营情况三、考核情况1. 西交软院&#xff08;面试&#xff09;2. 川大网安&#xff08;笔试面试&#xff09;3. 华东师范数据学院&#xff08;机试面试&#xff09;4. 人大信息学院专硕&#xff08;机试面试&#xff0c;保密&#xff09;5. 南大…...

Qt COM组件导出源文件

文章目录摘要dumpcpp.exe注册COM组件COM 组件转CPP参考关键字&#xff1a; Qt、 COM、 组件、 源文件、 dumpcpp摘要 由于厂家提供的库不是纯净C库&#xff0c;是基于COM组件开的库&#xff0c;在和厂家友好交流无果下&#xff0c;只能研究下Qt 如何调用&#xff0c;好在Qt 的…...

各数据库数据类型的介绍和匹配

各数据库数据类型的介绍和匹配1. Oracle的数据类型2. Mysql的数据类型3. Sql server的数据类型4. 类型匹配5. Awakening1. Oracle的数据类型 数据类型介绍 VARCHAR2 :可变长度的字符串 最大长度4000 bytes 可做索引的最大长度749&#xff1b; NCHAR :根据字符集而定的固定长度字…...

Rancher 部署 MySQL

文章目录创建 pvc部署 MySQL前置条件&#xff1a;安装 rancher&#xff0c;可参考文章 docker 部署 rancher 创建 pvc MySQL 数据库是需要存储的&#xff0c;所以必须先准备 pvc 创建 pvc 自定义 pvc 名称选择已经新建好的 storageclass&#xff0c;storageclass 的创建可参考…...

Python语言零基础入门教程(二十五)

Python OS 文件/目录方法 Python语言零基础入门教程&#xff08;二十四&#xff09; 39、Python os.openpty() 方法 概述 os.openpty() 方法用于打开一个新的伪终端对。返回 pty 和 tty的文件描述符。 语法 openpty()方法语法格式如下&#xff1a; os.openpty()参数 无 返…...

蓝桥杯算法训练合集十五 1.打翻的闹钟2.智斗锅鸡3.文件列表

目录 1.打翻的闹钟 2.智斗锅鸡 3.文件列表 1.打翻的闹钟 问题描述 冯迭伊曼晚上刷吉米多维奇刷的太勤奋了&#xff0c;几乎天天迟到。崔神为了让VonDieEman改掉迟到的坏毛病&#xff0c;给他买了个闹钟。 一天早上&#xff0c;老冯被闹钟吵醒&#xff0c;他随手将闹钟按掉丢…...

CPU扫盲-CPU与指令集

指令集架构就像是特定的CPU的设计图纸&#xff0c;它规定了这个CPU需要支持那些指令、寄存器有那些状态以及输入输出模型。根据指令集结构的设计&#xff0c;在CPU上通过硬件电路进行实现&#xff0c;就得到了支持该指令集的CPU。指令集就像是我们编程语言中的接口&#xff0c;…...

VINS-Mono/Fusion与OpenCV去畸变对比

VINS中没有直接使用opencv的去畸变函数&#xff0c;而是自己编写了迭代函数完成去畸变操作&#xff0c;主要是为了加快去畸变计算速度 本文对二者的结果精度和耗时进行了对比 VINS-Mono/Fusion与OpenCV去畸变对比1 去畸变原理2 代码实现2.1 OpenCV去畸变2.2 VINS去畸变3 二者对…...

jmx prometheus引起的一次cpu飙高

用户接入了jmx agent进行prometheus监控后&#xff0c;在某个时间点出现cpu飙高 排查思路&#xff1a; 1、top&#xff0c;找到java进程ID 2、top -Hp 进程ID&#xff0c;找到java进程下占用高CPU的线程ID 3、jstack 进程ID&#xff0c;找到那个高CPU的线程ID的堆栈。 4、分析堆…...

Android 虚拟 A/B 详解(六) SnapshotManager 之状态数据

本文为洛奇看世界(guyongqiangx)原创,转载请注明出处。 原文链接:https://blog.csdn.net/guyongqiangx/article/details/129094203 Android 虚拟 A/B 分区《AAndroid 虚拟 A/B 分区》系列,更新中,文章列表: Android 虚拟分区详解(一) 参考资料推荐Android 虚拟分区详解(二…...

Python快速入门系列之一:Python对象

Python对象1. 列表&#xff08;list&#xff09;2. 元组&#xff08;tuple&#xff09;3. 字典&#xff08;dict&#xff09;4. 集合&#xff08;set&#xff09;5. 字符串&#xff08;string&#xff09;6. BIF &#xff08;Built-in Function&#xff09;7. 列表、集合以及字…...

【博客626】不同类型的ARP报文作用以及ARP老化机制

不同类型的ARP报文作用以及ARP老化机制 1、ARP协议及报文 2、不同类型的ARP报文作用 3、ARP工作原理 4、ARP老化机制 5、Linux ARP老化机制 ARP状态机&#xff1a; 在上图中&#xff0c;我们看到只有arp缓存项的reachable状态对于外发包是可用的&#xff0c;对于stale状态的…...

现在做网站用什么工具/app代理推广合作50元

一.前期基础知识储备 traces.txt系统自动生成的记录anr等异常的文件&#xff0c;只记录java代码产生的异常。 如果是旧版本&#xff08;Android Studio3以下的版本&#xff09;的AS&#xff0c;可以直接通过DDMS的File Explorer直接导出来&#xff1a; 之上的AS由于移除了DD…...

网站app 开发/google官网注册

获取股票数据的渠道有很多&#xff0c;而且基本上是免费的。目前股票端用的比较多的有通达信&#xff0c;tushare, Quantaxis等&#xff0c;期货端有CTP&#xff0c;CTPBEE&#xff0c;VNPY&#xff0c;TQSDK等&#xff0c;今天我们先来个开胃小菜&#xff0c;教你如何用tushar…...

拉萨营销型网站建设/怎么用手机创建网站

本文章给大家介绍在php中类和对象的protected与const属性用法&#xff0c;有需要了解的朋友可参考参考。const属性用const属性定义的字段是一个常量&#xff0c;类中的常量和静态变量类似&#xff0c;不同之处就是常量的值一旦赋值不能被改变。const定义常量不需要加$符号&…...

网站开发公司属于什么行业/在线资源搜索引擎

版权声明&#xff1a;欢迎转载&#xff0c;请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/43447681 init 6 重启Linux。free -m查看内存大小&#xff0c;已M为单位。df -h查看硬盘情况&#xff0c;包括大小和分区。cat /proc/cpuinfo查看CPU信息。file…...

关于动物自己做的网站/seo优化方案模板

1、字符型输入框&#xff1a; &#xff08;1&#xff09;字符型输入框&#xff1a;英文全角、英文半角、数字、空或者空格、特殊字符&#xff0c;特别要注意单引号和&符号。不要直接输入特殊字符时&#xff0c;使用“粘贴、拷贝”功能尝试输入。 &#xff08;2&#xff0…...

电子商务网站开发流程图/怎么网站推广

jq清除select框的数据最近在接触 jq 的项目&#xff0c;之前都没有写过&#xff0c;最近遇到一个不知道怎么写的东西&#xff0c;记录一下 $(#id).val().trigger(change)...