MySQL InnoDB undo log数据结构分析

devtools/2024/9/29 13:08:41/

一、概念解析

1、undo log基本

undo log是InnoDB事务中特有的结构,它的作用有两个:一是进行事务回滚(原子性),旧数据先放到undo log中,等rollback时再将旧数据里的数据回滚回来;二是MVCC(隔离性),非阻塞读。

undo能够避免脏读:在操作数据之前,将数据备份到undo页中,然后在进行数据的修改,不能看到其他回话未提交的数据,当要读取被修改页数据行时,会指向备份在undo页中的数据,避免脏读。

undo回滚段头物理存储在ibdata1文件中第6个页位置。

undo log存放在数据库内部的一个特殊段中,这个段称为undo段。undo段位于共享表空间中。回滚段实际上是一种 undo 文件组织方式

在InnoDB存储引擎中有rollback segment,每个回滚段记录了1024个undo log segment(slot),每个undo log segment段中进行undo页的申请。

从1.1版本开始InnoDB支持最大128个rollback segment,所以理论上可以支持的最大的事务上限为128*1024。

在1.2版本开始,可以通过参数对rollback segment进行设置,参数有:

参数名称

含义

innodb_undo_directory

设置回滚段文件所在的路径

innodb_undo_logs

设置回滚段的个数

innodb_undo_tablespaces

设置构成回滚段文件的数量

也就是说:

回滚段可以存放在共享表空间以外的地方,即可以设置独立表空间,innodb_undo_directory的默认值为“.”,表示当前InnoDB存储引擎的目录。

回滚段的个数默认值为128。

设置回滚段文件的数量后,回滚段可以较为平均地分布在多个文件中,在路径下可以看到undo为前缀的文件,该文件代表回滚段文件。

可用show variables like “innodb_undo%”;查询:

重新初始化时指定innodb_undo_tablespaces=N来设置,设置好后会在data目录下生成undo独立表空间(大小10M):

2、事务系统头transaction system header

回滚段的管理,在InnoDB共享表空间中,用第6个页面(5号)来管理的,这个页面专门用来存储事务系统相关信息的,源代码位于trx0sys.h,它的格式如下:

这三个参数的含义分别为:

参数名称

含义

TRX_SYS_TRX_ID_STORE

存储事务号

TRX_SYS_FSEG_HEADER

存储事务段信息

TRX_SYS_RSEGS

数组,InnoDB有128个rollback segment

3、回滚段头rollback segment header

对于每一个回滚段,即上面TRX_SYS_RSEGS数组中的一个元素,也有其自己的存储格式,代码中的宏定义位于trx0rseg.h,格式如下:

这五个信息的含义如下:

参数名称

含义

TRX_RSEG_MAX_SIZE

所有undo段页面之和

TRX_RSEG_HISTORY_SIZE

需要purge的回滚段页面数

TRX_RSEG_HISTORY

存储history list的链表首地址

TRX_RSEG_FSEG_HEADER

存储回滚段的inode位置信息

TEX_RSEG_UNDO_SLOTS

数组,1024,每个元素是一个页面号

这五个信息存储了一个回滚段的信息,最后一个位置的数组,用来真正存储回滚段的位置。这五个信息是从页面偏移38的位置开始存储,在TRX_SYS宏定义中可以查看:

4、回滚页头undo log page header

定义在trx0undo.h,事务undo日志页面头偏移量:

其中各个参数的含义为:

参数名称

含义

TRX_UNDO_PAGE_TYPE

类型,TRX_UNDO_INSERT\UPDATE

TRX_UNDO_PAGE_START

开始存储undo日志的位置

TRX_UNDO_PAGE_FREE

结束标志

TRX_UNDO_PAGE_NODE

双向链表的指针

第一个页在undo log段的回滚日志段头:

其中各个参数的含义为:

参数名称

含义

TRX_UNDO_STATE

undo段五种状态,包括TRX_UNDO_ACTIVE\CACHED\TO_FREE\TO_PURGE\PREPARED

TRX_UNDO_LAST_LOG

最后一个undo日志的偏移位置

TRX_UNDO_FSEG_HEADER

undo段inode信息

TRX_UNDO_PAGE_LIST

段链表的首地址

其中undo log段的状态有五种:

5、回滚日志头undo log header

这是回滚日志的头,在第一页的update undo log中有几个undo log headers。同样定义在trx0undo.h中,它的宏定义如下:

整理并解释其中的含义:

参数名称

含义

TRX_UNDO_TRX_ID

存储当前undo日志对应事务的事务id

TRX_UNDO_TRX_NO

事务序列号

TRX_UNDO_DEL_MARKS

删除记录标记

TRX_UNDO_LOG_START

存储当前页面中第一个undo日志的开始位置

TRX_UNDO_XID_EXISTS

标记的当前日 志中有没有包含xid事务

TRX_UNDO_DICT_TRANS

标记当前事务是不是DDL,在回滚时判断如何操作

TRX_UNDO_TABLE_ID

表id

TRX_UNDO_NEXT_LOG

链接指向下一个undo日志

TRX_UNDO_PREV_LOG

指向上一个undo日志,构成双向链表

TRX_UNDO_HISTORY_NODE

存储history list中的双向链表,链表首地址

6、两种undo log格式

undo log格式有两种:

  • insert undo log
  • update undo log

其中,insert操作会产生insert undo log。因为隔离性的要求,insert操作只对事务本身可见,对其他事务不可见。并且undo log可以在事务提交后直接删除,不需要进行purge操作。

update和delete操作都会产生update undo log。对于update操作很简单,就是将旧版本的值修改为新版本的值,并且将旧版本的记录保存到undo log中;对于delete操作完后并不是真正的删除该行数据,而是将该行的数据存在undo log中,并且将标记位delete置为true,以备回滚时可以根据标记位进行逆操作,这样就能够找回之前的旧数据,起到回滚的作用。

在delete中又分为三种情况:

purge线程两个主要作用是:清理undo页和清除page里面带有delete_bit标识的数据行。在InnoDB中,事务中的delete操作实际上并不是真正的删除掉数据行,而是在记录上标识delete_bit,而不是真正删除记录,真正的删除工作需要后台purge线程去完成。

下面是两种undo log记录的具体的结构:

二、数据结构

与undo log相关的数据结构有trx_sys_t、trx_rsegs_t 、trx_t、trx_rseg_t、trx_undo_t、trx_undo_ptr_t等结构,其中比较重要的结构有两个:trx_rseg_t和trx_undo_t。trx_rseg_t保存回滚段的信息,trx_undo_t保存关于回滚日志的信息。

通过两种方式找到回滚日志:

结论:

1、从全局变量trx_sys中的回滚段数组rseg_array中的回滚链表update-undo_list中指针(trx_sys->rseg_array[N]->update_undo_list->start)以及当前事务trx中的回滚段指针rsegs中的slot槽区m_redo中的undo log(trx->rsegs->m_redo->update_undo)都可以找到相应的回滚段中的回滚日志

2、事务id、回滚段id、page_no递增。

1、trx_rseg_t

回滚段的内存对象的类型是一个叫trx_rseg_t的结构,它定义在trx0rseg.h文件中,它的各成员有:

成员变量

解释

ulint id;

回滚段id

RsegMutex mutex;

回滚段mutex,保护

ulint space;

回滚段头空间

ulint page_no;

回滚段页码

page_size_t page_size;

页面大小

ulint max_size;

允许的最大页大小

ulint curr_size;

当前页的大小

UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_list;

update回滚日志链表

UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_cached;

为快速重用而缓存的update回滚日志链表

UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_list;

insert回滚日志的字段

UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_cached;

为快速重用而缓存的insert undo log链表

ulint last_page_no;

最后一个尚未清除的日志页码

ulint last_offset;

最后一个尚未清除的日志头的字节偏移量

trx_id_t last_trx_no;

最后一个尚未清除的日志的事务号

ibool last_del_marks;

判断最后一个尚未清除的日志是否要清除

ulint trx_ref_count;

跟踪rseg分配事务的参考计数器

bool skip_allocation;

如果为真,则跳过分配此rseg

update\insert_undo_list 用于保存产生的回滚日志,update\insert_undo_cached用于快速重用而缓存的回滚日志链表。当确定回滚日志无用时,会将回滚日志从update\insert_undo_list中摘除,放到相应的cached链表中。

2、trx_undo_t

回滚日志的内存对象的类型是一个叫trx_undo_t的结构,它定义在trx0undo.h文件中,它的各成员有:

成员变量

解释

ulint     id;

回滚段内的回滚日志槽号(slot)

ulint     type;

类型。TRX_UNDO_INSERT\UPDATE

ulint     state;

相应的回滚日志段的状态

ibool del_marks;

删除标记

trx_id_t     trx_id;

事务id

XID     xid;

open XA事务识别

ibool dict_operation;

是否是dict操作

table_id_t table_id;

设置表ID

trx_rseg_t* rseg;

回滚日志所属的rseg回滚段

ulint     space;

放置回滚日志的空间id

page_size_t page_size;

回滚日志中标题页的大小

ulint     hdr_page_no;

回滚日志中标题页的页码

ulint      hdr_offset;

页面上回滚日志的header偏移量

ulint     last_page_no;

登录日志中最后一页的页码

ulint     size;

当前页的大小

ulint     empty;

回滚日志记录堆栈当前是否为空

ulint     top_page_no;

链接最近撤消日志记录的页码

ulint     top_offset;

最新回滚记录的偏移量

undo_no_t top_undo_no;

最新的回滚记录的编号

buf_block_t* guess_block;

猜测可能位于首页的缓冲区

ulint     withdraw_clock;

存储guess_block时缓冲池的退出时钟值

UT_LIST_NODE_T(trx_undo_t) undo_list;

回滚段中的回滚日志对象链表

回滚段指针包括回滚段的id、日志所在的page no、以及page内偏移量。通过回滚段的指针就能够找到这个回滚段,通过回滚日志的槽号、页码、回滚记录编号和偏移量就能定位到这条回滚日志。undo_list用于将此类型的undo log链接到undo log list中。

UT_LIST_NODE_T(trx_undo_t) undo_list链表中有两个指针,分别为prev和next,用于将此undo log链接到undo log list中。


http://www.ppmy.cn/devtools/118694.html

相关文章

大模型推理任务Nvidia GPU选型指南

大型语言模型 (LLM)(如 GPT-4、BERT 和其他基于 Transformer 的模型)彻底改变了 AI 格局。这些模型需要大量计算资源来进行训练和推理。选择合适的 GPU 进行 LLM 推理可以极大地影响性能、成本效益和可扩展性。 在本文中,我们将探索最适合 L…

8610 顺序查找

### 思路 1. **创建顺序表**:从输入中读取元素个数和元素值,构造顺序表。 2. **顺序查找**:在顺序表中依次查找关键字,找到则返回位置,否则返回0。 ### 伪代码 1. **创建顺序表**: - 动态分配存储空间。…

游戏开发2025年最新版——八股文面试题(unity,虚幻,cocos都适用)

1.静态合批与动态合批的原理是什么?有什么限制条件?为什么?对CPU和GPU产生的影响分别是什么? 原理:Unity运行时可以将一些物体进行合并,从而用一个描绘调用来渲染他们,就是一个drawcall批次。 限…

PyCharm 的安装和配置

环境要求: OS:Windows / macOS / Linux (此处使用 Windows 10 进行演示)Python:包括但不限于 Anaconda,miniconda,Python。在 Windows 下只要能找到 python.exe 即可 Download 进入 PyCharm 官网,选择对…

TypeError: unsupported operand type(s) for +=: ‘Dense‘ and ‘str‘

tensorflow2.0报这个错误 因为你在定义模型的时候 model Sequential(SimpleRNN(3),Dense(5, activationsoftmax) )是不是感觉少了点什么,没加[] model Sequential([SimpleRNN(3),Dense(5, activationsoftmax)] )

C# winforms 使用菜单和右键菜单

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…

从零开始的软件开发详解:数字药店系统源码与医保购药APP

很多小伙伴们疑问,医保购药APP是如何开发的,今天我将从零数字药店系统源码开始为大家提供一条清晰的实现方案。 一、技术架构设计 在开发医保购药APP之前,首先需要明确技术架构。一般来说,APP的技术架构可以分为前端和后端。 1…

HTTP 重定向:301 与 308 的区别

在Web开发中,HTTP 重定向是非常常见的一种操作。当我们需要将用户从一个URL自动引导到另一个URL时,HTTP重定向就起到了关键的作用。最常见的重定向状态码有301 Moved Permanently和308 Permanent Redirect。它们之间的差别不仅仅体现在行为上,也影响了请求方法的处理,进而影…