InnoDB技术内幕-表的逻辑存储结构

747 阅读5分钟

带着问题去剖析InnoDB的内幕

  • 1.表段区页行概念
  • 2.索引的执行过程

InnoDB逻辑存储结构

索引组织表

  • 在InnoDB存储引擎中,表都是根据主键顺序组织存放的。
  • 在每张表中都会有个主键,如果在创建表时没有显示的定义主键,则InnoDB会选择或者创建主键
    • 首先判断表中是否有非空唯一索引,如果有,则该列为主键
    • 如果不符合条件,InnoDB存储引擎自动创建一个6字节大小的指针作为主键

表空间

  • InnoDB存储引擎逻辑结构的最高层,所有的数据都放在表空间中。
  • InnoDB存储引擎默认有一个共享表空间ibdata1,如果启用innodb_file_per_table参数,则每张表都会独立放到一个表空间内。
  • 启用innodb_file_per_table之后,每张表空间内存放的只是数据、索引、插入缓冲Bitmap页。其他类的数据,如undo信息,插入缓冲索引页、系统事务信息,二次写缓冲等还是放在共享空间内。

  • 表空间是由各个段组成,常见的段有数据段、索引段、回滚段等。
  • 数据段为B+树的叶子节点(Leaf node segment)索引段为B+树的非索引节点(Non-leaf node segment)

  • 区是连续的页组成的空间,在任何情况下每个区的大小都为1MB
  • 为了保证区的连续性,InnoDB存储引擎第一从磁盘中申请4~5个区。在默认的情况下,InnoDB引擎页的大小为16KB,即一个区中一共有64个连续的页。

页(Page)

  • 页是InnoDB引擎磁盘管理的最小单位,默认每个页的大小是16KB,可以通过innodb_page_size 设置。
  • 常见的类型有:
    • 数据页(B-tree Node)
    • undo页(undo Log Page)
    • 系统页(System Page)
    • 事务数据页(Transaction system Page)
    • 插入缓冲图页(Insert Buffer Bitmap)
    • 插入缓冲空闲列表页(Insert Buffer Free List)
    • 未压缩的二进制大对象页(Unconmpressed BLOB Pgae)
    • 压缩的二进制大对象页(compressed BLOB Page)

  • InnoDB存储引擎是面向列的,也就是说数据是按行进行存放的。每个页存放的行记录有硬性定义,最多允许存放16KB/2-200行的记录,即7992行记录。

InnoDB数据页结构

File Header

名称大小(字节)说明
FIL_PAGE_SPACE_OR_CHECKSUM4checksum值
FIL_PAGE_OFFSET4表空间中页的偏移值,用来定位具体页在表空间下所有页的位置
FIL_PAGE_PREV 4当前页的上一个页,B+Tree特性决定了叶子节点必须是双向
FIL_PAGE_NEXT 4当前页的下一个页,B+Tree特性决定了叶子节点必须是双向
FIL_PAGE_LSN8该值代表该页最后被修改的日志序列位置LSN(LogSequence Number)
FIL_PAGE_TYPE 2InnoDB存储引擎页的类型
FIL_PAGE_FILE_FLUSH_LSN8该值仅在系统表空间的一个页中定义,代表文件至少被更新到了该LSN值。对于独立表空间,该值都为0
FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 4该值代表页属于哪个空间

Page Header

名称大小(字节)说明
PAGE_N_DIR_SLOTS2Page Directory (页目录)中的Slot(槽数)
PAGE_HEAP_TOP2堆中第一个记录的指针,记录在页中是根据堆的形式存放的
PAGE_N_HEAP2堆中的记录数,2字节,第15位表示行记录格式
PAGE_FREE2指向可重用空间的首指针
PAGE_GARBAGE2已删除记录的字节数,即行记录结构中delete flag=1的记录大小总数
PAGE_LAST_INSERT2最后插入记录的位置
PAGE_N_DIRECTION2一个方向连续插入的记录数量
PAGE_N_RECS2该页中记录的数量
PAGE_MAX_TRX_ID8修改当前页的最大事务ID,注意该值仅在Secondary Index 定义
PAGE_LEVEL2当前页在索引树中的位置,0x00代表叶节点,即页节点总是在第0层
PAGE_INDEX_ID8索引ID,表示当前页属于哪个索引
PAGE_BTR_SEG_LEAF10B+树数据页非页节点所在段的segment header,注意该值仅在B+树的Root页中定义
PAGE_BTR_SEG_TOP10B+树数据页所在段的segment header,注意该值仅在B+树的Root页中定义

Infimum和Supremum Record

  • 数据页中两个虚拟边界值

User Record 和Free Space

  • User Record: 即实际存储行记录的内容
  • Free Space 空间空间

Page Directory

  • Page Directory 中存放了记录的相对位置(注意,这里存放页相对位置,而不是便宜量),有些时候这些记录指针称为Slots(槽)或目录槽。

File Trailer

  • 为了检测是否已经完整地写入磁盘,FIL_PAGE_END_LSN占用8字节,前4字节代表页的checksum值,最后4字节和File Header 中的FIL_PAGE_LSN 相同。
  • 比较方式:将这两个值与File Header中FIL_PAGE_SPACE_OR_CHECKSUM 和FIL_PAGE_LSN值进行比较是否一致来确保页的完整性。

聚集索引

通过前面的介绍,我们大体了解了InnoDB存储引擎的逻辑存储结构。结合逻辑存储结构,回答一下问题2:索引的执行过程?

  • 页是InnoDB磁盘管理的最小单位。所以对于B+树索引来说,本身并不能找到具体的一行数据。能找到的只是该行数据所在的页。然后数据库将Page加载到内存,通过页目录进行二分查找,查找到数据落在具体的槽内,在通过next_record 确定是具体哪一行数据。 库->表->页->页目录->槽->行

熊猫笔记 : panda_nodes@163.com