MySQL

洞悉MySQL底层架构与SQL调优本质
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

InnoDB执行引擎内幕:表空间

发布于 2020-05-30 | 更新于 2024-05-16

一个InnoDB表及其索引可以在建在系统表空间中,或者是在一个 独立表空间 中,或在 通用表空间

表空间概览图:

image-20200523161854294

表空间涉及的文件

相关文件默认在磁盘中的innodb_data_home_dir目录下:

1
2
3
4
5
6
|- ibdata1  // 系统表空间文件
|- ibtmp1 // 默认临时表空间文件,可通过innodb_temp_data_file_path属性指定文件位置
|- test/ // 数据库文件夹
|- db.opt // test数据库配置文件,包含数据库字符集属性
|- t.frm // 数据表元数据文件,不管是使用独立表空间还是系统表空间,每个表都对应有一个
|- t.ibd // 数据库表独立表空间文件,如果使用的是独立表空间,则一个表对应一个ibd文件,否则保存在系统表空间文件中

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个字节,前缀索引也同样适用;
  • 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


  1. 14.6.3.3 General Tablespaces. Retrieved from https://dev.mysql.com/doc/refman/5.7/en/general-tablespaces.html ↩︎

  2. MYSQL INNODB表压缩. (2018-03-09). Retrieved from https://cloud.tencent.com/developer/article/1056453 ↩︎

  3. 前缀索引,一种优化索引大小的解决方案. (2015-03-03). Retrieved from https://www.cnblogs.com/studyzy/p/4310653.html ↩︎

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/mysql/innodb/tablespace.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。