浅析InnoDB Record Header及page overflow(1)

简介: 浅析InnoDB Record Header及page overflow

前言

土人有土办法,利用innodb_ruby观测验证innodb page header及overflow临界点。

这是一篇封存了两年的文章,最近拿出来重新整理发布。

1、背景信息

1.1 InnoDB Diagrams项目

首先看一下Jeremy Cole、Davi Arnaut两位大神联合维护的牛逼项目:InnoDB Diagrams

在这个项目中,详细介绍了InnoDB引擎数据结构、日志结构,以及InnoDB内部的运行机制。

为了配合这个项目,二位大神还开发了一个InnoDB数据文件解析工具 innodb_ruby

1.2 InnoDB Record Header

InnoDB Diagrams项目中有一张图介绍了InnoDB record header是如何构成的

image.png


关于这些头信息的解释可见文章 The physical structure of records in InnoDB,本文不赘述。

简言之,记住几条关键规则

  • 一条记录的record header,至少是5字节
  • 对record header影响最大的是变长列数量,及其是否允许为NULL的属性

关于变长列

  • 每个变长列,如果列长度 <128 字节,则需要额外1字节
  • 每个变长列,如果列长度 >=128 字节,则需要额外2字节
  • 如果没有任何变长列,则无需这额外的1-2字节
  • 变长类型为char/varchar/text/blob等

同学们可能会诧异,char为什么也当做变长类型了?这是因为,当字符集非latin1时,最大存储长度可能会超过255字节,例如 char(65) utf8mb4 最长就可以存储260字节,此时在record header中需要用2字节来表示其长度,因此也被当做变长类型了

关于列允许为NULL

  • 每个列如果允许为NULL,则增加 1bit,不足8bit也需要额外1字节
  • 例如只有2个列允许为NULL,只需要2bit来表示,但也需要占用1字节

P.S,在InnoDB的存储结构里,从tablespace到segment,再到extent、page,还是file层面,总有各种必要的header或trailer信息需要消耗额外的字节数,不像MyISAM那么简单。

1.3 innodb_ruby项目

上面提过,innodb_ruby工具可以帮助我们进一步理解InnoDB引擎数据结构、日志结构。

该项目用ruby语言开发(大神真是任性,选了这个比较冷门的开发语言)。

特别提醒,该项目已经多年未更新,有些数据类型发生了变化(例如最经典的5.6之后时间日期类型),它解析的可能就不准确了,在我下面的实测案例中也证实了这点。因此,我还用到另外一个辅助工具 innblock

1.4 innblock工具

由八怪开发,用于扫描和分析InnoDB page,详见 innblock | InnoDB page观察利器


2、定义不同数据类型时的record header消耗

根据上面的理论,我们接下来计算并验证当表里有各种不同的数据类型时,分别需要多少额外字节。

关于测试环境

  1. MySQL版本:Percona Server 5.7.22-22
  2. 测试配套工具:innodb_ruby & innblock

特别提醒,测试表的字符集为utf8mb4

经过计算和验证,最终可以得到以下几条结论:

  1. 每条记录的record header(下面简称RH)基础是5字节(简写成 RH=5)
  2. 每当表中多一个列允许为NULL,则额外增加1bit,且不足8bit时也需要消耗1字节(同理,不足16bit时需要消耗2字节)
  3. 每当表中多一个最大定义存储长度不超过255字节的变长列(char/varchar)时,额外增加1字节
  4. 每当表中多一个最大定义存储长度超过255字节的变长列(char/varchar/text/blob)时,额外增加2字节

由此我们可以推断出以下几种场景所需的record header大小横屏观看,下同)

场景 表定义 行长度
(字节)
record header
(字节)
备注说明
1 id int not null
提醒:无显式主键
28 5 5(RH)
+6(TRX_ID)
+7(ROLL_PTR)
+6(ROW_ID)
+4(INT) = 28
2 id int
提醒:无显式主键,且未指定not null
29 6 6(允许null) + 6 +7 +6
+4
= 28
3 id int not null
primary key(id)
提醒:id列是显式主键
22 5 5 + 6 + 7
+4
= 22
4 id int not null,
c1 char(10),
primary key(id)
c1列只存储一个字符'a'
34 7 7(char+null)+
6 + 7
+ 4 + 10(c1)
= 34
5 id int not null,
c1 varchar(10),
primary key(id)
c1列只存储一个字符'a'
25 7 7(varchar+null) +
6 + 7
+ 4 + 1(c1)
= 25

更多的场景,详见下面这个汇总表格

image.png




            </div>
相关文章
|
4天前
|
数据采集 人工智能 安全
|
13天前
|
云安全 监控 安全
|
5天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1102 152
|
18天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1776 9
|
10天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
708 152
|
12天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
664 15
|
7天前
|
SQL 自然语言处理 调度
Agent Skills 的一次工程实践
**本文采用 Agent Skills 实现整体智能体**,开发框架采用 AgentScope,模型使用 **qwen3-max**。Agent Skills 是 Anthropic 新推出的一种有别于mcp server的一种开发方式,用于为 AI **引入可共享的专业技能**。经验封装到**可发现、可复用的能力单元**中,每个技能以文件夹形式存在,包含特定任务的指导性说明(SKILL.md 文件)、脚本代码和资源等 。大模型可以根据需要动态加载这些技能,从而扩展自身的功能。目前不少国内外的一些框架也开始支持此种的开发方式,详细介绍如下。
467 5