第23章 后悔了怎么办-undo日志(下)
上一章我们主要介绍了为什么需要undo日志,以及INSERT、DELETE、UPDATE这些会对数据做改动的语句都会产生什么类型的undo日志,还有不同类型的undo日志的具体格式是什么。本章会继续介绍这些undo日志会被具体写到什么地方,以及在写入过程中需要注意的一些问题。
通用链表结构#
在写入undo日志的过程中会使用到多个链表,很多链表都有同样的节点结构,如图所示:

在某个表空间内,我们可以通过一个页的页号和在页内的偏移量来唯一定位一个节点的位置,这两个信息也就相当于指向这个节点的一个指针。所以: - Pre Node Page Number和Pre Node Offset的组合就是指向前一个节点的指针 - Next Node Page Number和Next Node Offset的组合就是指向后一个节点的指针。
整个List Node占用12个字节的存储空间。
为了更好的管理链表,设计InnoDB的大佬还提出了一个基节点的结构,里边存储了这个链表的头节点、尾节点以及链表长度信息,基节点的结构示意图如下:

其中: - List Length表明该链表一共有多少节点。 - First Node Page Number和First Node Offset的组合就是指向链表头节点的指针。 - Last Node Page Number和Last Node Offset的组合就是指向链表尾节点的指针。
整个List Base Node占用16个字节的存储空间。
所以使用List Base Node和List Node这两个结构组成的链表的示意图就是这样:

小贴士:上述链表结构我们在前面的文章中频频提到,尤其是在表空间那一章重点描述过,不过我不敢奢求大家都记住了,所以在这里又强调一遍,希望大家不要嫌我烦,我只是怕大家忘了学习后续内容吃力而已~
FIL_PAGE_UNDO_LOG页面#
我们前面介绍表空间的时候说过,表空间其实是由许许多多的页面构成的,页面默认大小为16KB。这些页面有不同的类型,比如类型为FIL_PAGE_INDEX的页面用于存储聚簇索引以及二级索引,类型为FIL_PAGE_TYPE_FSP_HDR的页面用于存储表空间头部信息的,还有其他各种类型的页面,其中有一种称之为FIL_PAGE_UNDO_LOG类型的页面是专门用来存储undo日志的,这种类型的页面的通用结构如下图所示(以默认的16KB大小为例):

“类型为FIL_PAGE_UNDO_LOG的页”这种说法太绕口,以后我们就简称为Undo页面了。上图中的File Header和File Trailer是各种页面都有的通用结构,我们前面介绍过很多遍了,这里就不赘述了(忘记了的可以到讲述数据页结构或者表空间的章节中查看)。Undo Page Header是Undo页面所特有的,我们来看一下它的结构:

其中各个属性的意思如下:
TRX_UNDO_PAGE_TYPE:本页面准备存储什么种类的undo日志。
我们前面介绍了好几种类型的undo日志,它们可以被分为两个大类:






