出錯的原因是,主庫服務異常重啓,導致slave庫複製報1032錯
也有這樣的情況,slave沒有限制只讀權限,開發或者運維人員在slave庫上誤刪數據,導致生成主庫update數據時,由於slave庫上記錄被提前誤刪,導致主從複製報錯1032,主從不同步了。
解決方法:
很多新手選擇了my.cnf可配置slave-skip-errors=1032 從而跳過日誌中1032 ERROR報錯,或者set global sql_slave_skip_counter=1;stop slave; start slave;
然而上面的方式都是不可取的,因爲slave庫上沒這條,master庫再更新時,slave還會報錯的。所以這個1032的報錯必須解決。如何解決呢,咱們下面來細說下
show master status \G;
複製報錯如下:
Could not execute Update_rows event on table appdb.hlz_ad_voucher;
Can't find record in 'hlz_ad_voucher', Error_code: 1032;
handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000427, end_log_pos 9279278
解決辦法:根據報錯結束的binglog位置點,通過解析主庫的binlog日誌文件來提取出當前正在update更新主庫上的記錄時的這條SQL記錄。
下面在master上是獲取到update更新記錄的SQL方法:
[root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v -v /data/mysql/binlog/mysql-bin.000427|grep -A 15 9279278|sed -n '/### UPDATE `appdb`.`hlz_ad_voucher`/,/COMMIT/p'|grep -B 100 '# at 9279278'
### UPDATE `appdb`.`hlz_ad_voucher`
### WHERE
### @1=9400072 /* INT meta=0 nullable=0 is_null=0 */
### @2=2994652 /* INT meta=0 nullable=0 is_null=0 */
### @3=0.50 /* DECIMAL(5,2) meta=1282 nullable=0 is_null=0 */
### @4=0 /* INT meta=0 nullable=0 is_null=0 */
### @5=0 /* INT meta=0 nullable=0 is_null=0 */
### @6=1 /* INT meta=0 nullable=0 is_null=0 */
### @7=0 /* INT meta=0 nullable=0 is_null=0 */
### @8='2020:05:05' /* DATE meta=0 nullable=0 is_null=0 */
### @9='新人贈送' /* VARSTRING(1020) meta=1020 nullable=0 is_null=0 */
### @10='2020-05-05 21:14:20.745' /* DATETIME(3) meta=3 nullable=0 is_null=0 */
### @11='2020-05-05 21:14:20.745' /* DATETIME(3) meta=3 nullable=0 is_null=0 */
### @12=0 /* INT meta=0 nullable=0 is_null=0 */
### @13=0 /* INT meta=0 nullable=0 is_null=0 */
--
#at 9279278
把獲取到update更新記錄的SQL轉換成insert into SQL語句,然後在slave庫對應的表插入,最後stop slave;start slave;show slave status\G
[root@localhost ~]# mysqlbinlog --no-defaults --base64-output=decode-rows -v -v /data/mysql/binlog/mysql-bin.000427|grep -A 15 9279278|sed -n '/### UPDATE `appdb`.`hlz_ad_voucher`/,/COMMIT/p'|grep -B 100 '# at 9279278'|sed 's/### //g;s/\/\*.*/,/g;s/UPDATE/INSERT INTO/g;s/WHERE/SELECT/g;' | sed -r 's/(@13.*),/\1;/g' | sed 's/@\([0-9]\+\)=//g;'
INSERT INTO `appdb`.`hlz_ad_voucher`
SELECT
9400072 ,
2994652 ,
0.50 ,
0 ,
0 ,
1 ,
0 ,
'2020:05:05' ,
'新人贈送' ,
'2020-05-05 21:14:20.745' ,
'2020-05-05 21:14:20.745' ,
0 ,
0 ;
--
#at 9279278
一直重複上面的方法在master的binlog文件中提取到SQL,然後轉化成insert into SQL,然後在插入slave庫對應的表,stop slave;start slave; 直到不再報錯爲止。