還原 SQL 文件報錯 ERROR 1005 (HY000): Can't create table ... (errno: 121),核心原因是 **外鍵約束名稱在實例內必須唯一**,或系統表空間 ibdata1 被舊備份污染導致元數據衝突。
1005:無法創建表errno: 121:外鍵名稱重複(MySQL 內部錯誤碼映射)ERROR 1005: Can't create table 'xxx' (errno: 121 "Duplicate key on write or update")MySQL 要求 **外鍵名稱(constraint symbol)在全實例唯一**,不僅在表內。若兩張表定義了同名外鍵(如均為 fk_user_id),第二張表創建失敗。
-- 表 A
CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
-- 表 B(同庫/不同庫)
CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
-- 報錯 1005 errno 121
解決:外鍵命名加表前綴 fk_orders_user_id、fk_logs_user_id,或不顯式命名讓 MySQL 自動生成唯一名。
操作:新裝 MySQL → 用舊實例 ibdata1 覆蓋新 ibdata1 → 嘗試導入 SQL 還原數據 → 報錯 1005/其他元數據錯誤。
原因:ibdata1 存儲數據字典、Undo Log、雙寫緩衝、外鍵元數據。舊 ibdata1 含舊表定義、外鍵名稱,與新導入 SQL 定義衝突。
解決**:
ibdata1、ib_logfile*ibdata1)| 檢查點 | 命令/動作 |
|---|---|
| 外鍵名稱唯一性 | SELECT CONSTRAINT_NAME, TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY' GROUP BY CONSTRAINT_NAME HAVING COUNT(*)>1; |
| SQL 文件中是否重複定義同名外鍵 | grep -n "CONSTRAINT.*FOREIGN KEY" backup.sql | sort | uniq -d |
| ibdata1 是否為舊備份覆蓋 | 對比文件修改時間、大小;新實例應為自動生成的小文件(~12MB) |
| 目標庫是否殘留舊表 | DROP DATABASE IF EXISTS target_db; CREATE DATABASE target_db; 乾淨重建 |
| 字符集/排序規則一致 | 庫表 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
DROP DATABASE ...; CREATE DATABASE ... CHARSET=utf8mb4;fk_子表_父表_欄位,全局唯一「乾淨重建」比「排查修補」快十倍,錯誤 1005/121 九成源於「髒環境」。