gtid_executed 和 gtid_purged 的关系是判断GTID连续性的最直接依据,主库gtid_executed必须包含从库gtid_executed,且从库gtid_purged不能超出主库范围。
GTID 连续性最直接的判断依据,是主从两端 gtid_executed 与 gtid_purged 的关系是否合理。主库的 gtid_executed 必须包含从库的 gtid_executed,且从库的 gtid_purged 不能超出主库已 purged 的范围。
常见错误现象:从库报错 ERROR 1872 (HY000): Slave failed to initialize GTID state 或启动复制后立即 Seconds_Behind_Master: NULL,往往就是 gtid_purged 被手动设错、或备份时未正确导出 GTID 集合导致。
SELECT @@global.gtid_executed;
SELECT @@global.gtid_executed, @@global.gtid_purged;
从库 gtid_executed ⊆ 主库 gtid_executed,且 从库 gtid_purged ⊆ 主库 gtid_purged
SET GLOBAL gtid_purged = '...'; 重置(仅限从库空闲、无活跃复制时)开启 GTID 复制后,Auto_Position: 1 是前提;但真正反映“连续性”的是 Retrieved_Gtid_Set 和 Executed_Gtid_Set 的差值是否收敛、有无跳变。
使用场景:日常巡检或故障初判。如果 Retrieved_Gtid_Set 持续增长但 Executed_Gtid_Set 停滞,说明 SQL 线程卡住;如果两者差值突然变大且不再缩小,可能是主库跳过事务(如空事务注入)或从库被误 reset。
Retrieved_Gtid_Set 表示 IO 线程已拉取但尚未执行的 GTID 集合Executed_Gtid_Set 表示 SQL 线程已实际执行的 GTID 集合Executed_Gtid_Set ⊆ Retrieved_Gtid_Set ⊆ gtid_executed,且差集随时间趋于 0Retrieved_Gtid_Set 不等于 gtid_executed —— 它只含 relay log 中暂存的部分最硬核的验证方式:直接计算主库 gtid_executed 减去从库 gtid_executed,看结果是否为空集。非空即表示从库落后,且差集内容就是缺失的事务 ID。
性能影响小,但需注意 MySQL 版本对 GTID 集合运算的支持程度(5.7.6+ 支持 GTID_SUBTRACT() 函数)。
SELECT GTID_SUBTRACT(@@global.gtid_executed, '从库返回的gtid_executed字符串');
'' → 连续;返回类似 uuid:1-10 → 缺失这些事务channel 对应的 Executed_Gtid_Set
pt-table-checksum 默认不感知 GTID,但它生成的校验记录会写入 percona.checksums 表,而该表的变更会被记录为 GTID 事务——这就提供了“校验动作”和“GTID 执行点”的锚定机会。
容易踩的坑:校验期间主库发生 DDL 或大事务,可能导致从库 checksum 行被延迟应用,进而让 GTID 差集误判为数据不一致。
SELECT @@global.gtid_mode, @@global.enforce_gtid_consistency; 全局为 ON--no-check-binlog-format,否则 GTID 模式下可能拒绝执行SELECT gtid_next FROM percona.checksums ORDER BY ts DESC LIMIT 1;,确认最后一条 checksum 对应的 GTID 已执行GTID_SUBTRACT 检查该 GTID 是否仍在主库 gtid_executed 中 —— 这才是“校验覆盖到的最新连续点”gtid_purged 一旦设置就不可逆,且会影响后续所有基于备份的从库初始化;哪怕只是临时测试,也别在生产从库上随意 SET GLOBAL gtid_purged。