【MySQL】gh-ost改雙主表結構主鍵衝突問題

風塵_NULL發表於2020-02-21

1)背景:

最近幫業務方排查了兩例主主複製丟資料或者主鍵衝突的問題,DB側的同事也問我這是什麼一個原理,在解答他們的同時,順便也把這個問題記錄一下

2)現象:

    公司一南北業務採用主主複製,而且該表的主鍵是自增ID,每個主庫的自增ID是錯開的,但是業務的主鍵卻出現了主鍵衝突,開始以為是設定不當,或者認為修改造成,但是翻看歷史記錄,沒人有過操作,而且配置也正確,沒人重啟;在調查binlog中,發現了一個有意思的現象,MySQL的一個主庫binlog中出現了兩條主鍵ID是一樣的binlog,而且是insert產生的binlog,具體現象如下:

17:19分一條

    

17:22分鐘的一條

    

    開始自己的感覺是懵逼的,怎麼主鍵相同,還能插入同一張表?後面猛然一想,這應該是gh-ost改表結構造成的(本公司DBA嚴重不足,部分DB操作只能讓業務運維也承擔一部分了)

3)模擬分析:

   

    前提:假設有兩個雙主,分別叫主庫A與主庫B,上面存在表T,T表只有一個主鍵,在ghost修改之前的表,我們叫T,修改之後的表是T'(T跟T'其實是同一張表,只是產生的時間不同的叫法,方便表示)  

主庫B進行rename table T to T_old,new_t TO T操作,這時候主庫A是T'表了

同時主庫A插入T表13的資料,但是主庫B還沒收到(延遲關係) 

主庫A的T表被主庫B傳過來的rename table T to T_old,new_t TO T修改,變成了T';由於T'表在主庫B還沒收到第二步發過來的13,所以主庫A的T'表肯定也沒13這個值

主庫A在這時又向T'插入13,正在複製給主庫B的T'中(由於延遲,還沒傳送到主庫的T'表)

主庫B的T'接收到第二步主庫A插入T的13

第四步主庫A寫入T'的13已經傳到主庫B,發現B主庫的T'表已經有了13(第五步過來的),然後主鍵衝突

到此,主鍵衝突的原因已經找到,這種衝突意味著資料有丟失(此分析需要你對gh-ost的原理有充分的理解)

4)如何避免

    在用gh-ost修改表結構的工程中,如果是雙主都有寫入,則必須將寫入切到單邊,然後再進行修改

    


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30221425/viewspace-2676301/,如需轉載,請註明出處,否則將追究法律責任。

相關文章