之前21年写过一篇MySQL的ibdata的文章,链接如下:
https://blog.youkuaiyun.com/db_murphy/article/details/119357309?spm=1001.2014.3001.5501
今天再来温故知新下。

ibdata 文件是InnoDB 存储引擎的核心系统表空间文件。InnoDB 存储元数据和数据,主要有:数据字典、Change Buffer、Doublewrite Buffer、Undo Logs、表数据等。
ibdata 文件(通常命名为 ibdata1,但可以有多个)是一个组合式的文件,主要负责存储以下内容:
1. 数据字典
这是最重要的元数据。它记录了所有InnoDB 表、列、索引的结构信息。例如,你创建了一个表 users,它的表结构、每个字段的类型、有哪些索引等信息都存储在数据字典里。没有这个,InnoDB 就无法知道如何找到和解读你的数据。
2. Change Buffer
中文常译为“变更缓冲区”。它是一种特殊的数据结构,用于缓存非唯一二级索引的变更(如 INSERT, DELETE, UPDATE)。当这些索引页不在内存中时,先将更改缓存到 Change Buffer,之后当索引页被加载到缓冲池时,再将这些更改合并进去。这样可以减少磁盘 I/O,提升写性能。
3. Doublewrite Buffer
中文常译为“双写缓冲区”。这是一个数据安全机制。InnoDB 在将数据页刷写到磁盘上的实际位置之前,会先将这些页写入双写缓冲区。如果发生意外断电或系统崩溃,导致只有部分页写入了磁盘(称为“部分页写入”),InnoDB 在恢复过程中可以通过双写缓冲区中的副本来修复损坏的页。这极大地保证了数据的完整性和一致性。
4. Undo Logs
中文常译为“撤销日志”。它存储了事务回滚和实现多版本并发控制(MVCC)所需的信息。当你执行 ROLLBACK 时,就需要用 Undo Log 来撤销更改。当其他事务需要读取某行数据的旧版本(以实现可重复读或读已提交的隔离级别)时,也是从 Undo Log 中获取。
5. 表数据(在某些配置下)
这取决于你的MySQL 配置。在默认配置 (innodb_file_per_table=OFF) 下,所有 InnoDB 表的数据和索引都会存储在共享的 ibdata 文件里。
在现代版本的MySQL(5.6+)中,默认配置是 innodb_file_per_table=ON。在这种配置下,每个 InnoDB 表会有自己独立的 .ibd 文件来存储该表的数据和索引。此时,ibdata 文件就主要存储上述 1-4 项内容,而不再存储用户表数据。
大家可能会遇到的问题:ibdata1 文件过大情况
这种情况通常发生在仍然使用共享表空间(innodb_file_per_table=OFF) 的旧系统上(如使用MySQL5.6)。
原因:因为所有表和索引的数据都塞进了ibdata1,这个文件会持续增长。而且,即使你删除了大量的表或数据,ibdata1 文件占用的磁盘空间也不会自动释放。 InnoDB 不会将删除后的空间返还给操作系统,它只会标记为可用,以便将来存储新的 InnoDB 数据。
如何释放空间?通常需要以下步骤:
1. 对所有数据库进行完整备份(使用 mysqldump)。
2. 停止 MySQL 服务。
3. 删除所有 ibdata 和 ib_logfile 文件。
4. 修改配置文件,确保 innodb_file_per_table=ON。
5. 启动 MySQL 服务。此时会生成新的、干净的 ibdata1 文件。
6. 从备份中恢复数据。
鉴于此,建议始终将innodb_file_per_table 设置为ON。 这样,每个表一个文件,当删除表 (DROP TABLE) 时,MySQL 可以直接删除对应的 .ibd 文件,空间会立即释放给操作系统。
文章小结
|
特性 |
说明 |
|
文件名 |
通常为 ibdata1,但可以通过配置增加 ibdata2, ibdata3 等。 |
|
核心角色 |
InnoDB 的系统表空间,是存储元数据和关键组件的中心仓库。 |
|
存储内容 |
数据字典、Change Buffer、Doublewrite Buffer、Undo Logs,以及(如果配置了)用户表和索引数据。 |
|
空间管理 |
一旦增长,无法自动收缩(即使删除数据)。要缩小它需要复杂的备份-重建-恢复操作。 |
|
最佳实践 |
始终设置 innodb_file_per_table=ON。这样用户数据会存储在独立的 .ibd 文件中,管理(备份、删除、迁移)起来更灵活,也避免了 ibdata1 无限膨胀的问题。 |
文章至此。
302

被折叠的 条评论
为什么被折叠?



