InnoDB 系統表空間 (`ibdata1`) 維護全局 `space_id` 計數器。每個獨立表空間 (`.ibd`) 創建時分配一個唯一 `space_id` 並寫入文件頭。**源庫 `.ibd` 的 `space_id` 必須等於目標庫該表的 `space_id`,否則 `IMPORT` 失敗報錯**:
ERROR 1030 (HY000): Got error -1 from storage engine
-- 錯誤日志:
InnoDB: tablespace id in file './db/t.ibd' is 2428, but in the InnoDB data dictionary they are 2430
-- 1. 目標庫建表 (結構完全一致)
CREATE TABLE sysUser (...) ENGINE=InnoDB;
-- 2. 目標庫丟棄表空間 (產生新 space_id 佔位)
ALTER TABLE sysUser DISCARD TABLESPACE;
-- 3. 複製源庫 .ibd 文件到目標庫數據目錄
scp src:/var/lib/mysql/db/sysUser.ibd dst:/var/lib/mysql/db/
-- 4. 修改文件擁有者
chown mysql:mysql /var/lib/mysql/db/sysUser.ibd
-- 5. 目標庫導入表空間
ALTER TABLE sysUser IMPORT TABLESPACE;
-- Query OK, 0 rows affected (0.05 sec) <-- 秒級完成億級遷移
目標庫 `space_id` 已經更大,需**將目標庫 `space_id` 推進到源庫 `space_id` 以上**。
方法:批量創建/刪除臨時表消耗 Space ID
#!/usr/bin/env python
# 消耗 Space ID 腳本
import MySQLdb
conn = MySQLdb.connect(host='dst', user='root', passwd='xxx', db='db_test', charset='utf8')
cursor = conn.cursor()
# 計算差值:源 2428, 目標 2430 -> 已經超過,無需操作
# 若源 44132, 目標 2436 -> 需消耗 44132 - 2436 = 41696 個 ID
# 安全起見少消耗幾個,留餘量手動補齊
target_consume = 41690
for i in range(target_consume):
cursor.execute("CREATE TABLE tmp_%d (id INT) ENGINE=InnoDB" % i)
cursor.execute("DROP TABLE tmp_%d" % i)
if i % 1000 == 0: print("Consumed %d" % i)
conn.close()
執行後,**重新執行標準流程 1-5 步** (目標庫重建表 → DISCARD → 複製 → IMPORT)。
同理,在目標庫消耗 ID 直到超過源庫。
**MySQL 5.6 引入 `.cfg` 元數據文件**,`FLUSH TABLES ... FOR EXPORT` 生成 `.cfg`,`IMPORT TABLESPACE` 時通過 `.cfg` 驗證結構兼容性,**不再強制要求 Space ID 一致**,極大簡化遷移。
-- 源庫 (5.6+)
FLUSH TABLES sysUser FOR EXPORT; -- 生成 sysUser.cfg
-- 複製 .ibd 和 .cfg 到目標庫
-- 目標庫
ALTER TABLE sysUser IMPORT TABLESPACE; -- 直接成功
| 風險 | 說明 | 緩解 |
|---|---|---|
| 頁校驗和損壞 | 文件複製過程/源庫本身有壞頁,導入後數據不可讀 | 源庫先 `CHECK TABLE` / `innochecksum` 驗證 |
| 數據字典不一致 | 表結構微小差異 (默認值、字符集、列順序) 導致導入後數據邏輯錯誤 | 嚴格保證 `SHOW CREATE TABLE` 完全一致 |
| 事務一致性 | `DISCARD` 瞬間進行中的事務數據可能丟失/不一致 | 源庫鎖表 `FLUSH TABLES sysUser WITH READ LOCK` 再複製 (影響業務) |
| 版本/架構不兼容 | 5.5→5.6、32bit→64bit、大端→小端 不支持 | 同版本同架構 |
| 外鍵約束 | 有外鍵的表無法 DISCARD/IMPORT | 遷移前刪除外鍵,遷移後重建 |
InnoDB 表空間傳輸 (TST) 通過 `DISCARD/IMPORT TABLESPACE` 實現物理級秒級遷移大表,**核心難點在於 Space ID 匹配** (5.5 需手動消耗 ID,5.6+ `.cfg` 機制解決)。**風險較高 (頁損壞、字典不一致、事務一致性)**,**生產環境非不得已首選成熟備份工具**。理解原理有助於排查遷移故障,實戰謹慎使用。