gtid同步异常本身不直接损耗性能,但会引发sql线程卡死、relay log堆积、重试风暴或复制线程频繁启停,进而拖垮从库cpu、磁盘i/o和主库网络带宽;需重点监控seconds_behind_master为null、retrieved_gtid_set与executed_gtid_set差距过大、last_sql_error中的锁超时或死锁等真实危险信号。

GTID同步异常本身不会直接导致集群性能损耗,但会引发SQL线程卡死、relay log堆积、重试风暴或复制线程频繁启停,这些才是真实拖垮从库CPU、磁盘I/O和主库网络带宽的元凶。
看懂 SHOW REPLICA STATUS 里真正危险的三个字段
别只扫一眼 Replica_SQL_Running: No 就去跳过事务。重点盯住:
-
Seconds_Behind_Master持续为NULL:说明SQL线程已彻底中断,不是延迟,是“失联”。此时从库可能还在疯狂拉取binlog(IO线程活着),但无法执行,relay log持续膨胀,磁盘写入飙升 -
Retrieved_Gtid_Set和Executed_Gtid_Set差距过大(比如前者包含:1-100000,后者只到:1-5):大概率是SQL线程在某个GTID处反复报错、回滚、重试,形成“执行→失败→重试”循环,CPU占用率会异常高 -
Last_SQL_Error中出现Lock wait timeout exceeded或Deadlock found:说明该事务在从库执行时被其他长事务阻塞,或自身触发了锁竞争——这不是GTID问题,而是从库负载/事务设计问题,强行跳过只会让不一致扩散
区分“GTID断裂”和“GTID冲突”的处理逻辑
两者现象相似(Replica_SQL_Running: No),但根因和操作完全相反:
-
GTID断裂(常见于主库
PURGE BINARY LOGS过猛):Retrieved_Gtid_Set里有f8e7f9b2-1a3c-11ef-8a12-00155d012345:12345,但主库binlog已不存在该事务。必须用SET GTID_NEXT='...'; BEGIN; COMMIT;注入空事务补位,否则永远卡住 -
GTID冲突(典型如从库被误写入同GTID事务):
Executed_Gtid_Set已包含出错事务号,但SQL线程又试图再执行一次。此时不能跳过,得先查SELECT * FROM mysql.gtid_executed WHERE source_uuid='...' AND interval_start = 12345;确认是否真重复;若确认是误写,需RESET REPLICA ALL;并重做全量同步
跳过事务前必须验证的三件事
用 SET GTID_NEXT 注入空事务看似简单,但一步错满盘输:
- 确认该GTID对应事务确实可丢弃:从
Last_SQL_Error提取事务号后,去主库执行mysqlbinlog --base64-output=DECODE-ROWS -v /path/to/binlog.0000* | grep -A 20 "GTID.*:12345",看里面是不是INSERT INTO config VALUES ('test', 'on')这类无害操作,而不是UPDATE order SET status=3 - 检查从库当前
@@sql_log_bin值:必须为ON,否则BEGIN; COMMIT;不会生成GTID,注入无效 - 确保没有其他会话正在修改同一张表:注入空事务期间,若应用正对该表执行大更新,可能触发元数据锁(MDL),导致整个从库DML阻塞
最易被忽略的点:GTID模式下,sql_log_bin=OFF 的会话变更永远不会进入复制流,但它的影响会持续存在——比如它删了一张从库需要的表,后续任何依赖该表的事务都会报 Table doesn't exist。这种“静默破坏”比显式报错更难定位。











