MySQL 5.6 前預設 innodb_file_per_table=OFF,所有 InnoDB 表資料集中在 ibdata1,無法回收空間。遷移至獨立表空間(每表一個 .ibd)可單獨管理、支援 DROP TABLE 即時釋放磁碟。
mysql> SHOW VARIABLES LIKE 'innodb_file_per_table';
+-----------------------+-------+
| Variable_name | Value |
+-----------------------+-------+
| innodb_file_per_table | OFF |
+-----------------------+-------+
-- 檔案系統驗證
ls -lh /var/lib/mysql/your_db/
# 僅有 .frm,無 .ibd → 共享表空間
systemctl stop mysqldmy.cnf [mysqld] 區塊)innodb_file_per_table = 1mysqldump -u root -p --single-transaction --routines --triggers --databases db1 db2 > /backup/innodb_all.sqlcd /var/lib/mysqlrm -f ibdata1 ib_logfile*rm -rf db1 db2 # 刪除原 InnoDB 資料庫目錄systemctl start mysqldmysql -u root -p < /backup/innodb_all.sqlmysql> SHOW VARIABLES LIKE 'innodb_file_per_table'; -- ONls -lh /var/lib/mysql/db1/ -- 出現 .ibd 檔案innodb_file_per_table=ON 後,MySQL 仍會讀取舊 ibdata1 的資料字典,若不刪除會報錯:InnoDB: Cannot initialize created log files because data files are corrupt...ibdata1 才能獲得乾淨的共享表空間(僅存系統資料字典、undo log、臨時表等),用戶表資料全部走 .ibd。
-- 單表線上遷移
ALTER TABLE `big_table` ENGINE=InnoDB; -- 觸發重建,生成 .ibd
-- 或使用 pt-online-schema-change 避免鎖表
pt-online-schema-change --alter "ENGINE=InnoDB" D=db,t=big_table --execute
逐表執行,完成後再清理 ibdata1(需停機)。
DROP TABLE / TRUNCATE 瞬間釋放磁碟空間。OPTIMIZE TABLE 整理碎片。.ibd + IMPORT TABLESPACE)。ibdata1 體積大幅縮小,不再無限增長。建議:新建實例直接設 innodb_file_per_table=ON;存量系統按上述停機窗口遷移一次即可。