mysql之innodb存储结构

2021/08/09 1065点热度 0人点赞 0条评论

InnoDB,是MySQL的数据库引擎之一,现为MySQL的默认存储引擎,为MySQL AB发布binary的标准之一。

InnoDB存储结构

  • 以页为单位来管理存储空间;

  • 以页作为磁盘和内存交互的基本单位;

  • 默认页大小为16kb(所以最少一次从磁盘读取16kb的内容),可以通过innodb_page_size 修改页的大小(在初始化时指定 mysqld --initialize);

  • 不同的行格式在磁盘上的存放形式也不同;

  • mysql规定一页中最少存储2行数据

  • 页中需要占用的额外空间需要132字节

compact 行格式(其他的差不多)

图片

  • 变长字段长度列表(2字节)

  • 变长字段包含 varchar varbinary text blob等

  • 按真实占用的字节数逆序存放

  • 长度列表只是表示当前字段在此占用的直接长度(方便探知和检索)

  • null值列表(1字节)

  • 标记允许为NULL的列

  • 用位来存储,1表示为NULL,0表示非NULL

  • null值列表必须是整数个字节(一个字节可以表示8列,设计表是,如果非null,一定要加上not null,字段多时,可以减少一些空间占用)

  • 记录头信息

  • 由固定的5字节组成

  • 可以理解为记录的元数据 图片

  • 记录的真实数据

  • 默认添加row_id(6字节,唯一标记)、trx_id(6字节,事务id)、roll_pointer(7字节,回滚指针)

  • 数据过长时,只会存储前768字节的数据,超过的数据会存储到溢出页中(需要20字节指向真正存储的数据页);

综上:mysql一条记录最少额外占用最少27字节;

上面数据过长,是多长?假设,我们有1个列数据过长,我们可以通过 132+2(n+27)<16*1024 算出当n>8099的时候绝对会溢出;

主键生成策略:

  • 优先使用自定义的主键

  • 没有自定义主键选不允许为NULL的唯一业务主键

  • 以上都没有使用mysql的row_id

InnoDB数据页结构

InnoDB有不同类型的数据页

  • 存放表空间的页

  • 存放数据的页

  • 存放索引的页

  • 存放inode信息的页

  • 存放redo信息的页

  • 存放undo信息的页 图片

Page Header

存储在数据页中的状态信息,包含了存储了多少数据,还有多少空闲,最后插入记录的位置,当前页的最大事务id,在B+树中所处的层级,索引ID(B+树中)

File Header

标注了页号、上一个页的页号,下一个页的页号,页面最后修改对应的额LSN,页的类型,页面被刷新到了哪个LSN,属于哪个表空间

File Trailer

我们都知道磁盘的写入数据远不如内存的cpu缓存的写入。mysql通过redo log来保证最终写入的一致性。在mysql写入磁盘的时候

  • 先将File Header 中的校验值写入到磁盘中

  • 页面刷新到磁盘后,再将File Trailer中的校验写入到磁盘

  • 前后一致写入成功

File Trailer中也会存储最后修改的LSN,如果不一致,会通过redo log进行修复。

yxkong

这个人很懒,什么都没留下