新功能上線後主從同步報錯 Duplicate entry ... for key 'PRIMARY',Binlog 中 INT 類型 ID 被編碼為 ASCII 十六進制(如 0x3636333130393834)。排查發現:應用使用 Prepared Statement + GBK 多字節字符集,導致主從字符集轉換不一致,Binlog 記錄異常。
Last_SQL_Error: Error 'Duplicate entry
'66310984-2014-04-18 00:00:00--122815.sh' for key 'PRIMARY''
on query. Default database: 'bill'. Query: 'INSERT INTO `BOND3311`...
VALUES(0x373236313333373339, 0x3636333130393834, ...) -- ID 被編碼為十六進制
character_set_server、collation_server、表字符集、SQL_MODE、MySQL 版本 → 全一致Prepared Statement GBK binlog hex觸發條件雙重滿足時必現:
MySQL 在 Prepared Statement 參數綁定階段,對多字節字符集的參數進行轉義時,會將二進制數據以十六進制形式寫入 Binlog。從庫重放時若字符集上下文不一致,導致解析偏移,主鍵衝突。
# 1. 停止同步
STOP SLAVE;
# 2. 修改 Binlog 格式為 ROW(避免語句級轉義問題)
SET GLOBAL binlog_format=ROW; -- 或配置文件永久生效
# 3. 重新同步基線數據
-- 主庫:mysqldump --master-data=2 --single-transaction db > base.sql
-- 從庫:mysql db < base.sql
# 4. 重置從庫位點並啟動
RESET SLAVE;
CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.xxxxxx', MASTER_LOG_POS=xxx;
START SLAVE;
utf8mb4,棄用 GBKSeconds_Behind_Master 與 Last_SQL_Error,設置告警