你在配置文件中使用innodb_data_file_path配置项指定的数据文件组成了InnoDB系统表空间。这些文件在逻辑上连接起构成了系统表空间。没有使用任何条带。你不能把你的表存储在系统表空间中的指定位置。在一个新创建的系统表空间中,InnoDB从第一个数据文件开始分配空间。
没有使用任何条带(There is no striping in use),应该结合前后文来理解,是指不能指定表在表空间内的存储位置,使得表空间内 存储空间 和 空闲空间 间隔分布,像条纹一样。
要避免将所有表和索引存储在系统表空间中带来的问题,你可以启用innodb_file_per_table设置项(默认),这会将每一个新创建的表存储在独立的表空间文件中(文件扩展名是.idb)。对采用这种存储方式的表来说,磁盘空间中的碎片更少,在表空间被清空后,空间会被返还给操作系统而不是被InnoDB保留在系统表空间中。想了解更多信息,请查看15.6.3.2,“独立表空间”。
你也可以将表存储在通用表空间中。通用表空间时使用CREATE TABLESPACE语法创建的共享表空间。它们可以被创建在MySQL数据目录之下,可以容纳多张表,可以支持所有行记录格式的表。想了解更多信息,请查看15.6.3.3,“通用表空间”。
页,区,段,和表空间 #
每一个表空间都由数据库页面组成。MySQL实例中的每一个表空间,页面大小都相同。默认情况下,所有的表空间的页大小是16KB,你可以在创建MySQL实例时指定innodb_page_size选项来将页面大小降低到8KB或4KB。想了解更多信息,请查阅文档中关于innodb_page_size的部分。
多个不大于16KB的页面组成了1MB大小的区(extent)(64个连续的16KB页面,或128个8KB页面,或256个4KB页面)。对于32KB大小的页面,一个区的大小是2MB。对于32KB大小的页面,区的大小是2MB。对于64KB大小的页面,区的大小是4MB。表空间中的文件在InnoDB中被称为“段”(segment)。(这些段和回滚段不同,后者实际上包含很多表空间段。)
当一个段在表空间内增长时,InnoDB会一次性分配前32个页面给它。之后,InnoDB会开始分配这个段的所有区。为了保证数据的连续性,InnoDB可以一次性给一个大段分配4个区。
在InnoDB中,会为每个索引分配两个段。一个是存储B+树的非叶子节点,另一个是存储叶子节点。让叶子节点在磁盘上连续存储可以提供更好的连续I/O操作,因为这些叶子节点中包含实际的表数据。
表空间中的一些页面存有其它页面的位图,所以表空间中的一部分区不能被整体分配给段,只能作为独立页面分配。
当你从一张表中删除数据时,InnoDB会收缩相应的B+树索引。被释放的空间是否对其它用户可用,取决于删除操作是否会将相关页面和区归还给表空间。删除一张表或删除表中的所有记录会确保将空间释放供其它用户使用。但是不要忘了,被删除的记录只有在purge操作时才会被物理删除,而purge操作会在不被事务回滚或一致性读需要之后一段时间自动发生。(见15.3,“InnoDB的多版本”。)
设置保留文件段的比例 #
MySQL8.0.26中引入的innodb_segment_reserve_factor变量,是一个高级特性,它允许定义表空间文件段保留的空页面比例。为了未来的增长保留一定比例的页面,这样B+树中的页面就可以连续分配。可以修改保留页面的比例,使得InnoDB可以为了解决数据碎片或存储空间无法高效使用的问题进行调优。
这个设置可用于独立表空间和通用表空间。innodb_segment_reserve_factor默认设置值是12.5(%),这个比例和上一次MySQL释放时保留的页面比例相同。
innodb_segment_reserve_factor变量是动态的,可以使用set语句设置。例如:
mysql> SET GLOBAL innodb_segment_reserve_factor=10;
页怎样和表记录关联 #
在innodb_page_size大小是4KB,8KB,16KB,和32KB时,每条记录的最大长度比一个数据页大小的1/2略小。例如,对于默认的16KB页面,一条记录的空间最大值比8KB略小。对于64KB大小的页,一条记录的空间最大值比16KB略小。
如果一条记录没有超出最大记录大小,所有的数据都存储在页面内。如果一条记录超出了大小上限,变长字段会被存储在外部页面中,直到记录大小降低到上限以下。
对于变长字段,行格式不同,外部页面存储页不同:
COMPACT和REDUNDANT格式 当一个变长字段被选择做外部页面存储时,InnoDB会将前768个字节存储在页面内,将其余部分存储到外部溢出页面中。每一个这种列都有自己的溢出页面列表。和768字节的前缀相伴的是用来存储列真实长度和指定溢出数据存储地址的指针的20字节。见15.10,“InnoDB记录格式”。
DYNAMIC和COMPRESSED格式 当一个变长字段被选择做外部页面存储时,InnoDB会在记录内存储20字节大小的指针,剩余部分被存储在外部溢出页中。见15.10,“InnoDB记录格式”。
LONGBLOB和LONGTEXT列大小必须必小于4GB,记录的总长度(包括BLOB和TEXT列),必须比4GB小。