通过SHOW TABLE STATUS查看Data_length和Data_free是否变化,结合SHOW VARIABLES LIKE 'innodb_file_per_table'判断:ON且值动态变化为独立表空间,OFF或所有表数据均在ibdata1中则为系统表空间。

怎么判断当前表用的是独立表空间还是系统表空间
InnoDB 默认开启 innodb_file_per_table(MySQL 5.6.6+),但老库或手动关过就可能还在共享表空间(ibdata1)。别猜,直接查:SHOW TABLE STATUS LIKE 'your_table_name',看 Engine 是 InnoDB 后,重点盯 Data_length 和 Data_free —— 如果值明显不为 0 且随数据增减变化,基本是独立表空间;如果所有 InnoDB 表的 Data_length 都“挤”在 ibdata1 里,SHOW VARIABLES LIKE 'innodb_file_per_table' 返回 OFF 就坐实了。
MyISAM 完全没这问题:每个表固定对应 .MYD(数据)和 .MYI(索引)两个文件,一目了然。
迁移已有表到独立表空间要重做,不是改个配置就行
innodb_file_per_table=ON 只对新创建的表生效。老表即使配置开了,仍躺在 ibdata1 里。想搬出来,必须重建:
-
ALTER TABLE your_table ENGINE=InnoDB;—— 最常用,会锁表(Online DDL 在 5.6+ 支持部分场景,但ALGORITHM=INPLACE不保证一定不锁读) -
mysqldump导出再导入 —— 适合低峰期,但耗时长、需额外磁盘空间
注意:迁移后原 ibdata1 不会自动缩小,它只增不减。想真正释放空间,只能停库、导出全部数据、删掉 ibdata1、重启、再导入 —— 生产环境慎用。
MyISAM 的 .MYD/.MYI 文件能直接 mv,InnoDB 的 .ibd 不行
MyISAM 表文件是自包含的,只要 MySQL 没在用,mv /var/lib/mysql/db/t1.MYD /backup/ 安全;恢复时复制回来、FLUSH TABLES 就行。InnoDB 的 .ibd 文件不能这么干 —— 它和内存中的 buffer pool、redo log、数据字典强耦合。
真要移动 InnoDB 表文件,必须走正规流程:
-
ALTER TABLE t1 DISCARD TABLESPACE;(先清掉内存里的元数据映射) - 把
t1.ibd移到目标位置 -
ALTER TABLE t1 IMPORT TABLESPACE;(校验页 checksum、重建内存映射)
漏一步就会报错 Tablespace is missing for table 'db/t1' 或 Failed to open table。
独立表空间下 DROP TABLE 会立刻释放磁盘空间,MyISAM 也是,但共享表空间不会
这是最常被忽略的运维差异。开 innodb_file_per_table=ON 时,DROP TABLE t1 直接删掉 t1.ibd,磁盘空间秒还。MyISAM 同理,删 .MYD/.MYI 就完事。
但如果表还在 ibdata1 里(即 innodb_file_per_table=OFF),DROP TABLE 只清理数据字典和 ibdata1 内部的页标记,文件体积完全不变。你看着表没了,ibdata1 还是那么大 —— 这就是为什么线上库 ibdata1 越跑越大却没法收缩。
所以,别只看配置开关,得确认表实际落在哪;删表前先 ls -lh 看看对应文件是否存在,比查文档更快定位问题。


















