MySQL

GTID 集合详解

·15 分钟阅读·5760 字

说明 MySQL GTID 集合的格式、核心变量、主从复制状态字段与故障判断方法

📋 目录

GTID 集合详解

核心定义 GTID(Global Transaction Identifier)是 MySQL 为每个已提交事务生成的全局唯一编号。GTID 集合用于描述一组事务编号范围,是判断主从复制位置、复制延迟、日志缺失和数据一致性的关键依据。

1. GTID 的基本格式

GTID 的标准格式是:

source_id:transaction_id

示例:

3E11FA47-71CA-11E1-9E33-C80AA9429562:1

含义:

部分说明
source_id事务来源实例的 UUID,通常对应 server_uuid
transaction_id该实例上递增的事务序号

多个连续事务可以合并为范围:

3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100

多个来源实例或多个范围可以组合成 GTID 集合:

3E11FA47-71CA-11E1-9E33-C80AA9429562:1-100,
9E11FA47-71CA-11E1-9E33-C80AA9429562:1-50:80-120

2. GTID 集合解决的问题

传统复制依赖 binlog 文件名和 position,例如:

mysql-bin.000123:456789

这种方式在主从切换、故障恢复、重新指向主库时容易出错。GTID 的核心价值是把复制位置从“物理日志位置”提升为“全局事务集合”。

对比项binlog file + positionGTID
定位方式依赖具体 binlog 文件和偏移量依赖全局事务编号
主从切换需要人工找位点可根据已执行集合自动定位
故障恢复容易找错 position更容易判断缺失事务
可读性偏底层物理位置可表达事务范围

GTID 让 MySQL 能够判断:从库已经执行了哪些事务,还缺哪些事务,应从新主库拉取哪些事务。

3. GTID 集合的表示方法

3.1. 单个事务

server_uuid:1

表示某个 server_uuid 上的第 1 个事务。

3.2. 连续事务范围

server_uuid:1-100

表示从 1 到 100 的连续事务。

3.3. 非连续事务范围

server_uuid:1-50:80-120

表示 1 到 50、80 到 120 已存在,中间 51 到 79 缺失或未包含。

3.4. 多个 server_uuid

uuid_a:1-100,
uuid_b:1-20

表示集合中同时包含来自多个 MySQL 实例的事务。多源复制、主从切换、级联复制等场景中可能看到多个 UUID。

4. 主库上的核心 GTID 变量

4.1. gtid_executed

gtid_executed 表示当前实例已经执行过的全部 GTID 集合。

查看方式:

SHOW VARIABLES LIKE 'gtid_executed';

或:

SELECT @@GLOBAL.gtid_executed;

在主库上,它可以理解为“主库已经产生并执行过的事务集合”。在从库上,它表示“从库本地已经执行过的事务集合”,其中既可能包含复制来的事务,也可能包含从库本地执行的事务。

4.2. gtid_purged

gtid_purged 表示当前实例已经执行过,但对应 binlog 已经被清理掉的 GTID 集合。

查看方式:

SHOW VARIABLES LIKE 'gtid_purged';

它常用于判断从库是否还能从主库补齐缺失事务。

gtid_purged 风险 如果从库缺失的 GTID 已经落入主库 gtid_purged,说明主库对应 binlog 已被清理,从库无法再通过正常复制补齐这部分事务,通常需要重新备份恢复或从其他保留日志的实例补齐。

4.3. gtid_executed 与 gtid_purged 的关系

可以简化理解为:

gtid_executed:当前实例执行过的全部事务
gtid_purged:执行过但 binlog 已清理的事务

因此:

gtid_purged 通常是 gtid_executed 的子集

保留在 binlog 中、仍可用于复制补齐的事务,大致可以理解为:

gtid_executed - gtid_purged

5. 从库上的复制状态 GTID 集合

从库状态中最关键的是 Retrieved_Gtid_Set 和 Executed_Gtid_Set。

查看方式:

SHOW REPLICA STATUS\G

在旧版本 MySQL 中也可能使用:

SHOW SLAVE STATUS\G

5.1. Retrieved_Gtid_Set

Retrieved_Gtid_Set 表示复制 IO 线程已经从主库拉取到本地 relay log 的 GTID 集合。

含义:

主库 binlog
  ↓  IO 线程拉取
从库 relay log
  ↓
Retrieved_Gtid_Set

它代表“已经下载到从库”的事务,但不代表已经执行完成。

5.2. Executed_Gtid_Set

Executed_Gtid_Set 表示从库 SQL 线程已经执行完成的 GTID 集合。

含义:

从库 relay log
  ↓  SQL 线程重放
从库数据文件
  ↓
Executed_Gtid_Set

它代表“已经在从库执行完成”的事务。

5.3. 两者的关系

正常情况下:

Executed_Gtid_Set ⊆ Retrieved_Gtid_Set

如果 Retrieved_Gtid_Set 持续增长,说明 IO 线程仍在拉取日志。

如果 Executed_Gtid_Set 持续追赶 Retrieved_Gtid_Set,说明 SQL 线程仍在执行 relay log。

如果两者长期差距扩大,通常表示 SQL 线程执行慢、复制延迟扩大或 SQL 线程报错停止。

6. 主从复制中的 GTID 流程

GTID 复制链路可以抽象为:

主库提交事务
  ↓
生成 GTID 并写入 binlog
  ↓
从库 IO 线程拉取 binlog
  ↓
写入 relay log,Retrieved_Gtid_Set 增长
  ↓
从库 SQL 线程重放 relay log
  ↓
写入从库数据,Executed_Gtid_Set 增长

对应关系:

阶段关键对象代表含义
主库提交gtid_executed主库已执行的事务
主库清理 binloggtid_purged主库已清理日志的事务
从库拉取Retrieved_Gtid_Set从库已下载到 relay log 的事务
从库执行Executed_Gtid_Set从库已重放完成的事务

7. 如何判断主从同步是否正常

7.1. IO 线程是否正常

关注字段:

Replica_IO_Running: Yes
Retrieved_Gtid_Set: 持续增长或接近主库 gtid_executed

如果主库仍有写入,但 Retrieved_Gtid_Set 不增长,可能是 IO 线程异常、网络异常、账号权限异常或主库 binlog 缺失。

7.2. SQL 线程是否正常

关注字段:

Replica_SQL_Running: Yes
Executed_Gtid_Set: 持续追赶 Retrieved_Gtid_Set

如果 Retrieved_Gtid_Set 增长但 Executed_Gtid_Set 不增长,通常是 SQL 线程执行失败、遇到重复键、表结构不一致、锁等待或从库性能不足。

7.3. 是否存在复制延迟

复制延迟可以从两个角度观察:

角度判断方法
时间延迟查看 Seconds_Behind_Source 或 Seconds_Behind_Master
事务集合差距比较 Retrieved_Gtid_Set 与 Executed_Gtid_Set 的差距

时间延迟可能受采样和线程状态影响,GTID 集合差距更适合判断“还有哪些事务未执行”。

8. 常见 GTID 集合判断场景

8.1. 从库缺事务

现象:从库 Executed_Gtid_Set 小于主库 gtid_executed。

主库 gtid_executed: uuid:1-100
从库 Executed_Gtid_Set: uuid:1-80

含义:从库还缺少 uuid:81-100。

如果这些事务仍在主库 binlog 中,从库可以继续复制追上;如果已落入主库 gtid_purged,则无法正常补齐。

8.2. 从库已经拉取但未执行

Retrieved_Gtid_Set: uuid:1-100
Executed_Gtid_Set:  uuid:1-80

含义:从库 IO 线程已经拉到 100,但 SQL 线程只执行到 80。此时应重点排查 SQL 线程状态、慢 SQL、锁等待和复制报错。

8.3. 从库多出事务

主库 gtid_executed: uuid_a:1-100
从库 Executed_Gtid_Set: uuid_a:1-100,uuid_b:1-5

含义:从库可能执行过本地写入事务,或曾经作为主库产生过事务。生产从库通常应避免本地写入,否则可能影响主从一致性和后续切换。

8.4. 主库已清理所需 binlog

从库缺失: uuid:50-60
主库 gtid_purged: uuid:1-80

含义:从库需要的 50-60 已被主库清理,无法从该主库继续复制。常见处理方向是重新搭建从库,或寻找仍保留该范围 binlog 的其他实例。

9. 常用 SQL 与函数

9.1. 查看 GTID 模式

SHOW VARIABLES LIKE 'gtid_mode';
SHOW VARIABLES LIKE 'enforce_gtid_consistency';

9.2. 查看当前实例 GTID 集合

SELECT @@GLOBAL.gtid_executed;
SELECT @@GLOBAL.gtid_purged;

9.3. 判断一个集合是否包含另一个集合

SELECT GTID_SUBSET('uuid:1-80', 'uuid:1-100');

返回 1 表示第一个集合是第二个集合的子集。

9.4. 计算集合差异

SELECT GTID_SUBTRACT('uuid:1-100', 'uuid:1-80');

返回结果:

uuid:81-100

该函数常用于判断从库缺少哪些事务。

10. 排查思路

10.1. 主从复制延迟

排查顺序:

  1. 查看 Retrieved_Gtid_Set 是否继续增长。
  2. 查看 Executed_Gtid_Set 是否继续增长。
  3. 如果只拉取不执行,检查 SQL 线程错误。
  4. 如果拉取也停止,检查 IO 线程、网络、账号权限和主库 binlog。
  5. 比较主库 gtid_executed 与从库 Executed_Gtid_Set。

10.2. GTID 缺失

排查顺序:

  1. 用 GTID_SUBTRACT() 计算从库缺失范围。
  2. 检查缺失范围是否包含在主库 gtid_purged 中。
  3. 如果未清理,尝试恢复复制线程。
  4. 如果已清理,评估重新搭建从库或寻找其他日志源。

10.3. 从库误写入

排查顺序:

  1. 比较主库与从库 gtid_executed。
  2. 找出从库多出的 server_uuid 范围。
  3. 判断是否为从库本地写入或历史主库切换遗留。
  4. 评估数据一致性影响。
  5. 修复后设置只读策略,例如 read_only 与 super_read_only。

11. 记忆口诀

  • gtid_executed:当前实例已经执行过的全部事务。
  • gtid_purged:当前实例执行过但 binlog 已清理的事务。
  • Retrieved_Gtid_Set:从库 IO 线程已经拉回 relay log 的事务。
  • Executed_Gtid_Set:从库 SQL 线程已经执行完成的事务。

可以用“下载”和“执行”区分从库两个集合:

Retrieved = 下载完成
Executed  = 执行完成

12. 面试回答模板

标准回答 GTID 是 MySQL 为每个事务生成的全局唯一编号,格式通常是 server_uuid:transaction_id。GTID 集合用于表达一批事务范围,例如 uuid:1-100。主库上的 gtid_executed 表示已经执行过的事务集合,gtid_purged 表示执行过但 binlog 已清理的事务集合;从库状态中的 Retrieved_Gtid_Set 表示 IO 线程已经拉取到 relay log 的事务,Executed_Gtid_Set 表示 SQL 线程已经执行完成的事务。排查主从复制时,如果 Retrieved 增长而 Executed 不增长,通常是 SQL 线程执行问题;如果从库缺失事务已经落入主库 gtid_purged,则无法通过正常复制补齐,通常需要重建从库或寻找其他日志源。


关联文档

Yanche Blog

记录云原生、Linux、数据库等技术领域的学习心得,以及日常生活的思考与感悟。

© 2026 Yanche Blog. All rights reserved.

Powered by Astro