【MySQL (8) |深入InnoDB空间及索引页文件结构 】
本文来自公众号 阿飞的博客 公号ID : AfeiJavaer
InnoDB数据存储模型用"spaces"表示,也被称为"tablespaces",有时候也被称为"file spaces",一个space可能包含多个操作系统级别的实际文件(例如ibdata1,ibdata2等)。但是只是被当做一个逻辑文件:多个物理文件只是被视为物理连接在一起。
InnoDB中每个space都会被分配一个32位整型的space ID,被许多其他地方用来关联这个space的。InnoDB总是有一个 “system space”,它的space ID总是为0,system space用于InnoDB需要的各种特殊簿记。
每个MySQL表创建一个.idb文件。但是从内部来看,.idb文件是一个可以包含多个表的space,只不过MySQL的实现,每个.ibd文件只包含一个表。
Pages
每个space被分割为多个page,通常每个page是16k(变量innodb_page_size
,编译mysql时可以通过修改UNIV_PAGE_SIZE来改变page的大小)。
space中的每个page被分配了一个32位整型的页号(page number),被称为offset
,这个offset实际上就是page相对space起始位置的偏移量。所以,page 0就是偏移量offset=0的文件,page 1就是偏移量offset=16384的文件,以此类推。
我们都知道InnoDB数据上限是64TB,这个限制实际上是每个space的限制。主要是因为页号是32位整型,并且默认pageSize是16k,所以,数据上限 64TB=2^32 x 16k = 64TB。
64TB限制在MySQL官网也有提到:The minimum tablespace size is slightly larger than 10MB. The maximum tablespace size is four billion pages (64TB). This is also the maximum size for a table. 这段话来自:https://dev.mysql.com/doc/refman/5.5/en/innodb-restrictions.html
一个page示意图如下:
page
如图所示,每个page都有38个字节的FIL header,以及8个字节的FIL trailer(FIL是file的简称)。FIL header包含了一个表示page type的字段,这个字段用来确定这个page数据的结构。
FIL header和trailer示意图如下所示:
FIL header and trailer
FIL Header:
-
checksum:4个字节32位checksum保存在header中。
-
Offset:Page Number,page初始化时就被保存在header中。
-
Previous/Next Page:指向前/后一页的指针,被保存在header中,允许构建成双向链表,从而连接所有相同等级的页。
-
page type:保存在header中,为了解析page数据,这个字段是必须的。
-
space ID:保存在header中,space的32位整型唯一编号。
-
Old-style Checksum:老格式32位checksum被保存在trailer中,不过已经被废弃,这块空间被申明为一些指针。
-
LSN:log sequence number。
Space files
一个space文件就是多个(最多2^32)串联的page。为了更高效的管理,64个连续的page组成一块,这个块的大小刚好1M(64 x 16k = 1024k = 1M),也被称为extent
。InnoDB需要做一些簿记,为了跟踪所有的page,extents以及space本身。space文件示意图如下所示:
space file overview
由图可知:
space中的第一页(page 0)一定是FSP_HDR(file space header),FSP_HDR页包含一个FSP头结构,记录一些东西,如:space的大小,free列表等。
FSP页内部的空间只够保存256个extends的簿记信息(每个extends是64个page,每个extend大小为1M。所以总共可以保存256 x 64 = 16384个page的簿记信息)。因此额外的页,每16,384页必须以XDES页的形式保留簿记信息。 XDES和FSP_HDR页的结构是相同的, 随着space文件的增长,这些额外的页面自动分配。
space中的第三页(page 2)就是INODE页,用于存储有文件段相关的列表。
The system space
即系统空间(page 0),在InnoDB中和一个特别的空间。只包含了很少的固定范围页数,系统空间和其他空间一样,它的前3页也是FSP_HDR,IBUF_BITMAP 和 INODE页。它的示意图如下所示:
ibdatal file overview
Per-table space files
InnoDB提供了一个"file per table"模式(对应变量innodb_file_per_table
),即每个表单独创建一个.ibd文件,实际上就是space文件。每个表创建的.ibd文件有着典型的space文件结构:
IBD File Overview
如图所示,它的前3页也是FSP_HDR,IBUF_BITMAP 和 INODE页。page 3即第4页是主键聚簇的root页。page 4是二级聚簇的root页。
对于每个表空间来说,分配的大多数的页还是索引类型,以及存储表数据的页。
参考英文链接:The basics of InnoDB space file layout:https://blog.jcole.us/2013/01/03/the-basics-of-innodb-space-file-layout/
文章的最后,插播一条消息,为了更方便的交流,建了一个技术交流群,大家有问题可以在群里提,有大佬会帮你回答,平时也可以聊聊天,扯扯蛋,二维码如果过期或者进不去的话可以在公众号对话框找到我的微信,加下好友,我拉你进群。
Github地址:https://github.com/Bylant/LeetCode
CSDN地址:https://blog.csdn.net/ZBylant
微信公众号