在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的情况下才能使用。