一个偶然的事情,线上一部MySQL slave 被人误删了数据,然后又在 master上执行了同样的 delete 操作,导致从库报了1032错误。
其实这种情况下,如果能将缺少的记录重新insert 进去,再 start slave就可以完美解决;
问题在于不知道他具体操作了什么数据,所以想直接跳过这个事务。
脑海里回想了下GTID模式下跳过1032 的步骤,大概步骤是:
mysql> SET @@SESSION.GTID_NEXT= ‘4ab8feff-5272-11e8-9320-08002715584a:201840‘;
Query OK, 0 rows affected (0.04 sec)
mysql> BEGIN;
Query OK, 0 rows affected (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
mysql> SET GTID_NEXT=‘AUTOMATIC‘;
Query OK, 0 rows affected (0.00 sec)
就能解决问题。
问题的关键是如何定位SESSION.GTID_NEXT,由于时隔久远记不太清,于是顺手Google 了一把,没想到结果令人大跌眼镜。
竟然不止一个人说是直接看 Retrieved_Gtid_Set 接收的最后一个GTID 号:
我们回顾一下这两个指标的含义:
Retrieved_Gtid_Set: 表示 从库IO进程从主库已经接收到的事务的GTID集合。
Executed_Gtid_Set:表示 已经在从库上执行的事务的GTID集合。
已正常的思维思考一下,或许Executed_Gtid_Set更有参考意义?答案是NO。
这里我们需要关注的是从库报 1032 时, Relay_Master_Log_File 和 Exec_Master_Log_Pos 处在什么位置,这里才是从库真正卡住的位置
显而易见,这些事务都是来自于主库,所以我们应该去主库上的binlog 找到对应的事务的 GTID
mysqlbinlog --start-position=2102 -vv --base64-output=DECODE-ROWS mybinlog.000010 >binlog-10.sql
看这里:
在2102 这个位置紧跟其后指定下一个事务的GTID:
SET @@SESSION.GTID_NEXT= ‘803ee8b1-af67-11e8-be2b-000c29ef4329:643‘/*!*/;
那下一个事务是什么呢?
就是从 begin 到 commit 中间的语句,而二这个语句正是在主库删除记录的语句。
正是我们应该跳过的事务,所以正确的姿势是:
mysql> SET @@SESSION.GTID_NEXT= ‘803ee8b1-af67-11e8-be2b-000c29ef4329:643‘;
mysql> BEGIN;
mysql> COMMIT;
mysql> SET GTID_NEXT=‘AUTOMATIC‘;
到此为止,欢迎指正!
原文地址:https://www.cnblogs.com/lidx/p/9723669.html