MySQL 的数据到底是怎么存的(下)|MySQL 系列(5)
作者 | 小汪哥写代码
来源 | 小汪哥(ID:xwgcoding)
前言
上篇文章《mysql的数据到底是怎么存的(下)|mysql系列(4)》我们分享了mysql innodb 引擎数据落盘的物理位置及物理空间的区分,那逻辑上数据是怎么组织的呢?其实关于这个方面的知识,前辈们已经整理的很多了。这里只是按照我的理解整理一下,当一回知识的搬运工。这里我们还是以InnoDB 存储引擎为例。
innodb 逻辑存储结构
MySQL 的存储结构分为 5 级:表空间、段、簇、页、行。
【表空间 Table Space】
表空间可以看做是 InnoDB 存储引擎逻辑结构的最高层,所有的数据都存放在表空间中。分为:系统表空间、独占表空间、通用表空间、 临时表空间、Undo 表空间。
【段 Segment】
表空间是由各个段组成的,常见的段有数据段、索引段、回滚段等,段是一个逻辑的概念。一个 ibd 文件(独立表空间文件)里面会由很多个段组成。
创建一个索引会创建两个段:
- 一个是索引段:leaf node segment,管理非叶子节点的数据
- 一个是数据段:non-leaf node segment,管理叶子节点的数据。
也就是说,一个表的段数,就是索引的个数乘以 2。
段的内存结构:INODE Entry
【簇 Extent】
一个段(Segment)又由很多的簇(也可以叫区)组成,每个区的大小是 1MB(64个连续的页)。
每一个段至少会有一个簇,一个段所管理的空间大小是无限的,可以一直扩展下去,但是扩展的最小单位就是簇。
区的内存结构:XDES Entry
【页 page】
簇是由连续的页(Page)组成的空间,一个簇中有 64 个连续的页。(1MB/16KB=64)。这些页面在物理上和逻辑上都是连续的。
页是MySQL中磁盘和内存交互的基本单位,也是MySQL是管理存储空间的基本单位。Innodb 默认每页16KB。也可以通过 innodb_page_size 设置。
一个表空间最多拥有 2^32 个页,默认情况下一个页的大小为 16KB,也就是说一个表空间最多存储 64TB 的数据。
InnoDB 的页和操作系统的页对应关系
操作系统和内存打交道,最小的单位是页 Page。文件系统的内存页通常是 4K。
InnoDB也为了不同的目的设计了若干种不同类型的页面。Undo日志页 、段信息节点、nsert Buffer空闲列表、Insert Buffer位图、系统页、索引页,也就是我们所说的数据页等。
数据页代表的这块16KB大小的存储空间可以被划分为多个部分,不同部分有不同的功能,各个部分如图所示:
【行 Row】
每一行数据是存在页上的,InnoDB 是按行存储的,每一行记录就是一条数据,插入数据过程如下:
每条记录都有记录一个区域存着记录头信息
每页数据中的组织形式
每页数据中分组的组织形式InnoDB会把页中的记录划分为若干个组,每个组的最后一个记录的地址偏移量作为一个槽,存放在Page Directory中。便于二分查找定位数据。
页和页直接的组织形式
这样要依赖于 File Header 中的两个属性
- FIL_PAGE_PREV:上一个页的页号
- FIL_PAGE_NEX:下一个页的页号
段由簇构成,段通过三个链表将不同状态的簇连接管理起来,链表是双向的,链表头分别为:FSEG_FREE,FSEG_FULL,FSEG_NOT_FULL,链表节点就是簇,每个簇被一个簇描述符管理。一个簇描述符,占用40B的空间,这些信息是被存储在页面中,这个页称为簇描述页,它存储的内容叫簇描述符。在Innodb中,一个簇描述页默认管理16834个页面,簇的大小默认为64个页,而一个簇描述符为40B,所以一个簇描述页中有16834/64=256个簇。其中256*40B空间用来存储簇描述符,关系图如下:
表空间、Inode页面、Inode、段、簇、页面之间的关系:
到目前为止,整个数据存储的脉络大概清楚了。InnoDB 页管理的逻辑图如下:
参考:
https://segmentfault.com/a/1190000037436803
https://www.cnblogs.com/zsql/p/11466934.html