Debian-Lenny

mysql 恢復備份時出現錯誤 1062 ‘duplicate entry’

  • September 23, 2015

抱歉,我看到了類似的執行緒,但我仍然找不到它解決我的問題,另外,我需要更多關於此的資訊。

**要求:**創建現有數據庫“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 數據庫的某些表時,我能夠看到失去的記錄。

問題:

  1. 這是否表明 db3 數據庫已損壞/有問題?
  2. 如何繼續創建 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)的多個條目,您必須通過檢查轉儲手動找出正確的條目,其中哪些“重複”確實導致衝突並手動將錯誤的記錄“回”更新為零(或轉儲中衝突行所說的任何內容)。

在這兩種情況下,您的數據仍然違反給定的架構:您的架構說數據是唯一的,但事實並非如此。從長遠來看,數據需要固定在應用程序級別。

引用自:https://serverfault.com/questions/462682