想必從庫異常中斷的情況不在少數,其中報錯信息中1032及1062的錯誤占了不少的比重 錯誤1032指的是從庫中找不到對應行的記錄 錯誤1062指的是主鍵衝突 遇到此報錯時,大多DBA會使用如下方法進行處理 1 手動處理 方法一: 找出引起異常的數據然後手動在從庫處理後重啟SQL線程繼續觀察; 根據報 ...
想必從庫異常中斷的情況不在少數,其中報錯信息中1032及1062的錯誤占了不少的比重
錯誤1032指的是從庫中找不到對應行的記錄
錯誤1062指的是主鍵衝突
遇到此報錯時,大多DBA會使用如下方法進行處理
1 手動處理
方法一: 找出引起異常的數據然後手動在從庫處理後重啟SQL線程繼續觀察;
根據報錯的信息,通過mysqlbinlog解析binlog日誌,找到對應的數據,然後查看從庫是否缺失數據或者已存在對應主鍵的數據,然後手動在從庫處理對應記錄的數據。處理完畢後再次開啟同步。
但是,後續還得觀察是否再次出現錯誤
方法二: 手動跳過1個或更多個事務,然後繼續觀察。
/* 傳統點位模式複製 */ SQL>set global sql_slave_skip_counter=1; SQL>start sql_thread; /* GTID模式複製 */ SQL>set gtid_next='e29d3917-9dbb-11e9-8b64-e4434b6e2c80:11103335-16054791'; SQL>begin;commit; SQL>set gtid_next='AUTOMATIC';
註意,手動跳過事務的方式存在一個很大的缺點: 1個事務中存在多個sql,用此方式,本事務中的其他SQL也會被跳過(具體的和binlog-format有關,對於當前常用的ROW格式均有影響)。
2 持續跳過錯誤
但是,如果一直報錯,但是,這些報錯又可以忽略可以怎麼處理,此時也有很多方法,通常使用的是如下幾種:
方法一: 使用pt-slave-restart工具跳過對應錯誤
但是使用pt-slave-restart工具跳過報錯時,必須關閉多線程複製,因為工具分不清到底哪個線程複製出了問題,然後會報類似如下的報錯:
Cannot skip transactions properly because GTID is enabled and slave_parallel_workers > 0. See 'GLOBAL TRANSACTION IDS' in the tool's documentation
處理步驟為:
/* 暫停並行複製 */ SQL> set global slave_parallel_workers=0; /* 使用pt-slave-restart工具跳過錯誤(填寫錯誤號)*/ pt-slave-restart --user=root --password='Admin@123' --socket=/data/mysql3306/tmp/mysql.sock --error-numbers=1062 /* 不再報錯時,再開啟並行複製 */ mysql> set global slave_parallel_workers=8;
方法二: 在配置文件里配置跳過指定錯誤
在配置文件[mysqld]項裡加入參數slave-skip-errors
slave-skip-errors=1032,1062
但是,此方法存在一個致命缺點:該參數是靜態參數,無法動態修改,需要修改配置文件後重啟資料庫方可生效。
3 冪等模式
因為手動跳過事務時,會忽略相同事務下的其他正常的SQL在從庫的應用;pt-slave-restart工具需要停止多線程複製,影響從庫應用速度;配置slave-skip-errors又需要重啟資料庫方可生效。那麼有沒有一種方式既不會跳過多餘的SQL,又無需重啟資料庫也不影響從庫應用SQL的速度呢?答案是有的,也就是將slave_exec_mode參數設置為IDEMPOTENT,即冪等模式(預設為嚴格模式STRICT)。
/* 線上動態修改 */ SQL > set global slave_exec_mode='IDEMPOTENT';
改為冪等模式後,可以忽略1032及1062的錯誤,對同一事務內的其他SQL無影響,依舊能正常執行。
4. 結語
本文中沒有舉具體案例進行實戰演示,不過建議大家還是自行搭建環境進行場景復現的演示(在從庫先插入部分數據或先更新部分數據),然後再在主庫執行,即可出現1062或1032的錯誤。
很多初學者或實戰經驗不足的同學可能不知道該參數,因此,更加建議在多種場景下測試。
如想和更多的資料庫技術愛好者及時交流,可以關註公眾號:資料庫乾貨鋪 回覆“加群”,進入技術交流群進行溝通。