第7章InnoDB数据存储结构
1.数据库的存储结构:页
索引结构给我们提供了高效的索引方式,不过索引信息以及数据记录都是保存在文件上的,确切说是存储在页结构中。另一方面,索引是在存储引擎中实现的,MySQL服务器上的存储引擎
负责对表中数据的读取和写入工作。不同存储引擎中存放的格式
一般是不同的,甚至有的存储引擎比如Memory都不用磁盘来存储数据。
由于InnoDB
是MySQL的默认存储引擎
,所以本章剖析InnoDB存储引擎的数据存储结构。
1.1 磁盘与内存交互基本单位:页
InnoDB将数据划分为若干个页,InnoDB中页的大小默认为16KB
。
以页
作为磁盘和内存之间交互的基本单位
,也就是一次最少从磁盘中读取16KB的内容到内存中,一次最少把内存中的16KB内容刷新到磁盘中。也就是说,**在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说,数据库管理存储空间的基本单位是页(Page),数据库I/O操作的最小单位是页。**一个页中可以存储多个行记录。
记录是按照行来存储的,但是数据库的读取并不以行为单位,否则一次读取(也就是一次I/O操作)只能处理一行数据,效率会非常低。
1.2 页结构概述
页a、页b、页c…页n这些页可以不在物理结构上相连
,只要通过双向链表
相关联即可。每个数据页中的记录会按照主键值从小到大的顺序组成一个单向链表
,每个数据页都会为存储在它里边的记录生成一个页目录
,在通过主键查找某条记录的时候可以在页目录中使用二分法
快速定位到对应的槽,然后再遍历该槽对应的分组中的记录即可快速找到指定的记录。
1.3页的大小![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/05a8e1d49c172d8e96d7776856c782a7.png)
1.4页的上层结构
区(Extent)是比页大一级的存储结构,在InnoDB存储引擎中,一个区会分配64个连续的页
。因为InnoDB中的页大小默认是16KB,所以一个区的大小是64*16KB=1MB
。
段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在InnoDB中是连续的64个页),不过在段中不要求区与区之间是相邻的。段是数据库中的分配单位,不同类型的数据库对象以不同的段形式存在。
当我们创建数据表、索引的时候,就会相应创建对应的段,比如创建一张表时会创建一个表段,创建一个索引时会创建一个索引段。
表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间
、用户表空间
、撤销表空间
、临时表空间
等。
2. 页的内部结构
页如果按类型划分的话,常见的有数据页(保存B+树节点)、系统页、Undo页
和事务数据页
等。数据页是我们最常使用的页。
数据页的16KB
大小的存储空间被划分为七个部分,分别是文件头(File Header)、页头(Page Header)、最大最小记录(Inflmum+supremum)、用户记录(User Records)、空闲空间(Free Space)、页目录(Page Directory)和文件尾(File Tailer)。
页结构的示意图如下所示:
2.1 第1部分:文件头部和文件尾部
2.1.1 File Header(文件头部)(38字节)
作用: 描述各种页的通用信息。(比如页的编号、其上一页、下一页是谁等)
大小:38字节
名称 | 占用空间大小 | 描述 |
---|---|---|
FIL_PAGE_SPACE_OR_CHKSUM |
4 字节 |
页的校验和(checksum值) |
FIL_PAGE_OFFSET |
4 字节 |
页号 |
FIL_PAGE_PREV |
4 字节 |
上一个页的页号 |
FIL_PAGE_NEXT |
4 字节 |
下一个页的页号 |
FIL_PAGE_LSN | 8 字节 |
页面被最后修改时对应的日志序列位置 |
FIL_PAGE_TYPE |
2 字节 |
该页的类型 |
FIL_PAGE_FILE_FLUSH_LSN | 8 字节 |
仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值 |
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID |
4 字节 |
页属于哪个表空间 |
FIL_PAGE_OFFSET(4字节)
:每一个页都有一个单独的页号,就跟你的身份证号码一样,InnoDB通过页号可以唯一定位
一个页。FIL_PAGE_TYPE(2字节)
:这个代表当前页的类型。
类型名称 | 十六进制 | 描述 |
---|---|---|
FIL_PAGE_TYPE_ALLOCATED | 0x0000 | 最新分配,还没有使用 |
FIL_PAGE_UNDO_LOG |
0x0002 | Undo日志页 |
FIL_PAGE_INODE | 0x0003 | 段信息节点 |
FIL_PAGE_IBUF_FREE_LIST | 0x0004 | Insert Buffer空闲列表 |
FIL_PAGE_IBUF_BITMAP | 0x0005 | Insert Buffer位图 |
FIL_PAGE_TYPE_SYS |
0x0006 | 系统页 |
FIL_PAGE_TYPE_TRX_SYS | 0x0007 | 事务系统数据 |
FIL_PAGE_TYPE_FSP_HDR | 0x0008 | 表空间头部信息 |
FIL_PAGE_TYPE_XDES | 0x0009 | 扩展描述页 |
FIL_PAGE_TYPE_BLOB | 0x000A | 溢出页 |
FIL_PAGE_INDEX |
0x45BF | 索引页,也就是我们所说的数据页 |
-
FIL_PAGE_PREV(4字节&#x