
MySQL 5.7+ 开启 GTID 前必须停掉复制并清空 relay log
GTID 模式不能动态开启,SET GLOBAL gtid_mode = ON 会直接报错,必须先停复制、清空中继日志、再重启实例。跳过这步,后续 START SLAVE 肯定失败,错误信息通常是:ERROR 1777 (HY000): Cannot start replication when gtid_mode is ON and server_uuid is not set 或更常见的 ERROR 3021 (HY000): This operation cannot be performed with a running slave。
实操建议:
- 执行
STOP SLAVE;,确认SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running都是Off - 手动删掉
relay-log文件(路径看SHOW VARIABLES LIKE 'relay_log',默认在 datadir 下),同时删掉relay-log.index - 确保
server-id已设置且主从不重复,server-uuid由 MySQL 启动时自动生成,不要手动改
my.cnf 里这 4 个参数缺一不可且顺序敏感
只加 gtid_mode=ON 不够,enforce_gtid_consistency 必须为 ON,否则启动直接拒绝;log_bin 和 binlog_format=ROW 也得同步配齐——GTID 要求所有事务可被唯一识别,STATEMENT 格式下某些语句(如 UUID()、NOW())会导致主从不一致,MySQL 会直接拦截。
配置片段示例(必须全部存在):
server-id = 123 log_bin = mysql-bin binlog_format = ROW gtid_mode = ON enforce_gtid_consistency = ON
注意:gtid_mode 只能逐步升级:OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON,但生产环境建议一步到位(5.7.6+ 支持直接设为 ON),前提是已确认没有不支持 GTID 的语句(如 CREATE TABLE ... SELECT、用户变量赋值等)。
CHANGE MASTER TO 语句必须用 GTID 方式重连
开启 GTID 后,不能再用 MASTER_LOG_FILE 和 MASTER_LOG_POS,否则 START SLAVE 会报错:ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is enabled。
正确做法是启用自动定位:
- 先在主库查当前位置:
SELECT @@global.gtid_executed; - 从库执行:
CHANGE MASTER TO MASTER_AUTO_POSITION = 1;(不是= ON,是整数1) - 再
START SLAVE;,MySQL 自动按gtid_executed和gtid_purged对齐位点
如果主从 GTID 集合不兼容(比如从库 gtid_purged 包含了主库已清理的事务),START SLAVE 会卡住或报 ERROR 3037,这时得重搭从库或手动注入空事务补集合。
从库执行 SET SQL_LOG_BIN = 0 后容易漏 GTID
运维时习惯性关 binlog 做免同步操作,但在 GTID 模式下,SET SQL_LOG_BIN = 0 不仅不写 binlog,还会跳过 GTID 分配——这意味着该事务在从库执行后,不会产生 GTID,后续主从切换或故障恢复时,这个事务就“消失”了,可能引发数据不一致。
安全替代方案:
- 临时关闭复制:
STOP SLAVE;,做完操作再START SLAVE; - 若必须在从库写数据,确保
SQL_LOG_BIN = 1,并用BINLOG+SET GTID_NEXT显式指定 GTID(极少用,风险高) - 检查是否漏 GTID:对比主从的
SELECT @@global.gtid_executed;,差集不为空就得警惕
GTID 的本质是把“位置”变成“身份”,一旦身份丢失,就再也找不到它在哪条链上。这点比传统 file+pos 复杂得多,也更不容出错。










