《MySQL是怎样运行的》-读书笔记(三):InnoDB记录和数据页

135 阅读4分钟

InnoDB记录存储结构

InnoDB简介

  • InnoDB将数据划分成若干个数据页,以页作为磁盘和内存之间交互的基本单位

  • 查看 存储引擎页的大小 (默认16KB

    • show variables like 'innodb_page_size'
      image.png
  • 也就是一般情况下,一次最少从磁盘中读取 16KB的内容到内存中,一次最少把内存中的16KB刷新到磁盘中

InnoDB行格式

行格式的种类

  • COMPACT 、REDUNDANT、DANAMIC、 COMPRESSED

指定行格式的语法

create table 表名 (列的信息) ROW_FORMAT = 行格式名称

COMPACT 行格式

image.png

  • 变长字段长度列表
    • 在mysql中 varchar(M)、VARBINARY(M)、各种TEXT、各种BLOB类型 。我们把这些数据类型称之为 变长字段
    • 变长字段中存储多少个字节的数据是不固定的,所以存储的时候需要存储2部分信息
      • 真正的数据内容
      • 该数据占用的字节数
    • 变长字段长度列表 按照列的顺序逆序存放,比如变长字段n3的字节数(内容长度) ,变长字段n2的字节数
    • 字节数用 16进制表示,比如 4个字节就是 0X04

    比如 c1 ,c2,c4 3个变长字段的值分别是 'aaaa' ,'bbb','c' 对应的长度也就是 0X04 ,0X03,0X01 因此该行的数据格式也就是如下:

image.png 其中 01 03 04之间是没有间隔的,只是为了清晰展示

  • NULL值列表 一条记录中的某些列可能存储NULL值 ,如果把这些NULL值放到记录的真实数据中存储会很占地方。所以把一条记录中值为NULL的列统一管理起来。 处理过程如下:
    • 统计表中运行存储NULL的列有哪些
    • 如果表中没有允许存储NULL的列,则NULL值列表也就不存在了。
      • 否则,每个允许存储NULL值的列对应一个二进制位,二进制位按照列的顺序逆序排列 1 表示值为NULL ,0 表示不为 NULL
    • 记录头信息
      • 由固定的 5个字节组成
      • 预留位1
      • 预留位2
      • deleted_flag
        • 标记该记录是否被删除
      • min_rec_flag
        • B+树的每层非叶子节点中最小的目录项记录都会添加该标记
      • n_owned
        • 一个页面中的记录会被分为若干个组,每个组中有一个记录是 “带头大哥”,其余的是小弟。 带头大哥记录的 n_owned的值代表改组有多少条记录
      • heap_no
        • 表示当前记录在叶堆中的相对位置
      • record_type
        • 表示当前记录的类型 0 普通记录 1 B+树非叶子节点的目录项记录 2 Infimum记录 3 Supremum记录
      • next_record
        • 下一条记录的相对位置
  • 记录的真是数据
    • row_id
      • 是否必需 否 6个字节 行ID ,唯一标识一条记录
    • trx_id
      • 是否必需 是 6个字节 事务ID
    • roll_pointer
      • 是否必需 是 7个字节 回滚指针

InnoDB主键生成策略
优先使用用户自定义的主键作为主键 无自定义主键,将选取一个 not null 的 UNIQUE键作为主键 上述条件都不满足,则自动为表添加一个 名为 row_id的隐藏列作为主键

溢出列

如果某一条记录中列太多,某一列的数据在当前页放不下时就会产生溢出列

  • COMPACT 、REDUNDANT
    • 在当前列存储一部分数据,剩下数据存其他页。然后在当前列位置用 20个字节指向其他数据中存储剩余数据的地址
  • DYNAMIC COMPRESSED
    • 数据全部存其他页,在当前列位置用20个字节指向其他数据中存储剩余数据的地址

InnoDB数据页结构

数据页结构

  • 文件头部
  • 页面头部
  • Infimum + Supermum
    • 页面中的最小记录和最大记录 ,两个虚拟的记录
  • User Records
    • 用户记录,用户存储的记录内容
    • 用户记录会进行分组,每个分组最多8条记录,每个对应对应页目录中一个槽
  • Free Space
    • 空闲空间 ,页中尚未使用的空间
  • Page Directory
    • 页目录,页中某些记录的相对位置
    • 由槽组成,槽对应一个分组,记录该分组中的最后一条记录的页地址偏移量(这条记录的n_owned的值就是这个分组有多少条记录)
  • File Trailer
    • 文件尾部,校验页是否完整

在页中根据主键查找记录的方式

  • 通过二分法确定该条记录所在分组对应的槽,并找到该槽所在分组中主键值最小的那条记录
  • 通过记录的next_record 属性遍历该槽所在组的各个记录