Innodb数据页简介(2)
01
概念介绍
3月17号的文章里面,我们提到了innodb的数据页结构,我们知道,页是内存和磁盘交互的基本单位,它的大小一般是16KB,可以被分为如下几个部分:
上次的文章里面,我们对这几个部分大概做了介绍,今天我们说说上面数据页的蓝色部分。
该部分保存的是数据页中真正的数据记录,也就是用户存储的记录。当我们一开始生成页的时候,其实并没有蓝色的Record部分,而是随着我们不断给数据库中插入记录,才逐渐从Free Space中划分出来的空间。用示意图来描述就是:
如果Free Space中的数据页被分配完了,则去申请新的数据页。
为了方便理解,我们现在创建一个表进行演示:
CREATE TABLE test(
-> c1 INT,
-> c2 INT,
-> c3 VARCHAR(1000),
-> PRIMARY KEY (c1)
-> ) engine=innodb charset=utf8;
Query OK, 0 rows affected (0.03 sec)
现在我们给这个表里面插入几条数据:
insert into test values
(1,2,'a'),
(2,3,'bb'),
(3,4,'ccc'),
(4,5,'dddd');
我们可以把上面的数据页结构简单表示如下:
我们可以看到,每条记录由三个部分构成,分别是记录头、记录数据以及其他信息,其中记录头里面包含很多字段来表示该条记录的信息,这些字段我们会逐渐进行讲解。目前4条记录都已经插入到record部分了,在实际过程中这四条记录是通过链表的方式进行连接的,如下:
在第一张图的数据页中,蓝色部分还有一部分是infimum和supermun,它们是两条伪记录,它们分别是这个数据页中"指定的"最大的记录和最小的记录。它们的作用是作为当前数据页内数据链表的首末两端。这样,数据页中的数据就可以被我们排列成下面的样子:
我们已经可以看到,我们的主键按照从大到小的顺序形成了一个链表,链表的首末位置分别是两条伪记录。
当我们对数据记录中id=2的一条记录进行删除时,实际上,在数据记录链表里面发生的变化如下:
可以看出,实际上并没有删除那条记录,而是通过将头信息中的delete标识位改为1、偏移量改为0来实现的,也就是说,这条记录所占用的空间并没有还给Free Space,当下一次插入id=2的记录的时候,这块空间还可以接着使用。
在这个过程中,我们加入了record_type字段,这两条伪记录和正常记录的区别之处在于数据记录的头信息里面的record_type字段,最小记录的record_type为2,最大记录的record为3,正常记录的record_type为0,record_type为1的记录,稍后我们会进行解释。
到现在为止,我们已经知道了头信息中的3个字段,分别是next_record和record_type以及delete字段,next_record保存的是下一条数据记录的真是数据的偏移量,record_type代表的是数据记录的类型,delete标示的是该字段是否被删除。除此之外,我们还需要知道记录头信息里面的另外一个字段n_owned,这个字段保存的是改组内一共有多少个数据记录,在上述删除的操作中,最大记录中该字段的变化过程如下:
关于这个初始值为何是5,后续的文章中我们会说明。至此,我们已经了解到,一个数据页,大概可以描述成如下形式: