mysql主从复制中的GTID是什么_全局事务标识解析

1次阅读

gtid是mysql主从复制中全局唯一的事务标识,格式为“server_uuid:sequence”,替代binlog_file+binlog_pos;启用需同时设置gtid_mode=on、enforce_gtid_consistency=on、log_slave_updates=on;change master to必须用master_auto_position=1。

mysql主从复制中的GTID是什么_全局事务标识解析

GTID 是什么:不是“ID”,而是复制坐标系统

GTID 不是给事务随便打个标签的编号,它是 MySQL 主从复制中替代 binlog_file + binlog_pos 的全新定位机制。每个事务在提交时被赋予一个形如 3E11FA47-71CA-11E1-9E33-C80AA9429562:23 的标识——前半段是主库的 server_uuid(写死在 auto.cnf 里),后半段是该实例上第 23 个已提交事务的序列号。

关键在于:这个组合在整个复制拓扑中全局唯一,且从不重复。它让从库不再靠“我在 mysql-bin.000003 的第 12489 字节”这种脆弱位置来同步,而是靠“我已执行 a3558952-9176-11f0-b428-5254007ccb52:1-2,请把后面没执行过的都给我”来驱动复制。

开启 GTID 的硬性前提:三参数缺一不可

只配 gtid_mode=ON 是无效的,MySQL 启动时会静默降级回传统模式。必须同时满足以下三项,否则 SHOW VARIABLES LIKE 'gtid_mode' 显示为 OFF

  • gtid_mode=ON:启用 GTID 生成功能
  • enforce_gtid_consistency=ON:强制事务合规(禁用 CREATE table ... selectTEMPORARY TABLE、非事务引擎等)
  • log_slave_updates=ON:从库也必须写 binlog(否则无法向下游传递 GTID)

漏掉 log_slave_updates 是最常被忽略的坑——尤其在级联复制场景下,中间从库不写 binlog,下游就收不到上游事务的 GTID,整个链路断裂。

CHANGE MASTER TO 怎么写:MASTER_AUTO_POSITION=1 是唯一正解

启用 GTID 后,CHANGE MASTER TO 中所有关于日志文件和位置的参数(MASTER_LOG_FILEMASTER_LOG_POS)必须彻底删除,否则报错 Error 1777 (HY000): Setting MASTER_LOG_FILE and MASTER_LOG_POS is not allowed when MASTER_AUTO_POSITION = 1

正确写法只有这一种:

CHANGE MASTER TO   MASTER_HOST='192.168.1.10',   MASTER_PORT=3306,   MASTER_USER='repl',   MASTER_PASSWORD='xxx',   MASTER_AUTO_POSITION=1;

执行后,从库会自动比对 SELECT @@global.gtid_executed 和主库的 gtid_executed 集合,找出缺失的 GTID 区间并拉取对应事务。不需要人工解析备份的 gtid_purged 值,也不需要 SET GLOBAL gtid_purged=... ——除非你做了物理备份恢复,那是另一回事。

常见故障信号:从库卡住、报错 Could not execute Write_rows Event

GTID 复制失败时,错误日志往往不直接说“GTID 冲突”,而是表现为 SQL 线程中断、中继日志积,或出现类似 Could not execute Write_rows event on table xxx; Duplicate entry '1' for key 'PRIMARY' 的报错。这通常意味着:

  • 从库被手动执行过写操作(比如误删/误插),引入了主库没有的 GTID,后续主库发来的同表事务因主键冲突失败
  • 备份恢复时没带 --set-gtid-purged=ON,导致从库的 gtid_executed 集合与实际 binlog 内容不一致
  • 跨版本升级后 gtid_mode 切换不干净,残留旧 binlog 位置信息

此时不要用 SET GLOBAL sql_slave_skip_counter=1 跳过——GTID 模式下该命令被禁用。必须用 SET GTID_NEXT='xxx:yyy'; BEGIN; COMMIT; 注入空事务跳过冲突 GTID,操作极容易出错,务必先查清 SELECT * FROM performance_schema.replication_applier_status_by_coordinator;SHOW SLAVE STATUSG 中的 Retrieved_Gtid_SetExecuted_Gtid_Set 差异。

真正麻烦的从来不是配置 GTID,而是当它出问题时,你得同时看懂三个集合:gtid_executedgtid_purgedRetrieved_Gtid_Set 之间的包含关系。少看一个,就可能跳错、漏数据、甚至让从库永远追不上主库。

text=ZqhQzanResources