近期業務准備上線一個新功能,灌入數據之後突然發現主從同步停止,報錯如下:
Error 'Duplicate entry '66310984-2014-04-18 00:00:00--122815.sh' for key 'PRIMARY'' on query. Default database: 'bill'. Query: 'INSERT INTO
BOND3311
(OBJECTID
,BONDID
,BONDNAME
,DECLAREDATE
,F001D
,F002D
,F003N
,F004N
,F005D
,F006D
,F007D
,F008D
,MEMO
,RECTIME
,MODTIME
,ISVALID
,F009N
,SEQID
,SECNAME
,F010N
,F014V
,F011D
,F013N
,SECCODE
)VALUES(0x373236313333373339,0x3636333130393834,0x32303131C4EAD0C2BDAEB9E3BBE3CAB5D2B5CDB6D7CA28BCAFCDC529D3D0CFDED4F0C8CEB9ABCBBEB9ABCBBED5AEC8AF,'2014-04-14 00:00:00',NULL,NULL,0x352E3833,0x35382E33,'2014-04-18 00:00:00',NULL,NULL,NULL,0xBBD8CADBB2BFB7D6B6D2B8B6,'2014-04-14 13:48:56','2014-04-14 13:48:56',0x31,0x3230,0x31373430333831393837,0x3131B9E3BBE3D5AE,0x352E3833,0xB6D2B8B6,'2014-04-21 00:00:00',0x3130352E3833,0x3132323831352E7368)'
從報錯信息可以看到,很多ID(int類型)字段的values被轉換成了ASCII碼執行,這也就導致了同步的中斷。第一反應是字符集問題,由於MySQL的字符集設置有多個參數,而在使用中文的時候,字符集的轉換會受到cline,connection,server,table都多處字符集的影響,所以經常會有一些亂碼的情況出現。
於是我們先去檢查主庫的數據是否正常寫入,結果是正常的。然後根據如下結構:
cline ——> master ——> slave
既然主庫數據寫入正常,那麼只能懷疑在master和slave做replication的時候發生了字符的轉義,導致了上述情況發生。我們先後檢查了如下參數設置,全部都一致。
如此詭異的問題,只好求助萬能的搜索引擎了,最終找到如下這篇blog,解釋的非常清晰。按照blog中的解釋,這個問題發生的前提有2個:
根據博客中提供的解決方案,我們先將同步中止,修改binlog format,然後將主庫的數據復制到從庫中保證數據一致性,在開啟同步,最終問題得以解決。
ps:如此詭異的問題,真是不遇到不知道,這才是赤裸裸的經驗問題。