GTID是事务在MySQL复制集群中的唯一标识,由server_uuid和transaction_id组成;启用GTID需开启log_bin、log_slave_updates和enforce_gtid_consistency;配置CHANGE MASTER TO时必须使用MASTER_AUTO_POSITION=1,并避免server_uuid冲突与errant transaction。

GTID 是什么:一个事务在整套复制集群里的“身份证”
GTID(Global Transaction Identifier)不是日志位置,也不是时间戳,而是一个形如 3e11fa47-71ca-11e1-9e33-c80aa9429562:23 的字符串,由两部分组成:server_uuid(实例唯一标识)和 transaction_id(该实例上第几个事务)。它意味着:只要这个事务在任意一台开启了 GTID 的 MySQL 上执行过,其他节点再收到同个 GTID 就直接跳过——不重放、不冲突、不丢数据。
为什么必须开 log_bin 和 log_slave_updates 才能用 GTID
GTID 复制不是靠“我从哪个 binlog 文件哪一行开始追”,而是靠“我本地 binlog 里有没有记录过这个 GTID”。所以从库必须:
-
log_bin=ON:否则无法写入自己执行过的 GTID(binlog 是 GTID 的“记账本”) -
log_slave_updates=ON:否则 relay log 里的事务不会写进自己的 binlog,下游从库就看不到上游传来的 GTID -
enforce_gtid_consistency=ON:强制禁止不安全语句(比如CREATE TABLE ... SELECT、TEMPORARY TABLE),否则一个事务可能被拆成多个 GTID 或分配重复 ID
配置完 GTID,CHANGE MASTER TO 怎么写才不翻车
传统复制要手动填 MASTER_LOG_FILE 和 MASTER_LOG_POS,GTID 下这两项必须删掉,只留 MASTER_AUTO_POSITION=1。否则 MySQL 会报错 ERROR 1777 (HY000): CHANGE MASTER TO without MASTER_AUTO_POSITION = 1 is not allowed when @@GLOBAL.GTID_MODE = ON。
正确写法示例:
CHANGE MASTER TO MASTER_HOST='192.168.10.100', MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='replpass', MASTER_AUTO_POSITION=1;
注意:如果主库做了备份恢复,且备份中已包含 gtid_purged 值,从库启动前需先执行 SET GLOBAL gtid_purged = 'xxx:1-100';,否则会因 GTID 集合不匹配拒绝同步。
最容易被忽略的坑:server_uuid 冲突和 errant transaction
MySQL 启动时自动生成 server_uuid 并写入 auto.cnf。如果克隆虚拟机没清空这个文件,多台实例会共用同一个 server_uuid,导致 GTID 混乱、复制中断甚至数据覆盖。
另一个隐形炸弹是 errant transaction:在从库上手动执行了写操作(比如修复数据),生成了新的 GTID。一旦主库 binlog 被 purge,这个 GTID 在其他节点上就“查无此证”,后续主从切换或新从库接入时直接卡死。
所以生产环境务必做到:
- 部署后立刻检查
SELECT @@server_uuid;,确认每台唯一 - 从库禁止任何写操作,哪怕
SET SQL_LOG_BIN=0也不行(GTID 仍会生成并写入 binlog) - 如真需修复,优先用 pt-table-sync 或主库导出导入,绕过从库写入










