MySQL主从同步可以跳过特定事务吗_利用GTID set方式过滤
MySQL主从同步跳过事务必须用SET GTID_NEXT配合BEGIN;COMMIT;伪造空事务,不可省略或仅用START TRANSACTION;GTID值须严格匹配原事务;跳过会导致GTID集合出现空洞,影响切主和延迟监控,且sql_sla ve_skip_counter在GTID模式下被禁用。

免费影视、动漫、音乐、游戏、小说资源长期稳定更新! 👉 点此立即查看 👈
MySQL主从同步跳过事务时,SET GTID_NEXT 必须配合 BEGIN; COMMIT;
直接执行 SET GTID_NEXT = 'xxx-xxx-xxx:123'; 然后什么都不做?这绝对是个坑。后续所有事务都会被拒绝写入,并报错 ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.。原因在于,MySQL会认为你试图手动注入一个GTID,却没有提供与之匹配的事务体,导致状态不一致。
所以,正确的姿势是强制“伪造”一个空事务:
SET GTID_NEXT = 'e10c57b9-1234-11ef-8a5d-00155d012345:12345'; BEGIN; COMMIT; SET GTID_NEXT = 'AUTOMATIC';
- 这里的关键是必须使用
BEGIN; COMMIT;这对组合,仅用START TRANSACTION;或者干脆省略事务体都是无效的。 GTID_NEXT的值必须与原故障事务的完整GTID(包含UUID和事务号)严格一致,大小写、连字符一个都不能错。- 操作前务必确认从库处于
STOP SLA VE;状态,否则可能被并行复制线程干扰,导致操作失败或状态混乱。
用 gtid_purged 跳过一批事务,要先清空 gtid_executed
如果想跳过从 e10c57b9-1234-11ef-8a5d-00155d012345:1000 到 :2000 这一整段事务,直接修改 gtid_purged 是行不通的。MySQL的规则是,新设置的 gtid_purged 必须是当前 gtid_executed 集合的子集。而“跳过”本质上是在宣称“这些事务已经执行了”,但实际上并没有,这就产生了逻辑冲突。
唯一的可行路径是,先重置从库的GTID状态:
STOP SLA VE; RESET MASTER; SET GLOBAL gtid_purged = 'e10c57b9-1234-11ef-8a5d-00155d012345:1-999,e10c57b9-1234-11ef-8a5d-00155d012345:2001-999999';
RESET MASTER这一步至关重要,它会清空gtid_executed,为后续设置gtid_purged扫清障碍。- 拼接后的
gtid_purged字符串必须完整覆盖所有你打算“假装已执行”的GTID区间。哪怕只漏掉一个,从库在后续拉取binlog时依然会卡住。 - 需要警惕的是,这个操作相当于丢弃了当前从库所有的复制位点信息,仅适用于你百分百确认主库缺失的那部分事务不会影响业务数据的一致性。
跳过事务后,SHOW SLA VE STATUS\G 的 Retrieved_Gtid_Set 和 Executed_Gtid_Set 不再连续
跳过操作完成后,你会发现这两个集合中间出现了“空洞”。例如,Executed_Gtid_Set 显示为 e10c...:1-999,e10c...:2001-2005,而主库可能已经推进到了 :3000。这本身不是错误,但会带来两个非常实际的影响:
- 影响主从切换:如果在此期间需要进行主从切换,而新的主库binlog中并不包含那些被跳过的GTID,那么从库将无法自动与新的主库对齐,执行
CHANGE MASTER TO ... GTID_SET时会失败。 - 干扰延迟监控:很多监控脚本依赖
Executed_Gtid_Set中最大的事务号来估算复制延迟。一旦GTID序列出现空洞,这种计算方式的结果将严重失真。即便是Percona Toolkit的pt-heartbeat工具,在GTID模式下也无法感知跳过行为,其计算的延迟数值同样不可信。
不要用 sql_sla ve_skip_counter 配合 GTID
在GTID模式下,如果你尝试执行 SET GLOBAL sql_sla ve_skip_counter = 1;,会立刻收到报错:ERROR 1776 (HY000): Cannot use sql_sla ve_skip_counter when @@GLOBAL.GTID_MODE = ON.。这不是配置问题,而是MySQL的强制限制——GTID设计的核心就是通过全局唯一标识来追踪每一个事务,使用跳过计数器会直接破坏这条链的完整性。
如果在某些文档或老旧脚本里看到两者混用的说法,那基本可以断定,它要么根本没在GTID模式下运行过,要么作者根本没有进行过实际验证。
最后,一个真正麻烦的地方在于:跳过事务这个动作本身,并不会在日志中留下明确的痕迹。事后,DBA很难回溯“为什么这里的GTID序列断了一截”。因此,在线上执行跳过操作前,务必先用 mysqlbinlog 工具仔细解析对应的binlog文件,确认目标事务确实只包含普通的DML操作,且没有跨库的数据依赖。否则,等到跳过后才发现主从数据不一致,那就只能面临一个更棘手的局面:全量重建从库。
游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。
同类文章
SQL如何调试复杂的嵌套查询_利用EXPLAIN分析执行路径
SQL如何调试复杂的嵌套查询:利用EXPLAIN分析执行路径 调试复杂SQL,尤其是嵌套查询,最怕的就是面对执行计划一头雾水。其实,读懂EXPLAIN的输出,关键在于理解优化器背后的权衡逻辑,而不是死记硬背几个术语。下面这几个常见的执行计划“疑点”,就是很好的切入点。 EXPLAIN 看不懂执行计划
mysql如何将时间戳转为日期_使用from unix time函数转换
MySQL中FROM_UNIXTIME()转换时间戳需注意时区、引号、NULL及类型溢出 在MySQL数据库操作中,将时间戳转换为可读日期是常见需求,FROM_UNIXTIME()函数是实现这一功能的核心工具。然而,实际应用中存在四个关键细节极易被忽视,直接影响数据准确性:必须使用 +08:00 格
mysql如何将表定义转化为JSON格式_数据库结构文档化技巧
MySQL表结构转JSON:避开常见陷阱,实现高效文档化方案 你是否需要将MySQL的表定义转换为一份清晰、可直接使用的JSON文档?这项工作听起来简单,但实际操作中,直接解析SHOW CREATE TABLE命令的输出会遇到格式不统一的问题,容易出错。有没有更稳定可靠的方法?答案是肯定的。 利用
SQL如何高效合并两个结构相似的表_使用UNION_ALL代替不必要的JOIN
SQL如何高效合并两个结构相似的表:使用UNION ALL代替不必要的JOIN 想把两个结构相似的表合并起来,你首先想到的是不是JOIN?其实,在很多场景下,UNION ALL才是那个更直接、更高效的选择。关键在于,你得先搞清楚自己的目标:是要把数据“纵向堆叠”起来,还是要“横向关联”起来。前者是U
mysql如何定期清理过期测试数据_mysql数据生命周期管理
MySQL测试数据清理:从“能删”到“会删”的四个关键步骤 清理数据库中的过期测试数据,看似是一项基础的运维任务,实则蕴含着诸多技术细节与风险考量。直接执行DELETE语句固然简单,但如何高效、安全、可控地完成清理,才是衡量专业度的关键。 用 DELETE + WHERE 清理过期测试数据最直接,但
- 日榜
- 周榜
- 月榜
1
2
3
4
5
6
7
8
9
10
相关攻略
2015-03-10 11:25
2015-03-10 11:05
2021-08-04 13:30
2015-03-10 11:22
2015-03-10 12:39
2022-05-16 18:57
2025-05-23 13:43
2025-05-23 14:01
热门教程
- 游戏攻略
- 安卓教程
- 苹果教程
- 电脑教程
热门话题

