GTID切换前必须停写并校验主从gtid_executed完全一致,否则报ERROR 1782;需执行FLUSH TABLES WITH READ LOCK、用MASTER_POS_WAIT等待追平、确认gtid_executed一字不差,再配置gtid_mode=ON、enforce_gtid_consistency=ON、log_bin、binlog_format=ROW和唯一server_id,并用MASTER_AUTO_POSITION=1重建复制。

GTID模式不是“开了就能省事”的开关,它能简化主从维护的前提是:所有节点配置一致、初始状态对齐、切换操作不越界。否则反而会触发ERROR 1782、ERROR 1777或复制卡在Waiting for source to。
为什么GTID切换时不能写MASTER_LOG_FILE和MASTER_LOG_POS
写了就失效——MySQL会直接忽略MASTER_AUTO_POSITION=1,退回到传统位置同步逻辑。一旦MASTER_LOG_POS超出当前binlog文件大小,立刻报错Client requested master to start replication from position > file size。
- 只保留
MASTER_HOST、MASTER_PORT、MASTER_USER、MASTER_PASSWORD、MASTER_AUTO_POSITION=1这5个参数 - 执行前必须先
RESET SLAVE ALL(注意不是RESET SLAVE),否则残留的master_log_file会干扰自动协商 - 如果从库之前是FILE/POSITION模式,切GTID前没清空旧位点,
START SLAVE后大概率卡住
切换前必须核对的三个GTID状态值
光看Seconds_Behind_Master = 0没用,真正决定能否安全切换的是三组GTID集合是否满足包含关系。
-
SELECT @@global.gtid_executed:新主库上已执行的全部事务ID,必须⊇所有从库的Executed_Gtid_Set -
SELECT @@global.gtid_purged:已被清理的GTID集合,不能<任何从库的Executed_Gtid_Set,否则报Cannot replicate because the master purged required binary logs -
SHOW SLAVE STATUS\G里的Retrieved_Gtid_Set和Executed_Gtid_Set差集必须为空,即已完全追平
开启GTID前必须停写并校验主从gtid_executed完全一致
直接改配置重启会失败,报ERROR 1782 (HY000): Statement violates GTID consistency。这不是参数顺序问题,而是数据状态不满足GTID启动前提。
- 主库执行
FLUSH TABLES WITH READ LOCK,记下SHOW MASTER STATUS中的Executed_Gtid_Set - 从库用
SELECT MASTER_POS_WAIT('binlog_file', position)等待追平(别信Seconds_Behind_Master) - 对比主从
SELECT @@global.gtid_executed输出是否一字不差;若有差异,说明存在anonymous事务(比如老版本升级残留),必须清理或重搭 - 解锁前确认所有应用写入已关闭,锁期间不能产生新事务
my.cnf里这5个参数缺一不可且顺序敏感
漏掉任何一个,GTID复制都会出问题:轻则复制中断,重则数据丢失或无法切换。
-
gtid_mode=ON(不是ON_PERMISSIVE,后者仅用于灰度过渡) -
enforce_gtid_consistency=ON(禁用CREATE TEMPORARY TABLE等不安全语句) -
log_bin(必须开启二进制日志) -
binlog_format=ROW(STATEMENT或MIXED会触发ERROR 1785) -
server_id(必须全局唯一,Docker或云环境要手动指定,避免自动生成重复)
GTID简化的是操作步骤,不是判断逻辑。真正容易被忽略的是状态校验环节——没人报错不代表状态对齐,而一次不对齐就会让后续所有切换动作失效。


















