今天測試環境一套MySQL 8.0.16主從出現Errno:1782錯誤,詳細報錯如下:
Worker 1 failed executing transaction 'NOT_YET_DETERMINED' at master log mysql-bin.000029, end_log_pos 33350454; Error executing row event: '@@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.'
該問題常見於5.7及以前版本:https://bugs.mysql.com/bug.php?id=85480
通過位點解析relay log發現日志里包含一個沒有生成GTID和BEGIN的COMMIT操作產生匿名事務,導致復制異常,日志內容如下。
從日志信息來看,當執行到COMMIT時,由於沒有設置GTID_NEXT,因此MySQL認為該事務未匿名事務,SQL線程異常停止
網上關於錯誤“Row event for unknown table”的資料較少,查到資料解釋大意是在建立table map信息丟失導致。
參考鏈接:
https://bugs.mysql.com/bug.php?id=60964
https://www.jianshu.com/p/4e28f09b3ce5
上面的情況是跳過"SET @@SESSION.GTID_NEXT" 和"BEGIN"兩部分,而如果只跳過"SET @@SESSION.GTID_NEXT",則執行BEGIN時,會報如下錯誤:
Last_Errno: 1782 Last_Error: Error '@@SESSION.GTID_NEXT cannot be set to ANONYMOUS when @@GLOBAL.GTID_MODE = ON.' on query. Default database: ''. Query: 'BEGIN'
位於該錯誤位點的GTID為“7efd338e-ee5e-11ea-8957-000c29bed658:5634856”,而從庫執行過的GTID為“7efd338e-ee5e-11ea-8957-000c29bed658:5634856”,由於缺少GTID_NEXT標識事務,從庫無法判定該事務是否已在從庫上執行,也就無法自動跳過該事務。
修復嘗試,通過重新開啟GTID可以修復此問題,使主從正常同步:
#關閉GTID stop slave sql_thread; SET GLOBAL GTID_MODE = 'OFF_PERMISSIVE'; SET GLOBAL GTID_MODE = 'ON_PERMISSIVE'; SET GLOBAL GTID_MODE = 'ON'; start slave sql_thread; #此時start slave會出現Errno: 1781異常 #開啟GTID SET GLOBAL GTID_MODE = OFF_PERMISSIVE; SET GLOBAL GTID_MODE = ON_PERMISSIVE; SET GLOBAL GTID_MODE = ON; start slave;
但是由於以上錯誤顯示先執行的GTID大於后生成的GTID,所以無法確保數據是否存在差異(當然可以使用pt-checksum對比數據),保險起見,決定使用熱備重做復制快速恢復。