解决MySQL GTID复制 主键冲突导致的主从不同步

解决MySQL GTID复制 主键冲突导致的主从不同步

本文同时提供以下语言的翻译: English  

最近MySQL集群老是不同步,查看show slave status\G才发现,报了一些之前从来没有遇到的错误,重置主从、重新导入都不好使,于是查阅资料,找到了解决方案。

0、错误提示

sql
1
2
3
Error Duplicate entry 'xxx' for key 'xxx'
# 或者
Error Duplicate name 'xxx'

错误码:1053,1146或1060,1062

1、MySQL 传统主从复制

解决方案

sql
1
2
3
stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = N ;      #跳过N个事务
start slave;

使用时,一般把N替换为1,执行即可。

或者在my.cnf中,设置忽略错误:

Text
1
2
3
[mysqld]
slave-skip-errors=1053,1146 #跳过指定类型的错误
#slave-skip-errors=all #跳过所有错误(不推荐)

2、MySQL GTID复制

在GTID复制中,使用以上方法会报错:

sql
1
2
mysql> set global sql_slave_skip_counter = 1;
ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction

因此需要使用插入空事务的方法。

查看主机状态:

sql
1
show master status \G

返回:

sql
1
2
3
4
5
6
7
*************************** 1. row ***************************
File: mysql-115-bin.000002
Position: 1273
Binlog_Do_DB: 
Binlog_Ignore_DB: 
Executed_Gtid_Set: 94b06c13-1f09-11e5-97ea-000c29c8caec:1-16
1 row in set (0.00 sec)

主库的事务id是1-16,再去查看从库的同步状态:

sql
1
show slave status \G

返回:

sql
1
2
3
4
5
...
Last_SQL_Error: Worker 2 failed executing transaction '' at master log mysql-115-bin.000002, end_log_pos 614; Error 'Duplicate entry '620' for key 'PRIMARY'...
Retrieved_Gtid_Set: 94b06c13-1f09-11e5-97ea-000c29c8caec:1-16
Executed_Gtid_Set: 94b06c13-1f09-11e5-97ea-000c29c8caec:1-10

解读:

  • Retrieved_Gtid_Set项:记录了relay日志从Master获取了binlog日志的位置
  • Executed_Gtid_Set项:记录本机执行的binlog日志位置,从机上该项中包括主机和从机的binlog日志位置。

Executed_Gtid_Set为1-10,说明卡在了第11个事务。

插入空事务,跳过该错误:

sql
1
2
3
4
5
STOP SLAVE;
SET GTID_NEXT="94b06c13-1f09-11e5-97ea-000c29c8caec:11";
BEGIN; COMMIT;
SET GTID_NEXT="AUTOMATIC";
START SLAVE;

就可以解决问题。

或者修改配置my.cnf

此处内容需要评论回复后(审核通过)方可阅读。

3、Pt-Slave-Restart工具

在SSH中执行:

Bash
1
2
3
4
5
6
7
#忽略所有1062错误,并再次启动SLAVE进程
pt-slave-resetart -S./mysql.sock —error-numbers=1062

# 或者

#检查到错误信息只要包含 Duplicate,就一概忽略,并再次启动 SLAVE 进程
pt-slave-resetart -S./mysql.sock —error-text="Duplicate"

4、小结

MySQL主从复制的错误,一般可以通过跳过事务或者插入空事务解决,最偷懒的办法就是修改配置,忽略指定错误。

无论是使用哪种复制方法,都也可以重新导出主库数据重新配置主从。

5、参考

  1. [MySQL FAQ]系列 — 不同复制模式下,如何忽略某些binlog事件1
  2. 插入空事务修复mysql 5.6 GTID复制错误2

解决MySQL GTID复制 主键冲突导致的主从不同步

https://blog.tsinbei.com/archives/911/

文章作者
Hsukqi Lee
发布于

2022-10-30

修改于

2022-12-13

许可协议

CC BY-NC-ND 4.0

评论

昵称
邮箱
网址
暂无