应优先使用gtid主从复制,禁用master_log_file和master_log_pos;主从均需启用gtid_mode=on、enforce-gtid-consistency=true、log_bin=on、binlog_format=row,server-id互异且非0;从库须清理auto.cnf以避免uuid冲突;change master to必须设master_auto_position=1;初始化应使用--set-gtid-purged=on导出导入,严禁手动set gtid_next。

能直接用 GTID 主从复制,就别碰 MASTER_LOG_FILE 和 MASTER_LOG_POS —— 配置错一个字符、重启一次从库、UUID 冲突、事务不一致,全在这俩参数上栽过跟头。
主从都必须开启的 GTID 基础参数
不是“主库开就行”,从库也必须同步启用,否则 START SLAVE 会报错 ERROR 3021 (HY000) 或直接拒绝启动复制线程。
-
gtid_mode=ON:必须为ON,不能是OFF_PERMISSIVE等中间态 -
enforce-gtid-consistency=true:注意配置文件里是短横线,SQL 里是下划线(enforce_gtid_consistency) -
log_bin必须开启(默认 MySQL 8.0 已开),且binlog_format=ROW—— 这是 GTID 的硬性要求,STATEMENT模式下无法启用 GTID -
server-id主从必须不同,且不能为 0;建议用有意义的数字(如主库server-id=101,从库server-id=102)
从库启动前必须清理 auto.cnf
如果从库是克隆/快照自动生成的(比如 VMware 复制虚拟机、Docker cp 数据目录),/var/lib/mysql/auto.cnf 文件里的 server-uuid 会和主库一模一样 —— 导致从库无法加入 GTID 复制链,SHOW SLAVE STATUS 中 Retrieved_Gtid_Set 为空,Executed_Gtid_Set 也不更新。
- 停掉 MySQL:
systemctl stop mysqld - 删掉旧 UUID:
rm -f /var/lib/mysql/auto.cnf - 再启动:
systemctl start mysqld—— MySQL 会自动生成新server-uuid并写入该文件 - 验证:
SELECT @@server_uuid;,确认主从输出值不一致
CHANGE MASTER TO 语句必须用 GTID 模式语法
传统基于日志文件+位置的写法在这里完全失效,强行用会报错 ERROR 1777 (HY000):“When @@GLOBAL.GTID_MODE = ON, the slave must be configured with a master_auto_position value of 1”。
- 正确写法(无需指定 binlog 名和 pos):
CHANGE MASTER TO<br> MASTER_HOST='192.168.10.101',<br> MASTER_PORT=3306,<br> MASTER_USER='repl',<br> MASTER_PASSWORD='repl123',<br> MASTER_AUTO_POSITION=1;
-
MASTER_AUTO_POSITION=1是关键,它告诉从库:请自动拉取主库缺失的 GTID 区间,不要问我从哪开始 - 账号权限必须包含
REPLICATION SLAVE,且 host 不能是'localhost'(本地 socket 不走网络协议,复制连不上)
常见卡住点:从库执行 START SLAVE 后 Seconds_Behind_Master 一直是 NULL
这通常不是网络问题,而是 GTID 集合冲突或初始状态不一致。最典型的是:从库已有数据,但没清空 mysql.gtid_executed 表,或导入了带 GTID 的备份却没跳过已存在事务。
- 检查当前状态:
SELECT * FROM performance_schema.replication_connection_status\G,看LAST_ERROR_MESSAGE - 若提示 “The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires”,说明主库 binlog 被删了,需重做从库初始化
- 安全做法:从库初始化时用
mysqldump --all-databases --single-transaction --set-gtid-purged=ON导出,再导入;避免手工 SET GTID_NEXT - 不要手动执行
SET GTID_NEXT+BEGIN; COMMIT;来“骗过” GTID 检查——容易导致后续事务被跳过或重复执行
GTID 的真正难点不在配置命令,而在于理解“每个事务只能被执行一次”的约束。一旦主从 GTID 集合出现不可逆的错位(比如从库误删了某段 GTID 记录),修复成本远高于重建从库。











