1.数据页的基本介绍

数据页的大小是16kb,有很多种数据页。

比如存放表空间头部信息的页,存放Insert Buffer信息的页,存放INODE信息的页,存放undo日志信息的页等。

名称 中文名 占用空间大小 简单描述
File Header 文件头部 38字节 页的一些通用信息
Page Header 页面头部 56字节 数据页专有的一些信息
Infimum + Supremum 最小记录和最大记录 26字节 两个虚拟的行记录
User Records 用户记录 不确定 实际存储的行记录内容
Free Space 空闲空间 不确定 页中尚未使用的空间
Page Directory 页面目录 不确定 页中的某些记录的相对位置
File Trailer 文件尾部 8字节 校验页是否完整

我们自己存储的记录会按照我们指定的行格式存储到User Records部分。

我们插入记录会按照指定的行格式来插入进去。刚开始并没有User Records这部分。

每当我们插入一条记录,都会从Free Space部分,也就是尚未使用的存储空间中申请一个记录大小的空间划分到User Records部分,当Free Space部分的空间全部被User Records部分替代掉之后,也就意味着这个页使用完了,如果还有新的记录插入的话,就需要去申请新的页了。

如果我们将某一个列指定为主键的话,在具体的行格式中InnoDB就没必要为我们去创建那个所谓的 row_id 隐藏列了。

上一篇笔记中,行格式记录,实际上就是每一条记录都有的信息。

其中记录头信息是有这5个字节,40位的信息。

记录头信息中各个属性的大体意思浏览一下(使用Compact行格式):

名称 大小(单位:bit) 描述
预留位1 1 没有使用
预留位2 1 没有使用
delete_mask 1 标记该记录是否被删除
min_rec_mask 1 B+树的每层非叶子节点中的最小记录都会添加该标记
n_owned 4 表示当前记录拥有的记录数
heap_no 13 表示当前记录在记录堆的位置信息
record_type 3 表示当前记录的类型,0表示普通记录,1表示B+树非叶节点记录,2表示最小记录,3表示最大记录
next_record 16 表示下一条记录的相对位置

TIPS:

  • B+树的非叶子节点记录,也是有标识的。
  • 记录中的数据应该是以二进制存在的。
  • 各条记录在User Records中存储的时候并没有空隙。
  • delete_mask 标记着当前记录是否被删除,占用1个二进制位,值为0的时候代表记录并没有被删除,为1的时候代表记录被删除掉了。被删除的记录还在页中!!这些被删除的记录之所以不立即从磁盘上移除,是因为移除它们之后把其他的记录在磁盘上重新排列需要性能消耗,所以只是打一个删除标记而已,所有被删除掉的记录都会组成一个所谓的垃圾链表,在这个链表中的记录占用的空间称之为所谓的可重用空间,之后如果有新记录插入到表中的话,可能把这些被删除的记录占用的存储空间覆盖掉。
  • 这个delete_mask位设置为1和将被删除的记录加入到垃圾链表中其实是两个阶段
  • min_rec_mask  B+树的每层非叶子节点中的最小记录都会添加该标记

  • heap_no

    这个属性表示当前记录在本中的位置,从图中可以看出来,我们插入的4条记录在本中的位置分别是:2345。是不是少了点啥?heap_no值为01的记录,这两个记录并不是我们自己插入的,所以有时候也称为伪记录或者虚拟记录。这两个伪记录一个代表最小记录,一个代表最大记录

  • 记录也可以比大小,对于一条完整的记录来说,比较记录的大小就是比较主键的大小。

两条伪记录分别为最小记录与最大记录(跟图上的Infimum + supremum 有关)。这两条记录的构造十分简单,都是由5字节大小的记录头信息和8字节大小的一个固定的部分组成的,如图所示

它们并不存放在User Records部分,他们被单独放在一个称为Infimum + Supremum的部分

next_record

表示从当前记录的真实数据到下一条记录的真实数据的地址偏移量。

比方说第一条记录的next_record值为32,意味着从第一条记录的真实数据的地址处向后找32个字节便是下一条记录的真实数据。

其实就是个链表。

下一条记录指得并不是按照我们插入顺序的下一条记录,而是按照主键值由小到大的顺序的下一条记录。

所以下一条记录并不一定物理连续,

Infimum记录(也就是最小记录) 的下一条记录就是本页中主键值最小的用户记录,而本页中主键值最大的用户记录的下一条记录就是 Supremum记录(也就是最大记录)

是一个链表形势的把数据穿插起来。

删除记录的话,就是相当于链表的next record的指针移动(偏移量的变化),实际上物理上面并没有移除。

并且被删除的记录next record为0;

不论我们怎么对页中的记录做增删改操作,InnoDB始终会维护一条记录的单链表,链表中的各个节点是按照主键值由小到大的顺序连接起来的。

next_record这个指针为什么要指向记录头信息和真实数据之间的位置呢?

因为这个位置刚刚好,向左读取就是记录头信息,向右读取就是真实数据。我们前边还说过变长字段长度列表、NULL值列表中的信息都是逆序存放,这样可以使记录中位置靠前的字段和它们对应的字段长度信息在内存中的距离更近,可能会提高高速缓存的命中率。

大喊牛逼,感觉意思就是因为之前的额外信息是逆序存储的,那么从中间进行向左推遍历,就能正序的访问列的变长大小之类的了。而且,这样也比较好的向右寻找到对应真实数据。左右相对对称,

而且,如果删除的记录被标记了删除,存储空间没有回收的话,再次插入主键相同的,会进行复用之前的物理空间

当数据页中存在多条被删除掉的记录时,这些记录的next_record属性将会把这些被删除掉的记录组成一个垃圾链表,以备之后重用这部分存储空间。

2. Page Header(页面头部)

数据页的第二部分!!!占56个字节,存储各种状态信息。

这是为了得到一个数据页中存储的记录的状态信息,比如本页中已经存储了多少条记录,第一条记录的地址是什么,页目录中存储了多少个槽等等,特意在页中定义了一个叫Page Header的部分,它是结构的第二部分,这个部分占用固定的56个字节,专门存储各种状态信息,具体各个字节都是干嘛的看下表:

名称 占用空间大小 描述
PAGE_N_DIR_SLOTS 2字节 在页目录中的槽数量
PAGE_HEAP_TOP 2字节 还未使用的空间最小地址,也就是说从该地址之后就是Free Space
PAGE_N_HEAP 2字节 本页中的记录的数量(包括最小和最大记录以及标记为删除的记录)
PAGE_FREE 2字节 第一个已经标记为删除的记录地址(各个已删除的记录通过next_record也会组成一个单链表,这个单链表中的记录可以被重新利用)
PAGE_GARBAGE 2字节 已删除记录占用的字节数
PAGE_LAST_INSERT 2字节 最后插入记录的位置
PAGE_DIRECTION 2字节 记录插入的方向
PAGE_N_DIRECTION 2字节 一个方向连续插入的记录数量
PAGE_N_RECS 2字节 该页中记录的数量(不包括最小和最大记录以及被标记为删除的记录)
PAGE_MAX_TRX_ID 8字节 修改当前页的最大事务ID,该值仅在二级索引中定义
PAGE_LEVEL 2字节 当前页在B+树中所处的层级
PAGE_INDEX_ID 8字节 索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAF 10字节 B+树叶子段的头部信息,仅在B+树的Root页定义
PAGE_BTR_SEG_TOP 10字节 B+树非叶子段的头部信息,仅在B+树的Root页定义

这里面比较需要注意的:

PAGE_DIRECTION

假如新插入的一条记录的主键值比上一条记录的主键值大,我们说这条记录的插入方向是右边,反之则是左边。用来表示最后一条记录插入方向的状态就是PAGE_DIRECTION(比主键大不大,决定了插入方向)

PAGE_N_DIRECTION

假设连续几次插入新记录的方向都是一致的,InnoDB会把沿着同一个方向插入记录的条数记下来,这个条数就用PAGE_N_DIRECTION这个状态表示。当然,如果最后一条记录的插入方向改变了的话,这个状态的值会被清零重新统计。

3. File Header(文件头部)

刚才的Page Header是只针对数据页才有的各种状态(比如记录多少个数据)

这个文件头是mysql中,各种页的都通用的内容。

页都通用的一些信息,比方说这个页的编号是多少,它的上一个页、下一个页是谁(38个字节)

名称 占用空间大小 描述
FIL_PAGE_SPACE_OR_CHKSUM 4字节 页的校验和(checksum值)
FIL_PAGE_OFFSET 4字节 页号
FIL_PAGE_PREV 4字节 上一个页的页号
FIL_PAGE_NEXT 4字节 下一个页的页号
FIL_PAGE_LSN 8字节 页面被最后修改时对应的日志序列位置(英文名是:Log Sequence Number)
FIL_PAGE_TYPE 2字节 该页的类型
FIL_PAGE_FILE_FLUSH_LSN 8字节 仅在系统表空间的一个页中定义,代表文件至少被刷新到了对应的LSN值
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4字节 页属于哪个表空间

FIL_PAGE_SPACE_OR_CHKSUM(校验和)

这个代表当前页面的校验和(checksum)。啥是个校验和?就是对于一个很长很长的字节串来说,我们会通过某种算法来计算一个比较短的值来代表这个很长的字节串,这个比较短的值就称为校验和。这样在比较两个很长的字节串之前先比较这两个长字节串的校验和,如果校验和都不一样两个长字节串肯定是不同的,所以省去了直接比较两个比较长的字节串的时间损耗。

FIL_PAGE_OFFSET(唯一编号)

每一个都有一个单独的页号,就跟你的身份证号码一样,InnoDB通过页号来可以唯一定位一个

FIL_PAGE_TYPE

InnoDB为了不同的目的而把页分为不同的类型。

页面类型还有:

类型名称 十六进制 描述
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_PREVFIL_PAGE_NEXT

上一个页号和下一个页号,类似双向链表,把页穿起来了。不需要物理关联。

并不是所有类型的页都有上一个和下一个页的属性,不过我们本集中唠叨的数据页(也就是类型为FIL_PAGE_INDEX的页)是有这两个属性的,所以所有的数据页其实是一个双链表

感谢大佬得书!!https://juejin.im/book/5bffcbc9f265da614b11b731/section/5bffdb30518825773a2ed38c

[Mysql]InnoDB数据页结构(掘金小册阅读笔记)相关推荐

  1. MySQL—InnoDB数据页结构

    概述 它是InnoDB管理存储空间的基本单位,一个页的大小一般是16KB.我们表中记录都是存放在页中的,官方称这种存放记录的页为索引(INDEX)页.因为这种类型的页是用来存放表数据的,也可以称为数据 ...

  2. MySQL进阶 - InnoDB数据页结构

    不同类型的页简介 前边我们简单提了一下页的概念,它是InnoDB管理存储空间的基本单位,一个页的大小一般是16KB.InnoDB为了不同的目的而设计了许多种不同类型的页,比如存放表空间头部信息的页,存 ...

  3. InnoDB 数据页结构

    参考https://blog.csdn.net/xioayu96/article/details/107857452 页(Page)是 Innodb 存储引擎用于管理数据的最小磁盘单位(默认16K) ...

  4. 《MYSQL是怎样运行的》笔记|配置文件|系统变量|字符集|InnoDB存储结构|数据页结构|索引结构与使用|数据目录|表空间|连表原理|查询优化|BufferPool|事务|redo与undo|锁

    <MYSQL是怎样运行的>笔记 前记: 历时15天,笔记+看书.完成于2022.2.5. 本书是讲具体的数据库实现,而数据库系统概念见:https://blog.csdn.net/qq_4 ...

  5. 【MySQL】InnoDB行格式、数据页结构以及索引底层原理分析

    目录 一.MySQL架构图 二.InnoDB数据页结构 2.1 局部性原理 2.2 InnoDB的数据页格式 三.InnoDB的行格式 3.1 Compact行格式 3.1.1 变长字段长度列表 3. ...

  6. mysql 表 页 行_Mysql之InnoDB行格式、数据页结构

    Mysql架构图 存储引擎负责对表中的数据的进行读取和写入,常用的存储引擎有InnoDB.MyISAM.Memory等,不同的存储引擎有自己的特性,数据在不同存储引擎中存放的格式也是不同的,比如Mem ...

  7. (八)InnoDB数据存储结构

    InnoDB数据存储结构 1.数据库的存储结构:页 1.1.磁盘与内存交互基本单位:页 1.2.页的结构概述 1.3.页的大小 1.4.页的上层结构 2.页的内部结构 第1部分:File Header ...

  8. Mysql+innodb数据存储逻辑

    Mysql+innodb数据存储逻辑. 表空间由段,区,页组成 ibdata1:共享表空间.即所有的数据都存放在这个表空间内.如果用户启用了innodb_file_per_table,则每张表内的数据 ...

  9. python文件下载器代码_GitHub - applechi/pythonCollection: python代码集合(文件下载器、pdf合并、极客时间专栏下载、掘金小册下载、新浪微博爬虫等)...

    json2mysql 这次更新了将一个json文件中的数据导入到mysql的脚本. 是用nodejs写的. 对应的文件是tomysql.js 有兴趣的同志可以研究下. pythonCollection ...

  10. 3-7 慕课和掘金小册的学习

    慕课和掘金小册的学习 1.前端安全系列(一):如何防止XSS攻击? 从上次事件之后,小明会小心的把插入到页面中的数据进行转义.而且他还发现了大部分模板都带有的转义配置,让所有插入到页面中的数据都默认进 ...

最新文章

  1. element-ui中el-tree树形控件-树节点的选择(选中当前节点,获取当前id并且获取其父级id)...
  2. python write非法字符报错_Python爬虫实现的微信公众号文章下载器
  3. Java系列笔记(1) - Java 类加载与初始化
  4. Linux Shell脚本入门--wget 命令用法详解
  5. 【剑指offer】矩形覆盖
  6. Leetcode5635. 构建字典序最大的可行序列[C++题解]:dfs暴搜
  7. NYOJ 685 查找字符串 字典树
  8. 基于Xml 的IOC 容器-分配解析策略
  9. e2200网卡驱动 linux,Linux驱动修炼之道-驱动中一些常见的宏
  10. 淘宝端智能演进和思考
  11. 前端_网页编程 节流
  12. 洛谷月赛 P3406 海底高铁
  13. 模块 calendar
  14. 10. Have assignment operators return a reference to *this
  15. spring @Transactional注解的使用和失效场景
  16. Intelligent Reference Curation for Visual Place Recognition via Bayesian Selective Fusion 论文阅读及注解
  17. 交互设计师作品集网站整理
  18. 在Ubuntu18.04上编译SWASH模型
  19. Android避免内存溢出(Out of Memory)方法总结
  20. 《Dragon Runaway》免费发布啦!请帮助小飞龙赶快逃离末日吧!

热门文章

  1. 使用python Selenium实现智慧树界面化自动刷网课 chromehandless实现智慧树无界面化自动刷网课
  2. HTML5响应式手机模板:h5手机抽奖游戏活动页面集合模板 HTML+CSS+JavaScript
  3. 人工智能——前言概述
  4. jy-12-SPRINGMYBATIS02——学子商城-@成恒
  5. 【Axure图标库】Axure彩色长阴影图标库910+ 方与圆二合一
  6. IFC标准是什么标准?IFC标准的发展历程是怎样的?
  7. 2022年下半年软考初级程序员备考
  8. RemObjects SDK开发论坛
  9. 3dsMax中Vray渲染器材质参数使用及5种材质展示
  10. html简单网页设计实验实践结论,网页设计社会实践报告