当前位置: 代码网 > it编程>数据库>Mysql > MySQL之InnoDB存储引擎中的页用法解读

MySQL之InnoDB存储引擎中的页用法解读

2025年06月26日 Mysql 我要评论
1、背景mysql中存储数据是存储引擎干的事,存储引擎存储数据的基本单位是页,我们往数据库插入表中的一条条记录就是存储在页上的,今天我们就来熟悉一下页上面有哪些内容。2、页的组成页由7部分组成,先大概

1、背景

mysql中存储数据是存储引擎干的事,存储引擎存储数据的基本单位是页,我们往数据库插入表中的一条条记录就是存储在页上的,今天我们就来熟悉一下页上面有哪些内容。

2、页的组成

页由7部分组成,先大概字面意思理解一下,后面再各部分详细讲解,组成图如下:

在这里插入图片描述

表格解释如下:

名称字节大小描述
文件头部38页的通用信息
页头部56页的专有信息
最小记录和最大记录262个固定的行记录
行记录不固定存放用户数据
空闲空间不固定未使用存放用户数据的空间
页目录不固定存放槽
文件尾部8校验页面是否完整

3、各部分讲解

【1】文件头部

文件头部38个字节由8个部分组成,看表理解:

名称字节大小描述
fil_page_space_or_chksum4表空间id或校验和
fil_page_offset4页号,当前页的唯一标识
fil_page_prev4上一个页号唯一标识
fil_page_next4下一个页号唯一标识
fil_page_lsn8该页最后一次修改对应的redo日志序号
fil_page_type2页类型
fil_page_file_flush_lsh8该页被刷到磁盘的redo日志序号
fil_page_arch_log_no_or_space_id4归档日志编号或页属于哪个表空间

1、本文是在fil_page_type为数据页的基础上进行讲解

2、fil_page_space_or_chksum对于数据页的类型含义为校验和,用来和文件尾部的校验和进行对比

【2】页头部

页头部的56个字节由14个部分组成,看表理解:

名称字节大小描述
page_n_dir_slots2页目录中存储槽的数量
page_heap_top2页中空闲空间地址
page_n_heap2未标记删除用户记录 + 已标记删除用户记录 + 最小记录 + 最大记录
page_free2第1条标记为已删除的用户记录地址
page_garbage2所有标记为已删除记录占用的字节数
page_last_insert2最后一条用户记录插入位置
page_direction2最后一条用户记录插入方向,主键/unique健/隐藏列唯一键比上一条大就为右,反之为左
page_n_recs2未标记为删除的用户记录数
page_max_trx_id8修改当前页的最新事务id
page_level2当前页在b+树中的层级
page_index_id8当前页属于的索引id
page_btr_seg_leaf10b+树叶子段的头部信息
page_btr_seg_top10b+树非叶子段的头部信息

【3】最小记录和最大记录

最小记录和最大记录2条记录是页中固定就存在的,最小记录和最大记录都是由5字节头部信息+8字节数据组成,所以它们总共占用空间26字节,最小记录数据部分固定为’infimum’,最大记录数据部分固定为’supremum’, 在讲它之前我们先了解一下compact行格式中头部信息用5字节来存储的行记录信息,其组成部分如下:

名称位大小描述
预留位1未使用
预留位1未使用
delete_mask10-记录未删除,1-记录已删除
min_rec_mask1b+树非叶子节点中的最小记录
n_owned4当前记录在记录组里拥有记录数
heap_no13当前记录在记录堆中的位置
record_type3记录类型,0-普通记录,1-b+数非叶子节点记录,2-最小记录,3-最大记录
next_record16指向下一条未被删除的记录

当页中没有任何用户记录时,最小记录和最大记录可以如图表示:

在这里插入图片描述

最小记录中的n_owned为1表示以最小记录结尾的分组记录中只有一条记录,这条记录就是最小记录本身,最小记录的next_record为13代表最小记录数据部分与下一条数据部分的偏移量,所以上图箭头指向最大记录的固定数据部分,13字节大小是这样计算的: 最小记录固定数据部分(8) + 最大记录头部信息(5)

next_record之所以指向下一条记录的数据部分是因为:对于用户记录,指向位置往左的头部信息中还有逆序的长度列表、逆序的是否为null列表,往右就是数据部分。

最大记录中的n_owned为1表示以最大记录结尾的分组记录中只有一条记录,这条记录就是最大记录本身,最大记录的next_record为0代表没有下一条记录,它就是最后一条记录。

n_owned数有这样的定义:

  • 1、最小记录所在分组记录数最多只能有1条。
  • 2、最大记录所在分组记录数范围为1~8条。
  • 3、用户记录所在分组记录数范围为4~8条。

【4】行记录

行记录讲解需要根据数据来进行理解了,我们先创建一张表如下:

create table test
(
    id int auto_increment primary key,
    str varchar(255) not null default ''
) engine = innodb default charset = utf8mb4;

插入3条记录:

insert into test (str)
values ('aaa'),
       ('bbb'),
       ('ccc');

查看记录:

mysql [xxx]> select * from test;
+----+-----+
| id | str |
+----+-----+
|  1 | aaa |
|  2 | bbb |
|  3 | ccc |
+----+-----+
3 rows in set (0.001 sec)

此时插入的3条记录和最小最大记录可以如图表示:

在这里插入图片描述

可以看到所有记录通过nex_record的偏移量组成了一个链表,删除其中某条记录,就会把该条记录的delete_mask设置为1,next_record设置为0,但是记录依然存在,只是标记为了删除,这是为了后面插入新数据时可以对这部分空间进行复用,如图:

在这里插入图片描述

因为是第1条标记删除的记录,也会在页头部记录这条记录的地址,如果有多条删除记录,它们之间也会组成一个链表。

【5】空闲空间

空闲空间就是给行记录使用的,行记录空间增加,空闲空间就减少。

【6】页目录

页目录就是用来存储槽的,槽就是一组用户记录中,相对页起始位置偏移量最大的一条记录, 这条记录数据部分相对页起始位置的偏移量就作为槽,槽对应的记录中的n_owned属性就代表这条记录对应的用户组内有多少条记录,槽与记录关系可以如图表示:

在这里插入图片描述

最大记录看起来虽然是在最后面,起始它是和最小记录挨着的,所以后面记录增加导致分组产生新增槽时相对页起始位置的偏移量要比槽1大。

在讲最小记录和最大记录时讲过分组记录的约束,根据这个约束行记录分组产生规则如下:

1、新增记录放到比插入记录主键值大且主键值相隔最近的行记录对应的槽里,并将当前槽对应行记录的n_owned属性+1,表示该槽对应的记录组的记录多了1个。

2、当记录组的记录数变为9个时,会将这9条记录分为2个组,一组4个一组5个,对于4条记录的分组会将里面相对页起始位置最大的值的行记录的数据部分偏移量(相对页起始位置)设置为新的槽。

查找记录的规则如下:

1、通过二分法找到对应的槽。

2、根据行记录的next_record属性找到对应的行。

【7】文件尾部

文件尾部大小为8个字节,前4个字节代表页的校验和,和文件头部的校验和相等就代表是一个完成的页,后4个字节代表最后一次修改当前页是对应的redo日志序号,这个以后再讲。

4、总结

本篇文章讲解了数据页的组成,页是存储数据的基本单位;每个页的文件头部都会有一个上下页号,组成了一个双向链表;页中每条行记录的next_record组成一个单项链表;innodb会把多条记录分为一个组,组里的最大记录的数据部分相对于页面开头的偏移量就设置为槽,查找记录时通过二分法查找所在的槽,再通过行记录的next_record属性找到对应的记录。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

  • Mysql 多表联合更新的项目实践

    Mysql 多表联合更新的项目实践

    mysql 可以基于多表查询更新数据。对于多表的 update 操作需要慎重,建议在更新前,先使用 select 语句查询验证更新的数据与自己期望的是否一致。下... [阅读全文]
  • mysql中的数据目录用法及说明

    mysql中的数据目录用法及说明

    1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的数据都是存储在这个目录中,可以大概了解一下这个目录下是怎么存储数... [阅读全文]
  • MySQL之InnoDB存储页的独立表空间解读

    1、背景我们往一张表里插入的行数据是存储在页上的,一张页的大小为16kb,数据量大的时候一张页不可能存储完一张表里的所有数据,所以需要多张页来进行存储,这多张页所在的存储空间就叫表…

    2025年06月26日 数据库
  • MySQL中的InnoDB单表访问过程

    MySQL中的InnoDB单表访问过程

    1、背景mysql通过查询条件查询到结果的过程就叫访问方法,一条查询语句的访问方法有很多种,接下来我们就来讲一下各种访问方法。2、环境创建表:mysql>... [阅读全文]
  • MySQL 中 ROW_NUMBER() 函数最佳实践

    MySQL 中 ROW_NUMBER() 函数最佳实践

    mysql 中row_number()函数详解row_number()是 sql 窗口函数中的一种,用于为查询结果集中的每一行分配一个​​唯一的连续序号​​。与... [阅读全文]
  • MySQL中的表连接原理分析

    MySQL中的表连接原理分析

    1、背景在进行sql查询时有时需要多张表的查询结果组成一个共同的结果返回,这时就用到了mysql中连接的用法,接下来就以两张表来讲解表连接的原理。2、环境创建两... [阅读全文]

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com