1. 程式人生 > >MySQL主從檢驗一致性工具pt-table-checksum報錯的案例分析

MySQL主從檢驗一致性工具pt-table-checksum報錯的案例分析

問題】

有同事反饋我們改造過的MySQL5.7.23版本,使用pt-table-checksum工具比較主從資料庫的一致性時報錯

Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave.

這個問題隱藏的比較深,經過反覆測試,終於定位到原因了。

【pt-table-checksum工具的關鍵處理流程】

1、 pt-table-checksum工具有一部分處理邏輯,對於binlog_format為ROW模式的複製,會在master和slave上設定binlog_format=STATEMENT,確保從庫也會執行 checksum SQL

2、接下來執行REPLACE INTO的語句

3、前面同事反饋的報錯就發生在執行REPLACE INTO語句時

對於Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. REPLACE... SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave.的報錯,其實是warning資訊

當執行set session binlog_format='statement'後執行REPLACE INTO,在MySQL5.6,5.7的版本中都會報warning

關鍵的差異在於warning的code編號發生了變化,在MySQL5.6及原生MySQL5.7下是1592,在我們改造過的MySQL5.7.23下是1593

4、從原始碼中看到pt-table-checksum對1592的code做了忽略,當出現1592的warnings時會繼續下面的處理,而當編號變為1593時,pt-table-checksum工具在這裡就直接報Error了

將pt-table-checksum程式碼中的1592修改為1593,再次執行,恢復正常

【為什麼MySQL5.7.23下的code會發生變化】

 應該與我們MySQL原始碼改造時,新增提示資訊有關,對應的code值是在編譯時動態生成,由於中間新定義了報錯資訊,後面的error code值都增加1

本身error code的值並不影響功能使用,但正好遇到第三方的pt-table-checksum工具這裡程式碼寫死了code值,所以導致了上面的問題。

【改進方案】

1、 為了更好的相容性,建議大家在自定義提示資訊時放在程式碼最下面,這樣不影響其他code值的生成,

2、 當前版本中如果有checksum的需求,可以臨時修改vim /usr/bin/pt-table-checksum,增加1593的warning資訊過濾