美文网首页mysql
InnoDB页结构

InnoDB页结构

作者: 修行者12138 | 来源:发表于2020-12-05 00:32 被阅读0次

    Innodb以页作为磁盘和内存交互的基本单位,默认大小是16k。页有各种各样的类型,其中存储真实用户数据的页称为索引页(以下简称为页)。以下讨论的页,实际上是聚簇索引的叶子节点。

    对于一些占用空间较大的列(比如varchar text blob类型等),不会把所有的数据都放在页里,具体看行格式。
    如果是COMPACT,对于占用空间较大的列,留一部分数据在页里,其他的放到溢出页。
    如果是DYNAMIC或者COMPRESSED,对于占用空间较大的列,不会留一部分数据在页里,全部放到溢出页。
    mysql 5.7默认行格式为DYNAMIC。

    一个页有7个组成部分,其中最主要的是空闲区(Free Space)、用户记录区(User Records)和页目录(Page Directory),其他的部分记录了页的一些基本信息,比如本页已存了多少记录,用户记录区的起始位置在本页的偏移量等。

    image.png

    用户记录区(也叫堆)用于存储真实的用户数据,每次新增一行记录,都会从空闲区取一定空间,划分到用户记录区,直到空闲区空了,就判定本页满了。

    每次删除记录,并不会真的把数据从页里移除掉,而是加一个删除标记(每一行记录都有若干空间存额外的信息,比如删除标记位),如果真的把数据从页里移除掉,需要把其他的记录往前移,并且需要修改偏移量,开销太大。被删除的记录会组成一个垃圾链表,垃圾的链表的空间可以被覆盖。

    用户记录区中,记录按主键从小到大排序,除了存储真实的用户数据行,还会有多余的两行,分别是Infimum和Supremum,分别表示本页的最小记录和最大记录。

    每一条记录都有一个指向下一行记录的指针(实际上存的是当前记录到下一个记录的距离,即字节数),也就是页内的记录组成了一条单向链表,单向链表的第一个节点是Infimum,第二个节点是第一行真实数据,第三个节点是第二行真实数据......倒数第二个节点是最后一行真实数据,最后一个节点是Supremum。


    image.png

    如果每次从页内找记录的时候,都从Infimum遍历到Supremum,性能太差了,所以用户记录区又分为好几个组,每个组有一个槽,记录了本组最大的记录在本页的地址偏移量。

    页里的页目录,就是用于存储槽。


    image.png

    每次从页查找数据的时候,会先从页目录做二分查找,找到比待查找值大但是差值最小的槽,待查找值就在该槽对应的组中。该槽的上一个槽对应的记录的下一行记录,就是本组的第一行记录,从这一行记录开始遍历本组,就能找到待查找的记录。

    页的File Header(文件头部)部分,存储了本页、上一个页、下一个页的页号,也就是不同页之间组成了双向链表。

    相关文章

      网友评论

        本文标题:InnoDB页结构

        本文链接:https://www.haomeiwen.com/subject/znfnwktx.html