mysql 恢復備份時出現錯誤 1062 ‘duplicate entry’
抱歉,我看到了類似的執行緒,但我仍然找不到它解決我的問題,另外,我需要更多關於此的資訊。
**要求:**創建現有數據庫“db3”的精確副本“db4”。
遵循的程序:
- mysqldump -uuser -ppass db3 > db3.sql (大小為6G)
- mysql -uuser -ppass db4 < db3.sql (db4 是一個新創建的空白數據庫)
第二步拋出錯誤:
ERROR 1062 (23000) at line 5524: Duplicate entry '600806' for key 1"
我用 –force 再次執行了第二步。還原已完成,但出現 2 個額外的類似錯誤:
ERROR 1062 (23000) at line 6309: Duplicate entry '187694' for key 1 ERROR 1062 (23000) at line 6572: Duplicate entry '1567400' for key 1
完成後,當我查詢 db4 數據庫的某些表時,我能夠看到失去的記錄。
問題:
- 這是否表明 db3 數據庫已損壞/有問題?
- 如何繼續創建 db3 的“一致/工作”副本 (db4)?
謝謝,
出現此類“重複”的原因有多種:
- 你的數據是吐司。
- 使用自動增量插入的應用程序,但後來執行 UPDATE 以手動將身份修改為不同的,可能存在的值。這有時會發生在“按 ID”排序並希望“修復排序”(實際上打破一致性)的應用程序開發人員身上。
- 在插入非唯一記錄之後,後來添加“唯一”約束的人會發生第二個問題的變體。
錯誤消息確實引用了第一個鍵,在大多數數據庫模式中它是第一個值。查看原始轉儲輸出,尤其是 INSERT 語句並檢查
INSERT INTO ... values (0,...
掃描錯誤消息中給出的 mysql 轉儲的行號。
我期待什麼樣的mysqldump範例:
INSERT INTO foo (id,bar,baz) values (1,2,3); INSERT INTO foo (id,bar,baz) values (0,4,5); INSERT INTO foo (id,bar,baz) values (2,6,7);
在自動遞增欄位的“正常”插入語句中,值“0”指定自動遞增欄位,因此不應出現在使用自動遞增欄位的數據庫 SQL 轉儲中。通過 SQL 轉儲重新載入數據庫,您的轉儲要求 SQL 伺服器將目前欄位值加一併插入該 ID。如果有人在插入記錄後手動將身份更新為零,您的 MySQL Dump 也會包含這個奇怪的 id。
如果您將此轉儲重播到一個空表中,這將嘗試創建以下記錄:
1,2,3 2,4,5 2,6,7
由於“id”欄位已設置為唯一自動增量,第二個 INSERT 將創建與以下記錄衝突的“錯誤”記錄(預期:0,4,5;實際:2,4,5)(id=2 ) 並因此給出錯誤消息。
在一個變體中,有人“手動”將身份更新為已經存在的值,然後將記錄更改為“唯一”。將記錄類型更改為唯一不會使 MySQL 重新驗證目前數據是否符合要求,因此會出現延遲錯誤。這種變化可能會產生這樣的轉儲:
INSERT INTO foo (id,bar,baz) values (1,2,3); INSERT INTO foo (id,bar,baz) values (1,4,5); INSERT INTO foo (id,bar,baz) values (2,6,7);
由於唯一約束,嘗試插入第二行將失敗。
在這兩種情況下,使用“–force”只會忽略“衝突”行並繼續導入。“衝突”行將失去,但可能導致此衝突的行將存在(但 id 記錄錯誤)。
如果我的想法與您的問題相符,請檢查您的數據庫轉儲。如果是這種情況,這裡有兩種“讓它工作”的解決方法:
- 分兩步導入數據,首先只有模式,然後是數據。在導入數據之前從架構中刪除唯一約束,稍後再次添加唯一約束(“ALTER TABLE … add unique…”)。
- 強制導入模式和所有數據,導致“不同”約束問題。手動檢查哪些記錄是正確的,並將錯誤的記錄重新分配為其原始值。
後續問題的範例:
mysql -uuser -ppass --execute "SET UNIQUE_CHECKS=0; source db3.sql" db4
這確實會強制導入所有衝突的記錄,甚至違反任何真正的唯一約束。導入後,您將擁有這三個記錄(600806、187694 和 1567400)的多個條目,您必須通過檢查轉儲手動找出正確的條目,其中哪些“重複”確實導致衝突並手動將錯誤的記錄“回”更新為零(或轉儲中衝突行所說的任何內容)。
在這兩種情況下,您的數據仍然違反給定的架構:您的架構說數據是唯一的,但事實並非如此。從長遠來看,數據需要固定在應用程序級別。