在MySQL DBA 日常運維工作中,主從同步失敗一定是會遇到的,最常見建是1032錯誤。
1032錯誤的主要原因是主庫更新或者是刪除的記錄在從庫上不存在引起的。
處理此種錯誤一般有兩種思路:
1、直接跳過錯誤執行語句
2、找到錯誤執行語句,修復從庫數據
第一種解決方案會有造成主從不一致的隱患(delete語句可以跳過),第二種是從根本上解決問題比較推薦
語句跳過操作方法如下:
--傳統模式
mysql> stop slave;
#表示跳過一步錯誤,后面的數字可變
mysql> set global sql_slave_skip_counter =1;
mysql> start slave;
之后再用mysql> show slave status\G 查看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
--GTID模式
mysql> stop slave;
通過show slave status\G;找到Retrieved_Gtid_Set:7800a22c-95ae-11e4-983d-080027de205a:10
mysql> set GTID_NEXT='7800a22c-95ae-11e4-983d-080027de205a:10 '
mysql> begin;commit;
mysql> set GTID_NEXT='AUTOMATIC';
mysql> start slave;
修復從庫數據方法如下:
實驗處理update錯誤步驟
主庫:
mysql> select * from t1;
Empty set (0.00 sec)
mysql> set sql_log_bin=0;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t1 values (1,'aa');
Query OK, 1 row affected (0.01 sec)
mysql> insert into t1 values (2,'bb');
Query OK, 1 row affected (0.00 sec)
mysql> insert into t1 values (4,'dd');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t1 values (5,'ee');
Query OK, 1 row affected (0.02 sec)
mysql> set sql_log_bin=1;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t1 values (3,'cc');
Query OK, 1 row affected (0.02 sec)
mysql> select * from t1;
+----+------+
| id | name |
+----+------+
| 1 | aaaa |
| 2 | bb |
| 3 | cc |
| 4 | dd |
| 5 | ee |
+----+------+
5 rows in set (0.00 sec)
從庫:
mysql> select * from t1;
+----+------+
| id | name |
+----+------+
| 3 | cc |
+----+------+
1 row in set (0.00 sec)
模擬故障:
主庫:
mysql> update t1 set name = 'aaaa' where id=1;
Query OK, 1 row affected (0.11 sec)
Rows matched: 1 Changed: 1 Warnings: 0
從庫:
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1032
Last_Error: Could not execute Update_rows event on table reptest.t1; Can't find record in 't1', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000009, end_log_pos 42303
單條故障處理:
根據Last_Error中提示的master log和end_log_pos的位置查找這條從庫上缺失的數據
主庫:
shell># mysqlbinlog -v --base64-output=decode-rows --stop-position=42303 /data/mysql/mysql3306/logs/mysql-bin.000009 | tail -20
SET TIMESTAMP=1496988091/*!*/;
BEGIN
/*!*/;
# at 42198
#170609 14:01:31 server id 1003306 end_log_pos 42249 CRC32 0xfff09796 Table_map: `reptest`.`t1` mapped to number 240
# at 42249
#170609 14:01:31 server id 1003306 end_log_pos 42303 CRC32 0x67a63dd5 Update_rows: table id 240 flags: STMT_END_F
### UPDATE `reptest`.`t1`
### WHERE
### @1=1
### @2='aa'
### SET
### @1=1
### @2='aaaa'
ROLLBACK /* added by mysqlbinlog */ /*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
找到之后,手動轉變為insert into `reptest`.`t1` values (1,'aa');
從庫:
mysql> insert into `reptest`.`t1` values (1,'aa');
Query OK, 1 row affected (0.01 sec)
mysql> start slave;
Query OK, 0 rows affected (0.03 sec)
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
此時故障已恢復,主從同步恢復正常。
可是如果有很多條不一致的,甚至涉及到多張表,如此處理就很費精力了,可以通過編寫腳本來處理,數據庫如果不大也可以重做。
出現1032錯誤之后,如果不是通過重做解決的,最好使用pt-table-checksum檢查、pt-table-sync修復,pt工具都是需要在主從雙yes的情況下才能使用。