mysql 5.7 gtid主从复制要求主库和从库gtid_mode必须同时为on,且enforce_gtid_consistency、log_slave_updates也需同步设为on;配置须写入my.cnf的[mysqld]段并重启生效,否则start slave将失败。

主从 GTID 模式不一致直接导致 START SLAVE 失败
MySQL 5.7 要启用 GTID 复制,gtid_mode 必须在主库和从库**同时为 ON**,且不能一端是 ON、另一端是 OFF 或 OFF_PERMISSIVE。只要有一端是 OFF,执行 START SLAVE 就会报错:ERROR 1777 (HY000): CHANGE MASTER TO ... requires MASTER_AUTO_POSITION = 1 when gtid_mode = ON 或更隐蔽的 Slave failed to initialize relay log info structure。
-
show variables like 'gtid_mode';必须在主、从两端分别执行,不能只查一端 - 注意区分
gtid_mode(全局开关)和enforce_gtid_consistency(事务合规性检查),后者也必须为ON,否则gtid_mode=ON无法生效 - 修改后需重启 mysqld 或执行
SET PERSIST gtid_mode = ON;(5.7.9+ 支持),但仅SET GLOBAL不持久,重启即失效
my.cnf 配置遗漏或拼写错误是最常见原因
即使 show variables 看起来是 ON,也要确认配置文件里是否真写了、有没有被注释、有没有大小写/空格干扰。比如:
-
gtid_mode=on(小写 on)有效;gtid_mode=ON(大写)也有效;但gtid_mode = true或gtid_mode=1会静默失败,启动时忽略该行 - 漏掉
enforce_gtid_consistency=true:会导致gtid_mode启动失败,日志里出现[Warning] Neither --relay-log nor --relay-log-index were used类似误导信息 - 配置写在
[client]段而非[mysqld]段,完全不生效
从库已启动过传统复制,残留旧状态干扰 GTID 初始化
如果从库之前用 MASTER_LOG_FILE/MASTER_LOG_POS 方式启动过复制,即使后来改了配置,gtid_executed 和 gtid_purged 可能仍为空或不匹配主库,导致 START SLAVE 卡在初始化阶段。
- 检查从库当前状态:
SELECT @@global.gtid_executed, @@global.gtid_purged; - 对比主库输出:
SHOW MASTER STATUS;中的Executed_Gtid_Set - 若从库
gtid_executed为空,说明它没真正执行过任何 GTID 事务,此时不能直接START SLAVE,要先用CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1; - 若从库
gtid_purged包含了主库没有的 UUID,说明 binlog 被清过但没同步 purge 信息,需手动重置:RESET MASTER;(仅限从库,且确保无其他下游依赖)
跳过错误时误设 gtid_next 导致后续 GTID 断层
当从库报错如 Last_SQL_Error: ... transaction 'xxx:12345' at master log ...,手动跳过常用 SET SESSION GTID_NEXT = 'xxx:12345'; BEGIN; COMMIT;。但这个操作本身会写入一个空事务到从库 binlog,如果从库 log_slave_updates=OFF(GTID 模式下应为 ON),该 GTID 就不会被记录进 gtid_executed,造成后续事务无法连续应用。
- 确认从库开启了
log_slave_updates=ON,否则 GTID 链会断裂 - 跳过前务必记下原事务 GTID,跳过后立即执行
SELECT @@global.gtid_executed;验证是否已包含该 GTID - 避免连续多次手动跳过——每次都会生成新 GTID,容易引发
GTID set mismatch报错
gtid_mode、enforce_gtid_consistency、log_slave_updates 三个变量必须严格对齐,且配置文件、运行时值、实际 binlog 内容三者要一致。最容易被忽略的是:改完配置没重启、重启没检查 error log 是否真加载成功、跳过事务后没验证 gtid_executed 是否更新。











