MySQL 8.0.23+因默认启用GTID复制,sql_slave_skip_counter已被弃用报错;跳过事务需停复制、设GTID_NEXT、空提交、重置并重启;1062错误本质是主从数据不一致,须溯源排查而非简单跳过;全量同步应避免mysqldump直接导入,推荐结合--single-transaction与--set-gtid-purged=OFF导出,并严格校验GTID连续性;从库只读需同时启用read_only和super_read_only。

为什么SET GLOBAL sql_slave_skip_counter = 1现在大多失效了
MySQL 8.0.23+ 默认启用了基于 GTID 的复制,sql_slave_skip_counter 已被弃用,强行执行会报错 ERROR 1251: SET GLOBAL sql_slave_skip_counter is not supported when @@GLOBAL.GTID_MODE = ON。不是你命令输错了,是机制变了。
真正能跳过的前提是:主从都开启 GTID,且你清楚要跳过的是哪条事务(通过 SELECT * FROM performance_schema.replication_applier_status_by_coordinator\G 查 LAST_ERROR_MESSAGE,定位到 GTID 值)。
- 先停复制:
STOP REPLICA; - 跳过当前卡住的事务:
SET GTID_NEXT = 'xxx-xxx-xxx:nnn';(填错误里显示的 GTID),再执行空事务:BEGIN; COMMIT; - 重置 GTID 下一个值:
SET GTID_NEXT = 'AUTOMATIC'; - 重启复制:
START REPLICA;
1062 错误本质是主从数据不一致,不是“跳过就完事”
Duplicate entry 'xxx' for key 'PRIMARY' 这类 1062 报错,说明从库已有某条记录,但主库又发来一条 INSERT 或 REPLACE,触发唯一键冲突。常见于手动在从库写入、主库双写未关、或历史数据导入遗漏。
直接跳过只是掩盖问题,下次可能在别的表、别的字段上再爆一次。必须确认:这条语句在主库是否本不该执行?比如是开发误操作、测试数据残留、还是应用层幂等没做好?
- 查主库 binlog:
mysqlbinlog --base64-output=DECODE-ROWS -v mysql-bin.0000xx | grep -A 10 -B 10 'xxx',看那条 INSERT 是谁、什么时候、为什么产生的 - 检查从库是否有不该存在的行:
SELECT * FROM tbl WHERE id = xxx;,对比主库结果 - 如果从库多出数据,且确认无业务影响,可先
DELETE FROM tbl WHERE id = xxx;,再START REPLICA;
想彻底重新同步,别用 mysqldump + 导入这种“土法炼钢”
全量导出再导入,在大库上极易锁表、拖慢主库、产生新延迟,还可能因字符集/时区/SQL_MODE 不一致导致隐性数据损坏。更稳的方式是基于现有从库做“克隆”或“快照恢复”。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
推荐路径:用 mysqldump --single-transaction --master-data=2 --triggers --routines 导出,但关键在后续——导入前必须停掉从库 SQL 线程,并在导入后手动重设复制位置(CHANGE REPLICATION SOURCE TO 中的 SOURCE_LOG_FILE 和 SOURCE_LOG_POS 要和 dump 文件里的 CHANGE MASTER 注释严格对应)。
- 导出时加
--set-gtid-purged=OFF(如果主从 GTID 模式已启用,否则导入会失败) - 导入后务必检查
SHOW REPLICA STATUS\G中Retrieved_Gtid_Set和Executed_Gtid_Set是否连续,断点要用SELECT GTID_SUBTRACT(...)校验 - 避免在业务高峰期操作;导入完成先
STOP REPLICA;,确认数据一致再START REPLICA;
最容易被忽略的坑:从库的 read_only 和 super_read_only
很多团队开了 read_only = ON,却忘了 super_read_only = ON。结果 root 用户仍能写入,导致从库悄悄脏写,下次主从同步一碰就 1062。这不是配置没生效,是权限层级漏了一层。
验证方式很简单:SELECT @@read_only, @@super_read_only; 两个都得是 1 才算真正只读。如果之前已经发生过误写,光开参数没用,得人工比对、清理、再校验。
- 临时修复误写:
STOP REPLICA; DELETE FROM tbl WHERE ...; START REPLICA; - 长期防护:在初始化从库脚本里明确写死两行:
SET PERSIST read_only = ON;和SET PERSIST super_read_only = ON; - 监控项建议加一条:
SELECT COUNT(*) FROM information_schema.PROCESSLIST WHERE COMMAND != 'Sleep' AND USER != 'system user';,异常活跃连接可能就是脏写源头
事情说清了就结束










