区(extent)的概念

表空间中的页实在是太多了,为了更好的管理这些页面,设计InnoDB的大叔们提出了(英文名:extent)的概念。对于16KB的页来说,连续的64个页就是一个,也就是说一个区默认占用1MB空间大小。每256个区被划分成一组


为什么要引入区?

  • 范围查找场景,解决随机I/O的问题

表空间结构.png

  • FSP_HDR类型:这个类型的页面是用来登记整个表空间的一些整体属性以及本组所有的,也就是extent 0 ~ extent 255这256个区的属性,稍后详细唠叨。需要注意的一点是,整个表空间只有一个FSP_HDR类型的页面。
  • IBUF_BITMAP类型:这个类型的页面是存储本组所有的区的所有页面关于INSERT BUFFER的信息。当然,你现在不用知道啥是个INSERT BUFFER,后边会详细说到你吐。
  • INODE类型:这个类型的页面存储了许多称为INODE的数据结构,还是那句话,现在你不需要知道啥是个INODE,后边儿会说到你吐。

  • XDES类型:全称是extent descriptor,用来登记本组256个区的属性,也就是说对于在extent 256区中的该类型页面存储的就是extent 256 ~ extent 511这些区的属性,对于在extent 512区中的该类型页面存储的就是extent 512 ~ extent 767这些区的属性。上边介绍的FSP_HDR类型的页面其实和XDES类型的页面的作用类似,只不过FSP_HDR类型的页面还会额外存储一些表空间的属性。

  • IBUF_BITMAP类型:上边介绍过了。

表空间被划分为许多连续的,每个区默认由64个页组成,每256个区划分为一组,每个组的最开始的几个页面类型是固定的就好了。

区的分类

  • 空闲的区(FREE):现在还没有用到这个区中的任何页面。
  • 有剩余空间的碎片区(FREE_FRAG):表示碎片区中还有可用的页面。
  • 没有剩余空间的碎片区(FULL_FRAG):表示碎片区中的所有页面都被使用,没有空闲页面。
  • 附属于某个段的区(FSEG)。每一个索引都可以分为叶子节点段和非叶子节点段,除此之外InnoDB还会另外定义一些特殊作用的段,在这些段中的数据量很大时将使用区来作为基本的分配单位。

段(segment)的概念

一个索引会生成2个段,一个叶子节点段,一个非叶子节点段。 段是以区为单位申请存储空间的

为什么要引入段?

  • 更深入一部解决范围查找的问题

    我们提到的范围查询,其实是对B+树叶子节点中的记录进行顺序扫描,而如果不区分叶子节点和非叶子节点,统统把节点代表的页面放到申请到的区中的话,进行范围扫描的效果就大打折扣了。所以设计InnoDB的大叔们对B+树的叶子节点和非叶子节点进行了区别对待,也就是说叶子节点有自己独有的,非叶子节点也有自己独有的。存放叶子节点的区的集合就算是一个segment),存放非叶子节点的区的集合也算是一个