溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

MySQL案例-奇怪的duplicate primary

發(fā)布時間:2020-08-11 09:20:45 來源:ITPUB博客 閱讀:208 作者:wangwenan6 欄目:MySQL數(shù)據(jù)庫
-------------------------------------------------------------------------------------------------記錄文---------------------------------------------------------------------------------------------------------------

結論先行: 最終只是解決了這個問題, 沒有找到根本的原因, 本文只有針對這個問題的分析和思考;
現(xiàn)象:
在Master-5.0.X與Slave-5.7.17進行同步的時候, slave worker拋出了一個錯誤, duplicate primary;
錯誤信息如圖:
MySQL案例-奇怪的duplicate primary

分析:
看上去是個很正常的報錯, 主鍵重復, 出現(xiàn)這個這個問題的可能性有不少, 不過這次的問題比較蹊蹺,
因為這個slave是用mydumper新做的, 剛開始同步幾條數(shù)據(jù)就報錯, 有點奇怪;

看了一眼表的數(shù)據(jù), pk=13的記錄確實存在, 那么久看看relaylog, 找一下完整的語句;
找到這個語句以后, 發(fā)現(xiàn)事情有點不對(ノへ ̄、)
MySQL案例-奇怪的duplicate primary

由于使用了auto_increment作為主鍵, binlog會在記錄這類語句的時候在binlog的statement之前注明主鍵的具體值;
從binlog的內(nèi)容來看, 這個語句明顯不應該是插入pk=13的記錄, 應該是91391才對;

那么如果從Master把這條數(shù)據(jù)單獨導出來, 直接手動導入的話, 跳過這個錯誤, 也是能解決問題;
看了一眼relaylog, 到導出數(shù)據(jù)的時候, 都沒有再對這條數(shù)據(jù)進行修改, let's go~
PS: 因為Master的寫入很少, 所以才能這么干, 繁重業(yè)務的話, 就跳過這種辦法吧...

為了保險起見, 新建了一個測試庫, 先試一下這么導數(shù)據(jù)會不會有問題;
MySQL案例-奇怪的duplicate primary

把數(shù)據(jù)導進去看看;
MySQL案例-奇怪的duplicate primary

導入沒有問題, 而且數(shù)據(jù)內(nèi)容也ok, 那么把數(shù)據(jù)往同步的庫里面導入試試.......

MySQL案例-奇怪的duplicate primary

(ノへ ̄、)看樣子同步報錯并不是意外.....

后來還陸陸續(xù)續(xù)做過以下嘗試:
懷疑表有問題, 畢竟從5.0.X的庫導入到5.7.17, 所以嘗試了: alter表; mysql_upgrade; 檢查auto_increament的值;
懷疑使用了假的relaylogㄟ( ▔, ▔ )ㄏ : 重新做同步;
語句有問題(╯‵□′)╯︵┻━┻  : 從已經(jīng)有這條數(shù)據(jù)的測試庫直接用insert...select來插入數(shù)據(jù); 
MySQL案例-奇怪的duplicate primary

全部都沒有用~

最后才把疑點放到這張表的觸發(fā)器上;
這個觸發(fā)器是用來做表字符集轉(zhuǎn)換的, 以前在別的數(shù)據(jù)庫中也用到過,這次報錯的信息也不是觸發(fā)器的內(nèi)容,按道理來說應該是沒啥問題的;
不過除了觸發(fā)器, 好像真沒有什么有可能會出問題的地方了, 試著刪了這個觸發(fā)器之后, 發(fā)現(xiàn)一切正常了......

最后的解決方法就只能刪了所有的觸發(fā)器;

思考:
首先遇到這個問題的時候, 去查了relaylog, 第一時間的猜測是binlog的問題或者是表的問題,
因為從報錯信息里面可以看出來, sql_thread在重演這一條語句的時候, 認為pk=13, 但是binlog里面記錄的明顯是91391;
那么就有可能是sql_thread在這一塊event的時候, 沒有認出來這個insert_id=91391的信息, 直接忽略掉了(雖然binlog都是v4, 但是天知道有什么bug不是..),
用了系統(tǒng)自己的auto_increament計數(shù)值(因為Master的寫入量很少, 考慮到13這個值也不大, 所以產(chǎn)生這種猜測);

所以檢查了表的auto_increament值, 也嘗試了mysql_upgrade和alter重建表, 但是都沒用;

之后發(fā)現(xiàn)binlog是statement, 這個語句并沒有把所有列的值進行顯式的賦值, 而且和后面的另外一條語句組成了一個事務,
如果把完整的信息都列出來, 或者把這個語句拆出來做成一個單獨的事務, 是不是就沒問題了?
所以之后單獨把那一行數(shù)據(jù)導出來, 再嘗試插入到表里面, 不管是source sql文件還是insert...select也不行;
從這幾次嘗試之后, 基本也能判斷不是SQL的問題了;

最后才把注意力放到觸發(fā)器上面, 這是測試表和業(yè)務表唯一的區(qū)別, 但是報錯里面的信息完全和觸發(fā)器沒關系;
不過在這次出問題的表上, 還是有一些端倪顯示出觸發(fā)器可能有問題, 那就是表自己記錄的auto_increament值,
表里面的最大值是91390, 插入失敗的數(shù)據(jù)是91391, 表中記錄的auto_increament是91392;
但是發(fā)現(xiàn)自己對這方面的了解不多, 也沒辦法確定這個auto_increament的值是不是查找根本原因的切入點;
路漫漫..... _(:з」∠)_ 

PS: 源庫導出結構的時候, 已經(jīng)確認源庫沒有觸發(fā)器和存儲過程, 而且也可以確認5.0.X和5.7的binlog都是v4;

PPPPPPPPPS: 畢竟從5.0.X往5.7做同步不是一個常見的場景, 姑且就當做是跨版本的同步問題吧, 如果能換成row模式的話, 好想看看會不會出問題;
向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI