InnoDB逻辑存储单元主要分(层级依次往下):

  1. 表空间 tablespace
  2. 段 segment
  3. 区 extent(64)
  4. 页 page

    表空间

    InnoDB存储引擎表中所有数据都是存储在表空间中的,表空间又分:
  • 系统表空间
  • 独立表空间
  • undo表空间
  • 临时表空间(5.7后)
  • 通用表空间(5.7后)

    系统表空间 ibdata1

    在安装数据库初始化数据时就是系统在创建一个ibdata1的表空间文件,它会存储所有数据的信息以及回滚段(undo)的信息
    数据库默认的ibdata1的大小是10MB,但是面对高并发事务时容易捉襟见肘,建议调整为1GB

    独立表空间

    设置参数 innodb_file_per_table=1 ,就可以把每张表的数据单独放到一个独立的表空间。目前mysql默认使用的都是独立表空间文件,其存储的是对应表的B+树数据、索引和插入缓冲等信息,其余信息还是存储在默认表空间中

    共享表空间和独立表空间的区别

  • 独立表空间

    • 优点:每个表都有自己的表空间,并且可以实现表空间的转移,可以使用alter table table_name engine=innodb或pt-online_schema_change命令就可以回收
    • 缺点:每个表文件都有.frm和.ibd文件两个文件描述符,如果单表增长过快容易出现性能问题
  • 共享表空间

    • 优点:数据和文件放在一起方便管理
    • 缺点:无法在线回收空间,如果想要回收,需要将全部InnoDB表中的数据备份、删除原表,然后再把数据导回到与原表结构一样的新表中。特别是统计分析、日志类系统不太适合使用共享表空间

      临时表空间

      mysql5.7把临时表的数据从系统表空间中抽离出来,形成自己的独立表空间参数innodb_temp_data_file_path,并把临时表的相关检索信息 保存在 系统信息表的information_schema库下的 innodb_temp_table_info表中。但目前还不能定义临时表空间文件的存放路径,只能与innodb_data_home_dir一致
      独立表空间文件名为 ibtmp1,默认大小为12MB

      通用表空间

      在生产中很少使用。多个表放在同一个表空间中,可以根据活跃度来划分表,存放在不同的磁盘上,可以减少metadata的存储开销

      表空间是由段组成的,也可以把一个表理解为一个段。通常有数据段、回滚段、索引段等。每个段由N个区和32个零散的页组成,段空间扩展是以区为单位进行扩展的。
      一般创建一个索引的同时就会创建2两个段,分别是非叶子节点和叶子节点段。而一个表的段数是索引个数的2倍

      区是由连续的页组成的,是物理上连续分配的一段空间,每个区的大小固定是1MB

      这是InnoDB的最小物理存储分配单位,一般一个区由64个连续的页组成,页默认大小是16KB
      从5.6开始就可以自定义调低页大小(8KB、4KB),从5.7开始可以调高页的大小(32KB、64KB)
      通常一个页会默认预留1/16的空间用户更新数据。且一个页最少可以存两行数据,虚拟最小行(infimum records)和虚拟最大行(infimum records)用于限定行记录的范围,以此来保证B+tree节点和双向链表结构

      页里面记录着行记录的信息,InnoDB存储引擎是面向列的,也就是数据是按照行存储的。行记录数据又是按照行格式进行存放的
      其中有两种文件格式,分别又对应四种行记录格式,table status中的row_format对应的就是表使用的行格式存储类型:
  • Antelope

    • compact(使用的最多)
    • redundnat
  • Barracuda
    • compressed
    • dynamic(5.7默认)

默认使用dynamic的原因是因为行溢出,行溢出就是需要存储的数据在当前存储页面之外,拆分到多个页进行存储。针对大数据类型text或blob存储在其字段中的数据,dynamic实际采用的数据都存放在溢出的页中(off-page),而数据页只存前20个字节的指针。而compact行格式下,溢出的列只存放768个前缀字节。
dynamic这种行记录格式针对溢出列所在的新页利用率会更高。