MySQL GTID_EXECUTED 怎样判断复制位点是否推进
MySQL 复制排查时,很多人看到 GTID_EXECUTED 里最后一个数字变化,就把它当成“复制位点已经推进”。这个判断不够稳:GTID_EXECUTED 实际是一个 GTID 集合,可能包含多个 UUID、连续区间和已经保留的历史事务。可靠做法是同时读取源端与副本端的集合,再判断集合覆盖关系。
官方文档:https://dev.mysql.com/doc/refman/8.4/en/replication-gtids.html
本文只解决一个问题:怎样根据 GTID 集合判断副本是否追上源端,以及没有追上时缺了哪些事务。示例使用 MySQL 8.4 语法,命令中的输出是说明格式,不代表某台机器的实际运行结果。
判断复制位点是否推进,不要只看单个序号;先取源端集合 S 和副本端集合 R,再用GTID_SUBSET(R,S)、GTID_SUBTRACT(S,R)判断覆盖关系和缺口。
先弄清 GTID_EXECUTED 到底表示什么
全局变量 @@GLOBAL.gtid_executed 表示服务器已经执行过的 GTID 集合;在源端执行 SHOW BINARY LOG STATUS 时,Executed_Gtid_Set 表示同一类信息。在副本端执行 SHOW REPLICA STATUS 时,也能看到 Executed_Gtid_Set。
因此它不是传统复制里的 File 加 Position,也不是一个可以简单做减法的整数。下面这样的集合:
3e11fa47-71ca-11e1-9e33-c80aa9429562:1-120 3e11fa47-71ca-11e1-9e33-c80aa9429562:125-130
中间的 121-124 可能并不在集合里。多源复制、过滤规则或事务执行顺序变化时,集合还可能包含多个 UUID。先把它当集合处理,后面的判断才不会被“最后一个数字”误导。

先分别保存源端和副本端快照
排查时不要在两个终端之间凭感觉对照。先在源端保存执行集合,再在副本端同时保存执行集合、接收集合和线程状态。这样可以区分“还没收到”和“已经收到但还没应用”。
-- 源端:查看已经执行并写入二进制日志的 GTID 集合 SHOW BINARY LOG STATUS\G -- 副本端:同时查看已接收、已应用以及线程状态 SHOW REPLICA STATUS\G -- 副本端:只取全局执行集合,便于脚本采集 SELECT @@GLOBAL.gtid_executed AS replica_executed;
源端关注 Executed_Gtid_Set,副本端关注 Executed_Gtid_Set 与 Retrieved_Gtid_Set。Retrieved_Gtid_Set 只说明事务已经进入或曾经进入 relay log,并不等于 SQL applier 已经执行完成。
如果 Retrieved_Gtid_Set 比副本的 Executed_Gtid_Set 更大,说明接收线程已经走在前面,应用线程仍有追赶空间;如果两者接近但线程状态异常,则应转向复制错误、权限或过滤规则排查。
用集合函数判断“是否追上”
假设源端快照记为 S,副本端已执行集合记为 R。MySQL 的 GTID_SUBSET(set1,set2) 在 set1 的所有 GTID 都包含于 set2 时返回 1,所以最直接的覆盖判断是:
-- 把下面两个字符串替换为同一时间窗口采集的源端与副本端集合 SET @source_set = '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-130'; SET @replica_set = '3E11FA47-71CA-11E1-9E33-C80AA9429562:1-120'; -- 副本集合覆盖源端集合时才可认为当前集合已追平 SELECT GTID_SUBSET(@source_set, @replica_set) AS source_covered; -- 反向差集用于找出源端有而副本端没有的事务 SELECT GTID_SUBTRACT(@source_set, @replica_set) AS missing_on_replica;
当 source_covered 为 1 时,副本的已执行集合覆盖了源端快照;当结果为 0 时,查看 missing_on_replica。例如差集为 ...:121-130,就表示这段事务仍未出现在副本的已执行集合中。
反向再算一次也很有用:
-- 如果副本集合反过来多出事务,说明两边可能不是同一复制拓扑或存在额外来源 SELECT GTID_SUBTRACT(@replica_set, @source_set) AS extra_on_replica;
这个结果不应被简单解释成“副本错误”。多源复制、切换过源库、人工注入 GTID 或采集时间不同,都可能让副本集合包含源端快照没有的事务。

线程状态决定“没推进”属于哪一层
集合比较只回答事务是否已经执行,不能单独说明复制为什么没有推进。副本端还要一起看 Replica_IO_Running、Replica_SQL_Running、Last_IO_Error 和 Last_SQL_Error。
- 接收集合不变,IO 线程异常:优先检查网络、账号权限、源端连接和 TLS 配置。
- 接收集合增加,执行集合不变:优先查看 SQL 线程、错误信息、锁等待和复制过滤。
- 两个集合都在增加但仍有差集:复制正在推进,差集应作为当前延迟范围,连续采样后再判断是否停止。
- 多通道复制:不要只看一个默认通道的状态;集合是服务器级视角,通道级故障仍需按
SHOW REPLICA STATUS的Channel_Name分开记录。
生产环境中建议连续取两次快照,例如间隔几秒或一个业务采样周期。一次快照只能说明瞬时集合关系,连续快照才能说明集合是否继续增长。不要把 Seconds_Behind_Source 单独当成 GTID 一致性的证明。
最小排查清单
- 源端记录
SHOW BINARY LOG STATUS的Executed_Gtid_Set。 - 副本端记录
SHOW REPLICA STATUS的Retrieved_Gtid_Set、Executed_Gtid_Set和线程状态。 - 用
GTID_SUBSET(S,R)判断源端集合是否被副本覆盖。 - 用
GTID_SUBTRACT(S,R)输出缺口,用反向差集识别额外来源。 - 连续采样后再处理网络、SQL 错误、过滤规则和多通道问题。
一句话总结:GTID_EXECUTED 适合做集合级的复制进度判断,不适合被压缩成一个“最后位点数字”。先区分已接收与已执行,再用集合覆盖和差集定位,结论才可用于生产排查。
相关问题
GTID_EXECUTED 为空是不是复制失败?
不一定。先确认 GTID 是否启用、当前服务器是否执行过 GTID 事务,以及查询的是全局变量还是某个复制通道。若 GTID 未使用,相关集合本来就可能为空。
为什么副本的 Retrieved_Gtid_Set 已经变大,Executed_Gtid_Set 还没变?
通常表示接收线程已经收到事务,但应用线程尚未完成执行。应结合 SQL 线程状态和 Last_SQL_Error 判断是正常追赶、锁等待还是应用错误。
MySQL OPTIMIZE TABLE 怎样判断表空间是否真的回收
- 上一篇
- MySQL OPTIMIZE TABLE 怎样判断表空间是否真的回收
- 下一篇
- MySQL table_io_waits_summary_by_index_usage 中 NULL 索引名代表什么
-
- 数据库 · MySQL | 1小时前 |
- MySQL collation_connection 怎样排查字符串比较异常
- 149浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · 数据库 · DDL · 迁移 · InnoDB · mysql innodb ALTER TABLE INSTANT ADD COLUMN 在线DDL 表结构变更
- MySQL INSTANT ADD COLUMN 怎样判断 DDL 是否支持
- 149浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL · mysql SQL JSON JSON_TABLE NESTED PATH
- MySQL JSON_TABLE 多个 NESTED PATH 为什么会补出 NULL 行
- 189浏览 收藏
-
- 数据库 · MySQL | 2小时前 | MySQL · SQL · mysql WITH RECURSIVE cte_max_recursion_depth CTE 递归查询
- MySQL CTE 递归查询怎样限制深度
- 360浏览 收藏
-
- 数据库 · MySQL | 2小时前 | MySQL · 执行计划 · sql优化 · 性能排查 · mysql 排序 磁盘临时表 EXPLAIN ANALYZE Sort_merge_passes
- MySQL EXPLAIN ANALYZE 怎样看排序是否落盘
- 264浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL 不同字符集列的索引长度参数对比
- 118浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 839次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 836次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 919次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 894次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 721次使用
-
- MySQL 明明加了索引,为什么查询还是很慢?先查这 6 个点
- 2026-06-27 374浏览
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- golang 基于 mysql 简单实现分布式读写锁
- 2023-01-07 384浏览
-
- 详解如何利用GORM实现MySQL事务
- 2023-01-07 184浏览
-
- Go语言实现操作MySQL的基础知识总结
- 2023-01-23 265浏览

