已启用 innodb_file_per_table 时新建表有独立 .ibd 文件,否则数据存于 ibdata1;执行 select @@innodb_file_per_table 或 show variables like 'innodb_file_per_table' 查看,需在 [mysqld] 段配置文件中设置并重启才永久生效。

开启 innodb_file_per_table 后,每个 InnoDB 表才会真正拥有自己的 .ibd 文件;不开启时,所有表数据都挤在共享表空间 ibdata1 里,删表不释放磁盘空间。
怎么确认当前是否已启用 innodb_file_per_table
别猜,直接查。这个配置是动态的,但只对新建表生效,已有表不会自动迁移。
- 执行
SELECT @@innodb_file_per_table;—— 返回1表示已启用 - 或查全局变量:
SHOW VARIABLES LIKE 'innodb_file_per_table'; - 注意:即使变量显示为
ON,如果实例启动前没在配置文件里写死,重启后可能回退(尤其 MySQL 5.6 及更早版本)
在哪里设置才真正生效
必须写进 MySQL 配置文件(如 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf),且放在 [mysqld] 段下。
- 加这一行:
innodb_file_per_table = ON(MySQL 5.6+ 推荐用ON,旧版也支持1) - 改完必须重启 MySQL 实例,
SET GLOBAL动态设置仅影响后续新建表,且部分版本不支持动态修改该变量 - 不要写在
[client]或其他段里,无效
开了之后,老表不会自动拆出来
这是最常被忽略的一点:启用只是“从现在起”新表走独立表空间,已存在的表仍留在 ibdata1 中。
- 想让某张老表也独立,得重建它:
ALTER TABLE <code>your_tableENGINE=InnoDB; - 或者用
OPTIMIZE TABLE <code>your_table;(本质也是重建) - 重建过程会锁表(除非用 pt-online-schema-change 或 MySQL 5.6+ 的在线 DDL 支持)
- 重建后检查:
ls -lh /var/lib/mysql/your_db/,看到your_table.ibd才算成功
删表后磁盘空间没回来?可能卡在这几个地方
即使开了 innodb_file_per_table,删表不释放空间也常见,原因往往不是配置问题。
- 文件系统层没回收:Linux 下删除
.ibd后,若还有进程(比如 mysqld)正打开该文件,空间不会立刻返还 —— 重启 MySQL 或等其释放句柄 - 表被误删但
.ibd文件残留:手动删了.frm却忘了删.ibd,或反向操作,导致元数据和文件状态不一致 - 开启了
innodb_undo_log_truncate且 undo 表空间膨胀严重,实际占空间的是undo_001等文件,跟.ibd无关
真正麻烦的是混合使用场景:一部分表启用了独立表空间,另一部分还在 ibdata1;这时候 ibdata1 只能增长不能收缩,删再多独立表也没法缩小它。想彻底清理,只能导出、删库、重建、再导入。











