mysql_数据页.md

seefly 2021年07月04日 15次浏览

MySql工作原理

MySQL 是怎样运行的:从根儿上理解 MySQL 学习笔记

字符串中最长的不重复子串

总结:

​ 记录在数据页内按照主键升序的方式通过next_record连接形成以个单向链表,为了能够快速定位页面中的数据mysql将表中数据进行分组,其中自带的最小记录自成一组,其他组最大8条记录,并在Page Directory(页面目录)中记录该组中最大元素的偏移量.

​ 在根据主键查找指定元素的时候,先使用二分法通过页面目录找到对应元素所在的组,然后再在组内进行遍历.

  • 数据页结构
image-20210430133232484

一、数据在数据页中的存储

再谈一下记录头

  • delete_mask 删除标志位
  • min_rec_mask B+树上非叶子节点都是1,数据节点都是0
  • n_owned 页面分组元素数量
  • heap_no 在页面中的序号,按主键或者row_id排序得到
  • record_type 数据记录类型
    • 0 普通数据行,就是我们的数据
    • 2 最小记录行,就是Infimum所在的行,系统自动添加的,它指向本页中最小的数据行
    • 3 最大记录行,就是Supremum所在的行,系统自动添加,被本页中最大的数据所指向,自己谁也不指。
    • 1 B+树非叶节点行,就是单纯的索引
  • next_record 下一个记录相对本条记录的偏移量,指向下一条记录的数据部分的开头,向左获取改行数据元信息,向右读取数据,这也是为什么变长列表和null值列表是逆序的原因。

image-20210430140721144

结论

  • 数据通过next_record形成一个单向链表
  • 节点间以主键或者row_id升序排列
  • next_record指向下一行数据的数据开始部分,相对本条数据的偏移量
  • 删除其中某行数据
    • 改变当前数据的delete_mask为1
    • 改变指向当前数据的数据行指向它的下一个元素
    • 当前数据的next_record指向当前页面内的垃圾链表的头部节点,头插法

二、Page Directory,页目录

​ 页面内的数据都是由单向链表连接起来的,虽然它是按照主键或者row_id升序连接,但是这种结构不支持快速访问,也就是说不能使用二分查找法根据主键快速定位元素,只能通过遍历的方式查找数据。

Page Directory就是一种辅助数据结构,它将页内数据分组,每组元素1~8个,组内最大的元素叫做组长(我起的),组长负责在它的记录头的n_owned字段内记录组员数量(包括他自己)。同时Page Directory内一个组对应一个solt,这个solt指向组长。这个时候如果再查询数据的话先根据solt定位组,再在组内遍历找到目标数据。

image-20210430145256482

小结

  • 数据页内数据按1~8个数据大小进行分组,最大的作为组长,并被Page Directory的一个Solt所记录
  • Infimum记录只能自己为一组
  • 组长的n_owned记录本组元素数量
  • 新增的数据会落在比自己大,且差值最小的组内
  • 当一个组放不下的时候会进行拆分,拆成两个,一个4,一个5,并新增一个Solt
  • 在当前页面根据key进行查找的时候先借助Solt定位该元素所在的组,再在组内进行遍历比对

三、Page Header(页面头部)

记录了当前页的一些有用的信息比如

  • 垃圾链表头部地址
  • 垃圾数据数量
  • 空闲空间起始地址
  • 记录数量
  • Solt数量
  • 等等

image-20210430151804025

四、File Header(文件头部)

通用数据类型,在各种页中都会由,记录一下当前页号、下一页页号、上一页页号、页面类型啥的,页面校验和

image-20210430152536200

五、File Trailer

放在页面底部,记录页面校验和,和头部的File Header相对应,就是为了在磁盘写到一半的时候断电,上半部分写进去了,下半部分没写进去,这个时候利用头部和尾部的校验和比较一下就知道这个数据是不是脏数据了