一次因爲字符集問題引起的MySQL主從同步不一致問題追查

 

近期業務準備上線一個新功能,灌入數據以後忽然發現主從同步中止,報錯以下:sql

Error 'Duplicate entry '66310984-2014-04-18 00:00:00--122815.sh' for key 'PRIMARY'' on query. Default database: 'bill'. Query: 'INSERT INTOBOND3311(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都多處字符集的影響,因此常常會有一些亂碼的狀況出現。搜索引擎

因而咱們先去檢查主庫的數據是否正常寫入,結果是正常的。而後根據以下結構:code

cline ——> master ——> slaveorm

既然主庫數據寫入正常,那麼只能懷疑在master和slave作replication的時候發生了字符的轉義,致使了上述狀況發生。咱們前後檢查了以下參數設置,所有都一致。server

  • 表字符集設置
  • server的字符集設置
  • 數據庫版本
  • sql mode

如此詭異的問題,只好求助萬能的搜索引擎了,最終找到以下這篇blog,解釋的很是清晰。按照blog中的解釋,這個問題發生的前提有2個:blog

  • 程序使用prepared statement
  • 字符集使用多字節字符集,好比GBK

根據博客中提供的解決方案,咱們先將同步停止,修改binlog format,而後將主庫的數據複製到從庫中保證數據一致性,在開啓同步,最終問題得以解決。索引

ps:如此詭異的問題,真是不遇到不知道,這纔是赤裸裸的經驗問題。get

相關文章
相關標籤/搜索