为什么别人能用好 MySQL?万字详解其复杂原理( 三 )


mysql> SHOW TABLE STATUS FROM test LIKE 't' G*************************** 1. row ***************************           Name: t         Engine: InnoDB        Version: 10     Row_format: Dynamic           Rows: 2 Avg_row_length: 8192    Data_length: 16384Max_data_length: 0   Index_length: 0      Data_free: 0 Auto_increment: 3    Create_time: 2019-01-13 02:24:52    Update_time: 2019-01-13 02:28:16     Check_time: NULL      Collation: utf8mb4_general_ci       Checksum: NULL Create_options:         Comment: 1 row in set (0.00 sec)InnoDB表使用上有一些限制,如一个表最多只能有64个辅助索引,一行大小不能超过65535等,组合索引不能超过16个字段等,一般应该不会突破限制,详细见 innodb-restrictions 。
3.2 InnoDB 表空间概述表空间根据类型可以分为系统表空间,File-Per-Table 表空间,常规表空间,Undo表空间,临时表空间等 。本节分析 File-Per-Table 表空间 。

  • 系统表空间:包含内容有数据字典,双写缓冲,修改缓冲以及undo日志,以及在系统表空间创建的表的数据和索引 。
  • 常规表空间:类似系统表空间,也是一种共享的表空间,可以通过 CREATE TABLESPACE 创建常规表空间,多个表可共享一个常规表空间,也可以修改表的表空间 。
注意:必须删除常规表空间中的表后才能删除常规表空间 。
CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' Engine=InnoDB;CREATE TABLE t1 (c1 INT PRIMARY KEY) TABLESPACE ts1;CREATE TABLE t2 (c2 INT PRIMARY KEY) TABLESPACE ts1;ALTER TABLE t2 TABLESPACE=innodb_file_per_table;DROP TABLE t1;DROP TABLESPACE ts1;
  • File-Per-Table表空间:MySQL InnoDB新版本提供了 innodb_file_per_table 选项,每个表可以有单独的表空间数据文件(.ibd),而不是全部放到系统表空间数据文件 ibdata1 中 。在 MySQL5.7 中该选项默认开启 。
  • 其他表空间:其他表空间中Undo表空间存储的是Undo日志 。除了存储在系统表空间外,Undo日志也可以存储在单独的Undo表空间中 。临时表空间则是非压缩的临时表的存储空间,默认是数据目录的 ibtmp1 文件,所有临时表共享,压缩的临时表用的是 File-Per-Table 表空间 。
表空间文件结构上分为段、区、页 。
为什么别人能用好 MySQL?万字详解其复杂原理

文章插图
 
  • 段(Segment)分为索引段,数据段,回滚段等 。其中索引段就是非叶子结点部分,而数据段就是叶子结点部分,回滚段用于数据的回滚和多版本控制 。一个段包含256个区(256M大小) 。
  • 区是页的集合,一个区包含64个连续的页,默认大小为 1MB (64*16K) 。
  • 页是 InnoDB 管理的最小单位,常见的有 FSP_HDR,INODE, INDEX 等类型 。所有页的结构都是一样的,分为文件头(前38字节),页数据和文件尾(后8字节) 。页数据根据页的类型不同而不一样 。
    • FILE_SPACE_HEADER 页:用于存储区的元信息 。ibd文件的第一页 FSP_HDR 页通常就用于存储区的元信息,里面的256个 XDES(extent descriptors) 项存储了256个区的元信息,包括区的使用情况和区里面页的使用情况 。
    • IBUF_BITMAP 页:用于记录 change buffer的使用情况 。
    • INODE 页:用于记录文件段(FSEG)的信息,每页有85个INODE entry,每个INODE entry占用192字节,用于描述一个文件段 。每个INODE entry包括文件段ID、属于该段的区的信息以及碎片页数组 。区信息包括 FREE(完全空闲的区), NOT_FULL(至少使用了一个页的区), FULL(没空闲页的区)三种类型的区的List Base Node(包含链表长度和头尾页号和偏移的结构体) 。碎片页数组则是不同于分配整个区的单独分配的32个页 。
    • INDEX 页:索引页的叶子结点的data就是数据,如聚集索引存储的行数据,辅助索引存储的主键值 。
3.3 InnoDB File-Per-Table表空间采用 File-Per-Table 的优缺点如下: