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

MySQL 主從複製報錯 1062 Duplicate Entry 深度排查與處理實戰

     編輯:MySQL 資料庫相關知識

線上從庫報錯 Last_Errno: 1062、Last_Error: Duplicate entry ... for key 'PRIMARY',SQL 執行緒停止。本文記錄一次完整的排查過程:從錯誤現場到 Binlog 對比、從 Relay Log 到主庫驗證,最終採用跳過錯誤恢復同步,並分析根因與預防措施。

一、錯誤現場還原

SHOW SLAVE STATUS\G
# 關鍵輸出
Slave_SQL_Running: No
Last_Errno: 1062
Last_Error: Error 'Duplicate entry '250.1.1-rding-changelogs/myIDENTITY/250/xxxx.xml' for key 'PRIMARY'' 
  on query: INSERT INTO `DATABASECHANGELOG` ...

表結構顯示主鍵為 PRIMARY KEY (ID, AUTHOR, FILENAME),複合主鍵設計非標準單一自增 ID。

二、資料現狀對比

1. 從庫已存在記錄

SELECT * FROM DATABASECHANGELOG WHERE AUTHOR='rding';
# 返回兩條記錄,包含衝突的 250.1.1

2. 主庫 Binlog 分析

解析 Relay_Master_Log_File: mysql-bin.000152,僅發現 一條 插入 250.1.1 的 INSERT 語句。

3. 從庫 Relay Log 分析

解析 Relay_Log_File: mysql-relay-bin.000455,同樣只有 一條 對應 INSERT。

4. 時間戳差異發現

節點DATEEXECUTED
從庫2013-08-12 20:41:22
主庫2013-08-12 19:54:29

從庫寫入時間比主庫晚約 47 分鐘,說明該記錄在從庫 已經存在,且非由當前 Binlog 事件產生。

三、深度排查:從庫 Binlog 回溯

解析從庫近期 5 個 Binlog (mysql-bin.004268~004272),均無 針對該記錄的 INSERT 操作。第 4 個 Binlog 解析報錯 ERROR: Error in Log_event::read_log_event(): 'read error', data_len: 438, event_type: 2(後續單獨分析)。

四、根因推斷

  1. 應用層重複提交:開發端網頁提交卡頓,用戶連點兩次,導致應用在短時間內發送兩次相同 INSERT。
  2. 從庫先行寫入:第一次提交在從庫成功寫入(時間 20:41:22),主庫 Binlog 記錄較早(19:54:29),可能存在時鐘不同步或複制延遲導致時間倒序。
  3. 第二次提交到達主庫:主庫執行第二次 INSERT,生成 Binlog 事件傳遞至從庫。
  4. 從庫重放報錯:從庫重放時發現主鍵衝突,SQL 執行緒停止。

五、緊急恢復與後續驗證

STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
SHOW SLAVE STATUS\G
# Slave_SQL_Running: Yes, Seconds_Behind_Master: 3434734 (大量延遲需追趕)

跳過錯誤後同步恢復,但需關注追趕進度與資料一致性。

六、預防與最佳實踐

  • 應用層去重:提交按鈕點擊後立即置灰/禁用,防止重複提交(本案例最終採用方案)。
  • 資料庫層約束:表設計應包含業務唯一鍵,配合 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE 實現冪等寫入。
  • 監控告警:部署從庫延遲、SQL 執行緒狀態監控,第一時間發現中斷。
  • 時間同步:所有 DB 節點強制 NTP 同步,避免時間戳倒序干擾排查。

核心教訓:資料層面的 SQL 萬萬不能輕易動,應從應用源頭解決重複提交問題。

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