GTID复制能自动找断点是因为每个事务自带唯一ID(server_uuid:transaction_id),从库通过比对gtid_executed与主库事务流自动跳过已执行事务;传统复制无此元信息,只能依赖人工指定且易失效的MASTER_LOG_FILE和MASTER_LOG_POS。

GTID复制能自动定位断点、避免重复执行、简化故障切换,而传统位点复制必须人工维护MASTER_LOG_FILE和MASTER_LOG_POS,稍有偏差就中断同步。
为什么GTID能自动找断点,而传统复制总要手动指定MASTER_LOG_FILE和MASTER_LOG_POS
因为GTID把每个事务打上了唯一“身份证”:server_uuid:transaction_id。从库启动时设MASTER_AUTO_POSITION=1,就会自动比对本地gtid_executed集合和主库发来的事务流,跳过所有已存在的GTID,只拉取缺失部分。
传统复制没有这个元信息,只能靠mysql-bin.000001+12345这种坐标定位——一旦备份时间差、日志轮转、purge binary logs误删,CHANGE MASTER TO立刻失效。
- GTID模式下,初始同步必须用
mysqldump --set-gtid-purged=ON导出,确保GTID_PURGED准确 - 传统模式下,
MASTER_LOG_FILE和MASTER_LOG_POS是必填项,且无法验证是否真实可读 - GTID的“自动”不是猜测,而是严格依赖
gtid_executed与gtid_purged的集合运算
GTID从库为何必须开log_bin和log_slave_updates=1
GTID要求从库也得“记住自己干过什么”,否则无法判断收到的GTID是否已执行过——这个记录就存在自己的binlog里。
传统从库默认不写binlog,省IO也省空间;但GTID从库不开log_bin会直接报错:ERROR 1792 (HY000): Changing the master configuration on a server running with GTID enabled is not allowed without enabling binary logging。
- 必须同时开启
log_slave_updates=1,否则从中继日志回放的事务不会写进自己的binlog,GTID链路就断了 - 级联复制(A→B→C)中,B若没开
log_slave_updates,C就收不到A的GTID,同步失败 - 这意味着GTID从库的磁盘IO和存储开销天然更高,上线前得评估容量
为什么GTID不能用sql_slave_skip_counter跳错误事务
sql_slave_skip_counter是按“事件条数”跳,而GTID是以“事务”为单位管理的。跳1条可能只跳过BEGIN或一半UPDATE,破坏原子性。
GTID强制事务粒度一致性,跳过必须基于GTID本身操作:
- 先查出错事务的GTID:
SELECT @@global.gtid_executed;+ 查SHOW SLAVE STATUS\G里的Retrieved_Gtid_Set和Executed_Gtid_Set - 再在从库执行:
SET GTID_NEXT='xxx:yyy'; BEGIN; COMMIT; SET GTID_NEXT='AUTOMATIC'; - 注意:
xxx:yyy必须是报错事务的完整GTID,不能拼错,也不能漏掉:
真正容易被忽略的是:GTID不是“开了就万事大吉”。它要求整个复制组(主+所有从)全部开启gtid_mode=ON且enforce_gtid_consistency=ON,任何一台不满足,整个链路就会降级或拒绝启动。另外,CREATE TEMPORARY TABLE、CREATE TABLE ... SELECT这类语句在GTID下直接被禁止,不是报错就是被拒绝执行。


















