MySQL undo日志精讲3-从回滚段中申请 Undo 页面链表

回滚段-Rollback Segment Header 页面

回滚段的概念

我们现在知道一个事务在执行过程中最多可以分配4个 Undo 页面链表,在同一时刻不同事务拥有的 Undo 页面链表是不一样的,所以在同一时刻系统里其实可以有许许多多个 Undo 页面链表存在。为了更好的管理这些链表,设计InnoDB的大佬又设计了一个称之为 Rollback Segment Header 的页面,在这个页面中存放了各个 Undo 页面链表的 first undo page 的页号,他们把这些页号称之为 undo slot
在这里插入图片描述
设计InnoDB的大佬规定,每一个 Rollback Segment Header 页面都对应着一个段,这个段就称为Rollback Segment,翻译过来就是回滚段。与我们之前介绍的各种段不同的是,这个Rollback Segment里其实只有一个页面(这可能是设计InnoDB的大佬们的一种洁癖,他们可能觉得为了某个目的去分配页面的话都得先申请一个段,或者他们觉得虽然目前版本的MySQL里Rollback Segment里其实只有一个页面,但可能之后的版本里会增加页面也说不定)。

从回滚段中申请 Undo 页面链表

初始情况下,由于未向任何事务分配任何Undo页面链表,所以对于一个Rollback Segment Header页面来说,它的各个undo slot都被设置成了一个特殊的值:FIL_NULL(对应的十六进制就是0xFFFFFFFF),表示该undo slot不指向任何页面。

随着时间的流逝,开始有事务需要分配Undo页面链表了,就从回滚段的第一个undo slot开始,看看该undo slot的值是不是FIL_NULL:

  • 如果是FIL_NULL,那么在表空间中新创建一个段(也就是Undo Log Segment),然后从段里申请一个页面作为 Undo 页面链表的 first undo page,然后把该 undo slot 的值设置为刚刚申请的这个页面的地址,这样也就意味着这个undo slot被分配给了这个事务。
  • 如果不是 FIL_NULL,说明该 undo slo t已经指向了一个undo链表,也就是说这个 undo slot 已经被别的事务占用了,那就跳到下一个undo slot,判断该undo slot的值是不是FIL_NULL,重复上面的步骤。

一个Rollback Segment Header页面中包含1024个undo slot,如果这1024个undo slot的值都不为FIL_NULL,这就意味着这1024个undo slot都已经名花有主(被分配给了某个事务),此时由于新事务无法再获得新的Undo页面链表,就会回滚这个事务并且给用户报错:

Too many active concurrent transactions

用户看到这个错误,可以选择重新执行这个事务(可能重新执行时有别的事务提交了,该事务就可以被分配Undo页面链表了)。

当一个事务提交时,它所占用的undo slot有两种命运:

如果该undo slot指向的Undo页面链表符合被重用的条件(就是我们上面说的Undo页面链表只占用一个页面并且已使用空间小于整个页面的3/4)。该 undo slot 就处于被缓存的状态,设计InnoDB的大佬规定这时该Undo页面链表的 TRX_UNDO_STATE 属性(该属性在 first undo page的Undo Log Segment Header部分)会被设置为TRX_UNDO_CACHED。

被缓存的undo slot都会被加入到一个链表,根据对应的Undo页面链表的类型不同,也会被加入到不同的链表:
如果对应的Undo页面链表是insert undo链表,则该undo slot会被加入insert undo cached链表。
如果对应的Undo页面链表是update undo链表,则该undo slot会被加入update undo cached链表。一个回滚段就对应着上述两个cached链表,如果有新事务要分配undo slot时,
先从对应的cached链表中找。如果没有被缓存的undo slot,才会到回滚段的 Rollback Segment Header页面中再去找。

如果该undo slot指向的Undo页面链表不符合被重用的条件,那么针对该undo slot对应的Undo页面链表类型不同,也会有不同的处理:

如果对应的Undo页面链表是insert undo链表,则该Undo页面链表的TRX_UNDO_STATE属性会被设置为 TRX_UNDO_TO_FREE,之后该Undo页面链表对应的段会被释放掉(也就意味着段中的页面可以被挪作他用),然后把该undo slot的值设置为FIL_NULL。如果对应的 Undo 页面链表是update undo链表,则该Undo页面链表的 TRX_UNDO_STATE 属性会被设置为 TRX_UNDO_TO_PRUGE,则会将该undo slot的值设置为FIL_NULL,然后将本次事务写入的一组undo日志放到所谓的 History 链表中(需要注意的是,这里并不会将Undo页面链表对应的段给释放掉,因为这些undo日志还有用呢~)。

多个回滚段

我们说一个事务执行过程中最多分配 4 个 Undo 页面链表,而一个回滚段里只有1024个 undo slot,很显然 undo slot的数量有点少啊。我们即使假设一个读写事务执行过程中只分配1个Undo页面链表,那 1024 个 undo slot 也只能支持1024个读写事务同时执行,再多了就崩溃了。这就相当于会议室只能容下1024个班长同时开会,如果有几千人同时到会议室开会的话,那后来的那些班长就没地方坐了,只能等待前面的人开完会自己再进去开。

话说在InnoDB的早期发展阶段的确只有一个回滚段,但是设计InnoDB的大佬后来意识到了这个问题,咋解决这问题呢?会议室不够,多盖几个会议室不就得了。所以设计InnoDB的大佬一口气定义了128个回滚段,也就相当于有了128 × 1024 = 131072 个 undo slot。假设一个读写事务执行过程中只分配1个Undo页面链表,那么就可以同时支持131072个读写事务并发执行(这么多事务在一台机器上并发执行,还真没见过呢~)。
  每个回滚段都对应着一个Rollback Segment Header页面,有128个回滚段,自然就要有128个Rollback Segment Header页面,这些页面的地址总得找个地方存一下吧!于是设计InnoDB的大佬在系统表空间的第5号页面的某个区域包含了128个8字节大小的格子:
  在这里插入图片描述每个8字节的格子的构造就像这样:
  
在这里插入图片描述如果所示,每个8字节的格子其实由两部分组成:

4字节大小的Space ID,代表一个表空间的ID。
4字节大小的Page number,代表一个页号。  
也就是说每个8字节大小的格子相当于一个指针,指向某个表空间中的某个页面,这些页面就是Rollback Segment Header。
这里需要注意的一点事,要定位一个Rollback Segment Header还需要知道对应的表空间ID,这也就意味着不同的回滚段可能分布在不同的表空间中。

所以通过上面的叙述我们可以大致清楚, 在系统表空间的第5号页面中存储了 128 个 Rollback Segment Header 页面地址,每个 Rollback Segment Header 就相当于一个回滚段。在Rollback Segment Header页面中,又包含1024个undo slot,每个undo slot都对应一个Undo页面链表。我们画个示意图:
  在这里插入图片描述

回滚段的分类

我们把这128个回滚段给编一下号,最开始的回滚段称之为第0号回滚段,之后依次递增,最后一个回滚段就称之为第127号回滚段。这128个回滚段可以被分成两大类:

第0号、第33~127号回滚段属于一类。其中第0号回滚段必须在系统表空间中(就是说第0号回滚段对应的Rollback Segment Header页面必须在系统表空间中),第33~127号回滚段既可以在系统表空间中,也可以在自己配置的undo表空间中,关于怎么配置我们稍后再说。如果一个事务在执行过程中由于对普通表的记录做了改动需要分配Undo页面链表时,必须从这一类的段中分配相应的undo slot。

第1~32号回滚段属于一类。这些回滚段必须在临时表空间(对应着数据目录中的ibtmp1文件)中。

如果一个事务在执行过程中由于对临时表的记录做了改动需要分配Undo页面链表时,必须从这一类的段中分配相应的undo slot。也就是说 如果一个事务在执行过程中既对普通表的记录做了改动,又对临时表的记录做了改动,那么需要为这个记录分配2个回滚段,再分别到这两个回滚段中分配对应的undo slot。

undo 日志在崩溃时的作用

在服务器因为崩溃而恢复的过程中, 首先需要按照 redo 日志将各个页面的数据恢复到崩溃之前的状态,这样可以保证已经提交的事务的持久性。但是这里仍然存在一个问题,就是 那些没有提交的事务写的 redo 日志可能也已经刷盘,那么这些未提交的事务修改过的页面在 MySOL 服务器重启时可能也被恢复了。为了保证事务的原子性,有必要在服务器重启时将这些未提交的事务回滚掉。那么,怎么找到这些未提交的事务呢? 这个工作又落到了 undo 日志头上。我们可以通过系统表空间的第5号页面定位到 128 个回滚段的位置,在每一个回滚段的1,024 个 undo slot 中找到那些值不为 FIL NULL 的 undo slot,每一个 undo slot 对应着一个Undo 页面链表。然后从 Undo 页面链表第一个页面的 Undo Log Segment Header 中找到 TRXUNDO STATE 属性,该属性标识当前 Undo 页面链表所处的状态。如果该属性的值为 TRXUNDO ACTIVE,则意味着有一个活跃的事务正在向这个 Undo 页面链表中写入 undo 日志,然后再在 Undo Segment Header 中找到 TRX UNDO LAST LOG 属性,通过该属性可以找到本Undo 页面链表最后一个 Undo Log Header 的位置。从该 Undo Log Header 中可以找到对应事务的事务d 以及一些其他信息,则该事务id 对应的事务就是未提交的事务。通过 undo 日志中记录的信息将该事务对页面所做的更改全部回滚掉,这样就保证了事务的原子性。

redo 日志最终是需要写在磁盘里的,
undo 日志是存在内存里的,但是写 undo 页对应 的 redo 是在磁盘里的

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

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

相关文章

【数据结构之顺序表】

数据结构学习笔记---002 数据结构之顺序表1、介绍线性表1.1、什么是线性表? 2、什么是顺序表?2.1、概念及结构2.2、顺序表的分类 3、顺序表接口的实现3.1、顺序表动态存储结构的Seqlist.h3.1.1、定义顺序表的动态存储结构3.1.2、声明顺序表各个接口的函数 3.2、顺序表动态存储…

Kubectl 部署有状态应用(下)

接上文 《Kubectl 部署有状态应用(上)》创建完StatefulSet后,本文继续介绍StatefulSet 扩展、更新、删除等内容。 StatefulSet 中的 Pod 验证序数索引和稳定的网络身份 StatefulSet 中的 Pod 具有唯一的序数索引和稳定的网络身份。 查看 …

外星人Alienware Area-51 R2原厂Win10预装系统

大三角外星人Area 15 R2原装出厂WINDOWS10系统 链接:https://pan.baidu.com/s/1JwDuHx1j7fRABtIpLmKW_g?pwdq4pd 提取码:q4pd 原厂系统自带所有驱动、外星人出厂主题壁纸、专属LOGO标志、Office办公软件、MyAlienware、外星人控制中心等预装程序 文…

2023最新轻松升级、安装和试用Navicat Premium 16.3.3 教程详解

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文…

Qt designer界面和所有组件功能的详细介绍(全!!!)

PyQt5和Qt designer的详细安装教程:https://blog.csdn.net/qq_43811536/article/details/135185233?spm1001.2014.3001.5501 目录 1. 界面介绍2. Widget Box 常用组件2.1 Layouts(布局)2.2 Spacers(间隔器)2.3 Item V…

python实现bp神经网络对csv文件进行数据预测

参考资源: sklearn库 bp神经网络[从原理到代码一篇搞定](2)_sklearn 神经网络-CSDN博客 十分钟上手sklearn:安装,获取数据,数据预处理 - 知乎 (zhihu.com) 一个实例讲解如何使用BP神经网络(附代码) - 知…

操作系统 内存管理篇

一.程序的装入和链接 装入方式: 链接方式: 二.进程的内存映像 三.内存的分配 1.连续分配 分配方式: 2.不连续分配 分页:页面大小一致 引入快表(和 cache 处理思路一致) 升级到二级页表 分段:…

智能算法(GA、DBO等)求解阻塞流水车间调度问题(BFSP)

先做一个声明:文章是由我的个人公众号中的推送直接复制粘贴而来,因此对智能优化算法感兴趣的朋友,可关注我的个人公众号:启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法,经典的,或者是近几年…

Kali Linux—借助 SET+MSF 进行网络钓鱼、生成木马、获主机shell、权限提升、远程监控、钓鱼邮件等完整渗透测试(二)

远控木马 SET 同时集成了木马生成工具,可以生成木马并调用MSF框架对远程主机进行控制。直接使用MSF生成木马并控制主机的可参考之前另一篇博文:渗透测试-Kali入侵Win7主机。 控制主机 1、运行 SET,选择创建攻击载荷和监听器: 2…

Topaz Video AI 视频修复工具(内附安装压缩包win+Mac)

目录 一、Topaz Video AI 简介 二、Topaz Video AI 安装下载 三、Topaz Video AI 使用 最近玩上了pika1.0和runway的图片转视频,发现生成出来的视频都是有点糊的,然后就找到这款AI修复视频工具 Topaz Video AI。 一、Topaz Video AI 简介 Topaz Video…

【C语言刷题每日一题#牛客网BC68】——X形图案

问题描述 思路分析 首先根据输入的描述&#xff0c;多组输入需要将scanf放在循环中来实现 #include<stdio.h> int main() {int a 0;while (scanf("%d", &a) ! EOF){} } 完成了输入之后&#xff0c;再来分析输出——输出的是一个由“*”组成的对称的X形…

力扣算法-Day10

160. 相交链表 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点&#xff0c;返回 null 。 示例 1&#xff1a; 输入&#xff1a;intersectVal 8, listA [4,1,8,4,5], listB [5,6,1,8,4,5], skipA 2, s…