首页 > 其他分享 >【Innodb阅读笔记】之行记录格式(Redundant)

【Innodb阅读笔记】之行记录格式(Redundant)

时间:2024-12-09 15:27:35浏览次数:5  
标签:10 00 20 字节 记录 笔记 Innodb Redundant 长度

一、Redundant 行记录格式

        在 MySQL 5.0 版本之前,Innodb 采用 Redundant 这种行记录存储方式。MySQL 之所以仍保留对 Redundant 的支持,关键在于要确保与旧版本页格式的兼容性,以此维系数据库在不同版本更迭期间的平稳过渡与数据连贯性。值得一提的是,Redundant 行记录格式自身还具备不少独特优点,使其在当时发挥了重要作用。

        其一,Redundant 格式有着出色的稳定性。在早期 MySQL 数据库应用场景尚不算复杂、硬件资源相对有限的环境下,它能够稳健地承载各类数据存储任务,极少出现因存储格式自身问题引发的数据异常或丢失情况,为数据库的稳定运行筑牢根基,让企业用户放心地将关键业务数据托付其中。

        其二,数据解析简易。从存储结构来看,虽说它与 Compact 行记录格式有所不同,但正是因为自身记录头信息及固定的存储规则,让数据解析环节相对直截了当。开发人员、数据库管理员在进行数据提取、排查问题或是执行低层级的数据操作时,能够迅速依据其格式特点定位到目标数据,节省大量时间成本,提升运维与开发效率。

        其三,Redundant 行记录格式兼容性极佳。它不仅适配旧版本 MySQL 的诸多特性与功能模块,对于一些老旧的第三方数据库工具、插件,同样能够无缝对接。这意味着企业无需大规模更换周边技术生态,就能持续利用既有资源开展业务,降低技术升级的成本与风险。

       再看 Redundant 行记录格式的具体构成,它与广为人知的 Compact 行记录格式相比,二者有着显著差异。Compact 行记录格式的开头部分是字段长度偏移列表,该列表别具一格,依照列顺序的逆序进行排列。具体而言,若字段长度小于 255 字节,仅用 1 字节予以表示;一旦长度超出 255 字节,便会启用 2 字节来精准描述。

        第二部分是记录头信息,这部分稳稳占据 6 字节的存储空间。其中,n_fields 值是重中之重,它精准记录了一行当中列的数量,以 10 位二进制数来承载信息,理论上最大值可达 1023,这一数值设定恰好揭示了 MySQL 数据库每行最多支持 1023 个列的底层缘由;另有一个 1byte_offs_flag,该标识肩负特殊使命,专门用于界定偏移列表究竟占用 1 字节还是 2 字节,为后续数据读取、解析提供关键指引。下面是记录头信息具体解析:

名称大小描述
()1未知
()1未知
deleted_flag1该行是否已被删除
min_rec_flag1存储目录项记录中主键值最小的目录项记录置为1,其它情况都置0.
n_owned4页目录中每个组的最后一条记录会存储该组的记录数,作为n_owned字段。值的关注的是,在mysql中最小记录是一组,普通记录与其它记录是一组,因此最小记录中n_owned属性是1,最大记录的n_owned值是5.
heap_no13当前页中该记录的排序位置
n_fields10 记录中页的数量
1byte_offs_flag1偏移列表为 1 字节还是 2 字节
next_record16页中 下一条记录的相对位置
total40 合计

二、实践

1. 创建表结构并导入对应数据

# mytest 表结构 
mysql> show create table mytest \G;
*************************** 1. row ***************************
       Table: mytest
Create Table: CREATE TABLE `mytest` (
  `t1` varchar(10) DEFAULT NULL,
  `t2` varchar(10) DEFAULT NULL,
  `t3` char(10) DEFAULT NULL,
  `t4` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT
1 row in set (0.00 sec)


# 根据 mytest 表 创建表结构
create table mytest2 engine = Innodb row_format = redundant
as select * from mytest


# 表定义 
mysql> show table status like 'mytest2' \G;
*************************** 1. row ***************************
           Name: mytest2
         Engine: InnoDB
        Version: 10
     Row_format: Redundant
           Rows: 8
 Avg_row_length: 2048
    Data_length: 16384
Max_data_length: 0
   Index_length: 0
      Data_free: 0
 Auto_increment: NULL
    Create_time: 2024-12-09 10:32:41
    Update_time: 2024-12-09 10:32:41
     Check_time: NULL
      Collation: utf8mb4_general_ci
       Checksum: NULL
 Create_options: row_format=REDUNDANT
        Comment:
1 row in set (0.00 sec)

2. 找到 mytest2.ibd 文件,并使用二进制文件打开

# 查找到 C07D位置
23 20 16 14 13 0c 06     # 边长字段列表
00 00 10 0f 00 ba        # record header
00 00 00 00 02 09        # rowid
00 00 00 00 05 5f        # transactionID
da 00 00 01 59 01 10     # roll point
61 
62 62
62 62 20 20 20 20 20 20 20 20
63 63 63

# 解析第一行 变长字段列表  23 20 16 14 13 0c 06 
# 转换为 06 0c 13 14 16 20 23 分别代表:
# 第一列长度 6,第二列长度 6 = 0x0C - 0x06 第三列长度 7 = 0x13 - 0x0C
# 第四列长度 1 = 0x14 - 0x13,第五列长度 2 = 0x16 - 0x14
# 第六列长度 10 = 0x20 - 0x16,第七列长度 3 = 0x23 - 0x20

# 解析第二行

# 00 转换为 二进制 0000 0000,前两位不介绍,第三位表示当前记录没有被删除, 第四位表示当前记录不是最小记录, 
# 后四位表示 当前组有多少数据,记录在最后一行,当前不是最后一行数据,所以为 0 

# 00 10 0f 转换为二进制 为 0000 0000 0001 0000 0000 1111
# 对于前 13 位 0000 0000 0001 0,表示排序顺序为 10
# 对于 14 到 23 位 000 0000 111 记录列的数量,转换为 10进制为 7 位,正好对应边长字段个数
# 最后 1 为 是否为 1 字节,当前为 1,表示列的长度用 1 字节表示

# 0c 06 表示下一行的相对位置 0xC089 + 0x00BA - 0x008A (当前数据的偏移地址) = 0xC0B9

# 后面 7 列为正常数据列 其中 3 行为隐藏列,4 行为定义数据列

# 第二行数据  
23 20 16 14 13 0c 06     # 边长字段列表
00 00 18 0f 00 ea        # record header
00 00 00 00 02 0a        # rowid
00 00 00 00 05 5f        # transactionID
da 00 00 01 59 01 1e     # roll point

# transactionID 为什么和第一条数据一样 
# 因为 他们是在一个事物提交的, 所以事务是一样的
# 注意 第三条数据的位置计算 0xC0B9 + (0x00EA - 0x00BA (当前数据的偏移地址)) = 0xC0B9  + 0x30 = C0E9

# 第三行数据 null 数据 
21 9e 94 14 13 0c 06     # 边长字段列表
00 00 20 0f 01 18        # record header
00 00 00 00 02 0b        # rowid
00 00 00 00 05 5f        # transactionID
da 00 00 01 59 01 2c     # roll point 
64
00 00 00 00 00 00 00 00 00 00
66 66 66

# 解析第一行 变长字段列表  21 9e 94 14 13 0c 06
# 转换为 06 0c 13 14 94 9e 21 分别代表:
# 第一列长度 6,
# 第二列长度 6 = 0x0C - 0x06 
# 第三列长度 7 = 0x13 - 0x0C
# 第四列长度 1 = 0x14 - 0x13,
# 第五列固定长度 null 变成 0x94,边长列表记录为 0x94 固定写死,行中数据使用00占用
# 第六列长度 10 = 0x9e - 0x94,记录当前行占用多少字节,但是具体行不存储数据
# 第七列长度 3 = 0x21 - 0x14 - 0x0A(第二行数据 null占用字节 )


        当前表 mytest2 的字符集为 Latin1,每个字符最多占用 1 字节,若用户将表的字符集改为 utf8,第三列固定长度类型长度不再是占用10字节,而是 10 * 3 = 30 字节, 所以在 Redundant 下 char 可能是占用存储最大字节数。

标签:10,00,20,字节,记录,笔记,Innodb,Redundant,长度
From: https://blog.csdn.net/weixin_43262384/article/details/144338550

相关文章

  • GObject学习笔记(二)类型创建与注册
    前言本文可在https://paw5zx.github.io/GObject-tutorial-beginner-02/中阅读,体验更加在上一节中我们介绍了GObject类型的类和实例变量的创建和使用。GObject是一个基本的可实例化类类型,是所有使用GObject系统的类型的基类,提供了继承、封装、多态等面向对象的核心特性。不过我们......
  • CTF学习笔记
    RSA入门(二)-Kicky_Mu-博客园按键音(即DTMF)解密网站:DTMFDecoderPHP伪协议e.ghttp://node5.anna.nssctf.cn:25660/falg.php不能通过换思路http://node5.anna.nssctf.cn:25660/flag或者?file=php://filter/resource=flagwebdog1_startif(isset($_GET['web'])){$f......
  • [笔记] Git 实战指南:Git命令大全 与 Git提交信息规范
    本文档是关于Git版本控制系统的综合指南,涵盖了从基础到高级的各种命令和最佳实践。它旨在为开发者提供一个全面的资源,帮助他们更有效地使用Git进行代码版本管理、团队协作以及项目开发。文档分为两个主要部分:Git命令大全和Git提交信息规范。Git安装文档:[笔记]W......
  • STM32开发环境笔记
             ......
  • PAWNYABLE kernel race condition 笔记
    漏洞点在于,open的时候mutex的检查和设置不是原子操作。staticintmodule_open(structinode*inode,structfile*file){printk(KERN_INFO"module_opencalled\n");if(mutex){printk(KERN_INFO"resourceisbusy");return-EBUSY;}mutex=......
  • 【笔记】VMware vCenter(VSCA)分布式交换机的使用
    先说咋回事,我有俩服务器,都有万兆电口,但是我交换机是千兆的,只有四个万兆光口而且我只有第一个服务器有光口,第二个只有俩万兆电口,我做虚拟机迁移的时候如果走交换机就把我业务口的带宽占完了,而且还是千兆所以想用vsca的分布式交换机实现俩服务器之间网络直连不走交换机1、首先在V......
  • MySQL学习笔记(第三天)
    第三天常见的字段约束NOTNULL:不能为空UNIQUE:字段值必须唯一的(不能重复)DEFAULT:默认值(当插入数据的时候没有给初始值,使用默认值)->成绩字段->0        ->保密PRIMARYKEY:主键(UNIQUE+NOTNULL)FOREIGNKEY:外键()测试NOTNULLMariaDB[test2]......
  • MySQL学习笔记(第四天)
    第四天范围查询BETWEENANDIN(1,2,3,4)SELECT*FROMproductWHEREpriceBETWEEN300AND800;查询价格在300~800之间的商品SELECT*FROMproductWHEREcidIN('c001','c003');查询商品cid=c001或c003LIMIT限制返回数量LIMITN=>返回前N条数据LIMITN,M=>......
  • Linux命令学习笔记(第六天)
    第六天cat>zijinjie.txt<<EOF当前页面编辑文件(不用vim)按EOF退出head默认读取文件的前10行-nnl/etc/passwd|head-5读取passwd文件的前五行并显示行号tail默认读取文件的尾10行-ntail-n+2从第2行开始显示到末尾tail-fsc.txt动态监控文件末尾的变化,一旦有新......
  • LLM学习笔记(17)序列标注任务(训练模型阶段)
    训练模型这段代码的主要功能是构建一个用于序列标注任务的模型,尤其是针对命名实体识别(NER,NamedEntityRecognition)的任务。通过利用BERT模型和Transformers库提供的工具,快速构建一个可用于标注每个token的实体标签的分类器。构建模型具体功能AutoModelFo......