mysql InnoDB存储结构

本文主要是对InnoDB的逻辑存储结构进行学习。

mysql支持很多存储引擎,使用show engines可以查看,如下图所示

此处插入mysql支持的存储引擎

其中InnoDB是我们实际工作中最常接触到的存储引擎。

InnoDB存储引擎,数据被放在表空间(tablespace)中,表空间又分为段(segment)、区(extent)、页(page)。

此处插入InnoDB逻辑存储结构

默认情况下InnoDB存储引擎有一个共享表空间ibdata1,即所有的数据都放在这个表空间内。当参数innodb_file_per_table开启的时候,每个表的数据就会单独放到一个表空间内。

例如我有一个数据库mytestdb,里面有一个表user_info。那么在mysql存放数据的路径里面,就有会一个mytestdb文件夹,里面有user_info.frmuser_info.ibd两个文件。

注意:每个表的表空间里面存放的是数据、索引、插入缓冲Bitmap页,其他的数据(例如undo log、系统事务信息等)还是存放在原来的共享表空间ibdata1里面,所以即使innodb_file_per_table已开启,共享表空间ibdata1还是会变大。

表空间由各个段组成,常见的段有数据段、索引段、回滚段等。

区是由连续页组成的空间,每个区的大小都是1MB。为了保证区的连续性,InnoDB存储引擎会一次从磁盘申请4~5个区。

页是InnoDB磁盘管理的最小单位,每个页默认的大小是16KB,所以一个区有64个连续的页。可以通过参数innodb_page_size来设置页的大小。常见的页的类型有:数据页、undo页、系统页、事务数据页…………

数据页的结构如下图所示:

此处插入数据页的结构

可以看到InnoDB数据页里面有以下部分:

  • File Header :里面是记录的一些头信息。
    • 例如上一个页FIL_PAGE_PREV、下一个页FIL_PAGE_NEXT。(所以页和页之间是双向链表)
    • 例如页的类型FIL_PAGE_TYPE,可以是数据页,也可以是索引页或其他类型,根据取值来进行区分
    • …………
  • Page Header :是记录数据页的状态信息
    • PAGE_N_DIR_SLOTS是在Page Directory页目录中的槽数
    • PAGE_N_RECS是该页中记录的数量
    • PAGE_LAST_INSERT是最后插入记录的位置
    • …………
  • Infimum和Supremum :是每个数据页中都有的两个虚拟的行记录。这两个在页创建的时候就有了,而且在任何情况下都不会被删除。
    • Infimum是比该页中最小的记录还要小的记录
    • Supremum是比该页中最大的记录还要大的记录
  • User Record :是实际存储的记录内容
    • 行与行之间是链表结构
  • Free Space :是空闲空间
    • 该部分也是链表结构。
    • 当一条记录被删除之后,它的空间就会被加入空闲链表中
  • Page Directory :是一个稀疏目录。
    • InnoDB查找在具体的数据页里面查找某条记录的时候,现将数据页载入内容,然后通过Page Directory二分查找找到大致的位置,然后通过链表结构(即每个行的next_record标志位来找到下一条)来查找。
  • File Trailer :是为了检测页是否已经完整写入磁盘用的,可以用来保证页的完整性。
Show Comments