gtid是唯一能实现自动续同步的可靠方式,因其用全局唯一事务id替代位点,通过集合差集自动补全缺失事务,而位点仅是易失效的字节偏移量;启用gtid必须严格满足log_bin=on、log_slave_updates=1、enforce_gtid_consistency=on等强制配置,缺一则复制失败。

GTID 是主从复制中能真正“自动续同步”的唯一可靠方式,位点复制在生产环境里本质是手动运维陷阱。
为什么 CHANGE MASTER TO MASTER_LOG_FILE/MASTER_LOG_POS 会失效
位点不是事务锚点,只是二进制日志文件里的字节偏移量。它不携带任何语义信息:
- 主库
purge binary logs后,mysql-bin.000005被删,你指定的MASTER_LOG_FILE='mysql-bin.000005'立刻报错ERROR 1236 (HY000): Could not open log file - 从库重启或中继日志损坏,
Relay_Master_Log_File和Exec_Master_Log_Pos可能已不可信,硬套过去大概率跳过或重复执行事务 - 备份恢复时若未精确记录
SHOW MASTER STATUS时间点,mysqldump --master-data=2写入的位点和实际 binlog 状态常有毫秒级偏差
GTID 如何做到“自动找断点”
靠的是集合运算,不是猜测:
- 从库启动时设
MASTER_AUTO_POSITION=1,I/O 线程会向主库声明自己已执行的 GTID 集合:gtid_executed - 主库比对后,只推送
Retrieved_Gtid_Set - gtid_executed差集部分的事务 - 每个事务自带身份证:
3E11FA47-71CA-11E1-9E33-C80AA9429562:23,不存在“第几条事件”这种模糊概念
这解释了为什么 SET GLOBAL sql_slave_skip_counter=1 在 GTID 模式下被禁用——跳事件会破坏事务原子性,而 GTID 要求要么全执行、要么全跳过。
GTID 强制要求的配置项不是可选项
很多团队开了 gtid-mode=ON 却漏掉关键配套,导致复制直接失败:
- 从库必须开
log_bin=ON:否则无法持久化自己执行过的 GTID,下次重启就“失忆” - 必须开
log_slave_updates=1:SQL 线程回放的事务得写进自己的 binlog,否则级联复制(A→B→C)中 C 收不到 A 的 GTID -
enforce-gtid-consistency=ON不是建议,是强制前提:禁止 CREATE TEMPORARY TABLE、非确定性函数等破坏 GTID 可重放性的操作
这些不是性能优化项,而是 GTID 协议运行的底层契约。少一个,START SLAVE 就会报 ERROR 1792 或同步静默中断。
故障切换时,位点让人熬夜,GTID 一行命令搞定
主库宕机需切从库为新主库时:
- 位点模式:你得登录原主库查
SHOW MASTER STATUS(如果还能登),再登录新主库查SHOW SLAVE STATUS\G里的Relay_Master_Log_File和Exec_Master_Log_Pos,再人工算偏移、校验 binlog 是否完整……整个过程依赖运气 - GTID 模式:新主库上执行
RESET MASTER清空自身gtid_purged,其他从库执行CHANGE MASTER TO MASTER_HOST='new_master', MASTER_AUTO_POSITION=1即可,无需任何计算
真正容易被忽略的是:GTID 的“自动”建立在所有节点严格一致的配置和事务合规性之上。一旦某个节点偷偷关了 log_slave_updates,或者执行了被 enforce-gtid-consistency 拦住的语句,整个 GTID 链路就会在你看不见的地方悄悄断裂。











