mysql主从复制中的GTID是什么_mysql全局事务ID解析

8次阅读

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。

mysql主从复制中的GTID是什么_mysql全局事务ID解析

GTID 是什么:一个事务在整套复制集群里的“身份证”

GTID(Global Transaction Identifier)不是日志位置,也不是时间戳,而是一个形如 3e11fa47-71ca-11e1-9e33-c80aa9429562:23字符串,由两部分组成:server_uuid(实例唯一标识)和 transaction_id(该实例上第几个事务)。它意味着:只要这个事务在任意一台开启了 GTID 的 MySQL 上执行过,其他节点再收到同个 GTID 就直接跳过——不重放、不冲突、不丢数据。

为什么必须开 log_binlog_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 ... selectTEMPORARY TABLE),否则一个事务可能被拆成多个 GTID 或分配重复 ID

配置完 GTID,CHANGE MASTER TO 怎么写才不翻车

传统复制要手动填 MASTER_LOG_FILEMASTER_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 或主库导出导入,绕过从库写入

text=ZqhQzanResources