MySQL 8.0 不能直接 SET GLOBAL gtid_mode = ON,因其状态机必须严格按 OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON 逐步切换,跳步会触发 ERROR 1787 并拒绝服务。

MySQL 8.0 可以在线开启 GTID,但必须严格按阶段切换 gtid_mode,跳过中间状态会直接报错退出服务。
为什么不能直接 SET GLOBAL gtid_mode = ON
MySQL 8.0 的 gtid_mode 是一个有严格迁移路径的状态机:OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON。任意跳步(比如 OFF → ON)会导致 MySQL 拒绝执行并报错 ERROR 1787 (HY000): Setting GLOBAL gtid_mode requires the server to be started with --enforce-gtid-consistency=ON 或更严重的崩溃风险。
这是因为 GTID 要求所有事务都可被唯一标识,而某些语句(如事务内建临时表、CREATE TABLE ... SELECT)在未预检时会破坏一致性。
- 必须先设
enforce_gtid_consistency = WARN运行一段时间,观察错误日志是否出现Statement violates GTID consistency - 确认无警告后,再逐步提升
gtid_mode级别 - 每一步
SET GLOBAL后需用SHOW VARIABLES LIKE 'gtid_mode'确认生效
在线开启四步操作顺序(必须严格按序)
以下命令需在 MySQL 客户端中逐条执行,且每步之间建议间隔数分钟(尤其第二、三步),确保无活跃长事务和复制冲突:
-
SET GLOBAL enforce_gtid_consistency = WARN;—— 开始捕获不兼容语句(日志里搜GTID consistency) SET GLOBAL gtid_mode = OFF_PERMISSIVE;-
SET GLOBAL gtid_mode = ON_PERMISSIVE;—— 此时新事务开始生成 GTID,旧事务仍可执行 -
SET GLOBAL gtid_mode = ON;—— 最终锁定,此后只接受带 GTID 的事务
注意:enforce_gtid_consistency 必须在第四步前设为 ON,否则最后一步会失败:
SET GLOBAL enforce_gtid_consistency = ON;
该设置本身无需重启,但若配置文件中缺失,下次重启后会丢失 —— 所以同步更新 my.cnf 的 [mysqld] 段:
gtid_mode = ON<br>enforce_gtid_consistency = ON<br>binlog_format = ROW
配置文件漏写 binlog_format = ROW 会怎样
GTID 复制强制要求 binlog_format = ROW,哪怕你在线设了 gtid_mode = ON,只要 binlog_format 是 MIXED 或 STATEMENT,后续执行 CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1 就会报错:
ERROR 1777 (HY000): CHANGE MASTER TO MASTER_AUTO_POSITION = 1 is not supported when @@GLOBAL.GTID_MODE = ON and @@GLOBAL.BINLOG_FORMAT != 'ROW'
- 检查当前值:
SHOW VARIABLES LIKE 'binlog_format'; - 在线修改:
SET GLOBAL binlog_format = ROW;(对已有连接立即生效) - 但该变量是只读的(
read_only为 ON 时不可改),此时必须改配置文件 +mysqladmin reload或重启 —— 所以一开始就要配好
从库执行 START SLAVE 前最容易忽略的点
主库开完 GTID 并导出数据后,从库导入完毕,执行 CHANGE MASTER TO 时必须用 MASTER_AUTO_POSITION = 1,而不是传统的位置参数:
CHANGE MASTER TO<br> MASTER_HOST='192.168.1.100',<br> MASTER_PORT=3306,<br> MASTER_USER='repl_user',<br> MASTER_PASSWORD='StrongP@ss123',<br> MASTER_AUTO_POSITION = 1;
常见错误:
- 忘了删掉
MASTER_LOG_FILE和MASTER_LOG_POS—— 这两个参数与MASTER_AUTO_POSITION = 1互斥,留着会报错 - 从库
server_id和主库重复 —— 导致复制线程拒绝启动,查SHOW SLAVE STATUS\G里的Seconds_Behind_Master为NULL且Slave_IO_Running: No - 从库没清空
auto.cnf(尤其是克隆虚拟机部署)——server_uuid冲突,SHOW SLAVE STATUS中Retrieved_Gtid_Set为空
真正稳定的 GTID 启用,不是靠“设完就跑”,而是靠 SHOW VARIABLES LIKE '%gtid%' 和 SELECT * FROM performance_schema.replication_connection_status\G 交叉验证每个环节是否就绪 —— 尤其是 Auto_Position 字段必须为 1,Retrieved_Gtid_Set 和 Executed_Gtid_Set 要持续增长且不为空。











