首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

InnoDB 共享表空間遷移至獨立表空間(innodb_file_per_table)完整操作

     編輯:MySQL 資料庫相關知識

MySQL 5.6 前預設 innodb_file_per_table=OFF,所有 InnoDB 表資料集中在 ibdata1,無法回收空間。遷移至獨立表空間(每表一個 .ibd)可單獨管理、支援 DROP TABLE 即時釋放磁碟。

1. 確認目前模式


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 → 共享表空間

2. 完整遷移步驟(停機方案,最穩妥)

  1. 停止 MySQL
    systemctl stop mysqld
  2. 修改配置(my.cnf [mysqld] 區塊)
    innodb_file_per_table = 1
  3. 備份所有 InnoDB 表
    mysqldump -u root -p --single-transaction --routines --triggers --databases db1 db2 > /backup/innodb_all.sql
  4. 刪除共享表空間與日誌
    cd /var/lib/mysql
    rm -f ibdata1 ib_logfile*
    rm -rf db1 db2 # 刪除原 InnoDB 資料庫目錄
  5. 啟動 MySQL(自動建立新 ibdata1、ib_logfile*)
    systemctl start mysqld
  6. 還原資料
    mysql -u root -p < /backup/innodb_all.sql
  7. 驗證
    mysql> SHOW VARIABLES LIKE 'innodb_file_per_table'; -- ON
    ls -lh /var/lib/mysql/db1/ -- 出現 .ibd 檔案

3. 為什麼必須刪除 ibdata1 與資料庫目錄?

  • 啟用 innodb_file_per_table=ON 後,MySQL 仍會讀取舊 ibdata1 的資料字典,若不刪除會報錯:
    InnoDB: Cannot initialize created log files because data files are corrupt...
  • 重建 ibdata1 才能獲得乾淨的共享表空間(僅存系統資料字典、undo log、臨時表等),用戶表資料全部走 .ibd。

4. 線上遷移方案(不停機,適合大表)


-- 單表線上遷移
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(需停機)。

5. 遷移後收益

  • DROP TABLE / TRUNCATE 瞬間釋放磁碟空間。
  • 可對單表執行 OPTIMIZE TABLE 整理碎片。
  • 備份/還原單表更靈活(複製 .ibd + IMPORT TABLESPACE)。
  • ibdata1 體積大幅縮小,不再無限增長。

建議:新建實例直接設 innodb_file_per_table=ON;存量系統按上述停機窗口遷移一次即可。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved