天天看點

MySQL · 答疑解惑 · 外鍵删除bug分析

下面我們來複現下:

5.5的表現

5.6的表現

很明顯5.6的報錯資訊更精确些,5.5的報錯太不人性化了,容易造成誤解。

它們差别在于5.6的報錯處理在語義分析階段,精準的定位了錯誤資訊。

而5.5的報錯處理在執行階段。

我們先來看看5.5的執行流程:

<code>dict_load_foreigns</code>:這個函數由于承擔的責任太多,隻要發現錯誤,就籠統的抛出<code>error on rename of 'xxxx' to 'xxxx' (errno: xxx)</code>的錯誤.

bug中這個ddl雖然執行失敗了,但實際上foreign key reply_ibfk_2被删除了。這個bug在單機環境下影響不大,但在主備環境下由于ddl執行失敗并沒有記binlog,進而導緻主備表結構不一緻。這個bug隻出現在5.6以前的版本中,5.6是ok的

我們來看看5.5的流程:

出錯復原之前的修改,預期是復原删除外鍵reply_ibfk_2,但是删除外鍵reply_ibfk_2操作在第一次<code>mysql_rename_table</code>中,屬于一個事務,而復原操作在第二次<code>mysql_rename_table</code>中,屬于另一個事務,是以復原沒有成功。

那麼5.6為什麼沒有出現這種錯誤呢?5.6在語義分析的時候就發現錯誤,還沒來得及删外鍵就已經報錯傳回了。

5.5修複方法,将删外鍵的操作放到第二次<code>mysql_rename_table</code>中進行,如果出現錯誤就可以順利的復原了。當然,還是5.6的做法比較好。

繼續閱讀