一个InnoDB
表及其索引可以在建在系统表空间中,或者是在一个 独立表空间 中,或在 通用表空间。
- 当
innodb_file_per_table
启用时,通常是将表存放在独立表空间中,这是默认配置; - 当
innodb_file_per_table
禁用时,则会在系统表空间中创建表; - 要在通用表空间中创建表,请使用
CREATE TABLE ... TABLESPACE
语法。有关更多信息,请参见官方文档 14.6.3.3 General Tablespaces。
表空间概览图:
表空间涉及的文件
相关文件默认在磁盘中的innodb_data_home_dir
目录下:
1 | |- ibdata1 // 系统表空间文件 |
frm文件
创建一个InnoDB
表时,MySQL 在数据库目录中创建一个.frm文件。frm文件包含MySQL表的元数据(如表定义)。每个InnoDB表都有一个.frm文件。
与其他MySQL存储引擎不同, InnoDB
它还在系统表空间
内的自身内部数据字典中编码有关表的信息。MySQL删除表或数据库时,将删除一个或多个.frm
文件以及InnoDB
数据字典中的相应条目。
因此,在InnoDB中,您不能仅通过移动.frm
文件来移动表。有关移动InnoDB
表的信息,请参见官方文档14.6.1.4 Moving or Copying InnoDB Tables。
ibd文件
对于在独立表空间创建的表,还会在数据库目录中生成一个 .ibd表空间文件。
在通用表空间
中创建的表在现有的常规表空间 .ibd文件中创建。常规表空间文件可以在MySQL数据目录内部或外部创建。有关更多信息,请参见官方文档14.6.3.3 General Tablespaces。
ibdata文件
系统表空间文件,在 InnoDB
系统表空间中创建的表在ibdata中创建。
1、系统表空间
系统表空间由一个或多个数据文件(ibdata文件)组成。其中包含与InnoDB
相关对象有关的元数据(InnoDB
数据字典 data dictionary),以及更改缓冲区(change buffer), 双写缓冲区(doublewrite buffer)和撤消日志(undo logs)的存储区 。
InnoDB
如果表是在系统表空间中创建的,则系统表空间中也包含表的表数据和索引数据。
系统表空间的问题
在MySQL 5.6.7之前,默认设置是将所有InnoDB
表和索引保留 在系统表空间内,这通常会导致该文件变得非常大。因为系统表空间永远不会缩小,所以如果先加载然后删除大量临时数据,则可能会出现存储问题。
在MySQL 5.7中,默认设置为 独立表空间模式,其中每个表及其相关索引存储在单独的 .ibd文件中。此默认设置使使用**Barracuda文件格式的InnoDB
功能更容易使用,例如表压缩**,页外列的有效存储以及大索引键前缀(innodb_large_prefix
)。
将所有表数据保留在系统表空间或单独的 .ibd
文件中通常会对存储管理产生影响。
InnoDB
在MySQL 5.7.6中引入了通用表空间[1],这些表空间也由.ibd
文件表示 。通用表空间是使用CREATE TABLESPACE
语法创建的共享表空间。它们可以在MySQL数据目录之外创建,能够容纳多个表,并支持所有行格式的表。
2、独立表空间
MySQL 5.7中,配置参数:innodb_file_per_table
,默认处于启用状态,这是一个重要的配置选项,会影响InnoDB
文件存储,功能的可用性和I/O特性等。
启用之后,每个表的数据和索引是存放在单独的.ibd文件中的,而不是在系统表空间的共享ibdata文件中。
优点
- 您可以更加灵活的选择
数据压缩
[2]的行格式,如:- 默认情况下(innodb_page_size=16K),
前缀索引
[3]最多包含768个字节。如果开启innodb_large_prefix,且Innodb表的存储行格式为 DYNAMIC 或 COMPRESSED,则前缀索引最多可包含3072个字节,前缀索引也同样适用;
- 默认情况下(innodb_page_size=16K),
TRUNCATE TABLE
执行的更快,并且回收的空间不会继续保留,而是让操作系统使用;- 可以在单独的存储设备上创建每表文件表空间数据文件,以进行I / O优化,空间管理或备份。请参见 14.6.1.2 Creating Tables Externally;
缺点
- 独立表空间中的未使用空间只能由同一个表使用,如果管理不当,会造成空间浪费;
- 多个表需要刷盘,只能执行多次fsync,无法合并多个表的写操作,这可能会导致更多的fsync操作总数;
- mysqld必须为每个表文件空间保留一个打开的文件句柄,如果表数量多,可能会影响性能;
- 每个表都需要自己的数据文件,需要更多的文件描述符;
即使启用了innodb_file_per_table参数,每张表空间存放的只是数据、索引和插入缓存Bitmap页,其他数据如回滚信息、插入缓冲索引页、系统事务信息、二次写缓冲等还是存放在原来的共享表空间中。
3、通用表空间
通用表空间使用CREATE TABLESPACE
语法创建。
类似于系统表空间,通用表空间是共享表空间,可以存储多个表的数据。
通用表空间比独立表空间具有潜在的内存优势,服务器在表空间的生存期内将表空间元数据保留在内存中。一个通用表空间通常可以存放多个表数据,消耗更少的表空间元数据内存。
数据文件可以放置在MySQL数据目录或独立于MySQL数据目录。
4、undo表空间
undo表空间包含undo log。
innodb_rollback_segments
变量定义分配给每个撤消表空间的回滚段的数量。
undo log可以存储在一个或多个undo表空间中,而不是系统表空间中。
在默认配置中,撤消日志位于系统表空间中。SSD存储更适合undo log的I/O模式,为此,可以把undo log存放在有别于系统表空间的ssd硬盘中。
innodb_undo_tablespaces
配置选项控制undo表空间的数量。
5、临时表空间
由用户创建的非压缩临时表和磁盘内部临时表是在共享临时表空间中创建的。
innodb_temp_data_file_path
配置选项指定零时表空间文件的路径,如果未指定,则默认在 innodb_data_home_dir
目录中创建一个略大于12MB 的自动扩展数据文件ibtmp1
。
使用ROW_FORMAT=COMPRESSED
属性创建的压缩临时表,是在独立表空间中的临时文件目录中创建的 。
服务启动的时候创建临时表空间,关闭的时候销毁临时表空间。如果临时表空间创建失败,则意味着服务启动失败。
References
14.6.3.3 General Tablespaces. Retrieved from https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html ↩︎
MYSQL INNODB表压缩. (2018-03-09). Retrieved from https://cloud.tencent.com/developer/article/1056453 ↩︎
前缀索引,一种优化索引大小的解决方案. (2015-03-03). Retrieved from https://www.cnblogs.com/studyzy/p/4310653.html ↩︎