gtid是大规模主从迁移的生存底线,必须开启gtid_mode=on且enforce_gtid_consistency=on,从库启用master_auto_position=1,通过对比@@gtid_executed校验全量同步完整性,严禁手动指定binlog位置。

主从复制不是“开个复制就完事”的黑盒,它在大规模迁移中极易因延迟、一致性、切流原子性三个环节崩盘。真正能撑住百亿级平滑迁移的,是把 Seconds_Behind_Master 当假象、把 GTID 当必需、把应用层写入控制当命门来处理。
为什么 Seconds_Behind_Master = 0 不能代表数据已追平
这个值只反映SQL线程当前回放位置和IO线程拉取位置的差值,不体现并行队列堆积或大事务卡点。高并发下常见现象:状态显示为0,但新插入的订单在从库查不到——因为事务还在 replication_applier_status_by_coordinator 的等待队列里没调度出去。
- 必须监控
performance_schema.replication_applier_status_by_coordinator中的APPLYING_EVENT和QUEUE_SIZE,后者持续 > 10 就说明并行压力已饱和 -
SHOW SLAVE STATUS里的Exec_Master_Log_Pos和主库SHOW MASTER STATUS的Position对比才具实际意义,但仅适用于非GTID模式 - 大事务(如全表
UPDATE或ALTER TABLE)会强制退化为单线程回放,此时Seconds_Behind_Master会跳变式飙升,且无法靠增加slave_parallel_workers缓解
切流前必须停写旧主库,而不是只改DNS或VIP
应用连接池有长连接缓存、中间件路由规则有生效延迟、JDBC驱动可能复用旧连接——这些都会导致切流后仍有写请求打到旧主库,新主库完全收不到,立刻产生双写不一致。
- 执行
SET GLOBAL read_only = ON是比FLUSH TABLES WITH READ LOCK更稳妥的选择,它不阻塞读,且可立即生效(需确认变量已写入配置文件,避免重启失效) - 切流动作必须三者同步:应用配置更新(如Spring Boot的
spring.datasource.url)、连接池强制刷新(如HikariCP调用evictAllConnections())、中间件路由规则发布(如ShardingSphere的ALTER SHARDING RULE) - 切完立刻验证:查新主库的
SELECT @@gtid_executed,与旧主库执行SELECT @@gtid_executed对比,确保新主库包含全部GTID集合;若不一致,说明有漏写
GTID 不是可选项,而是大规模迁移的生存底线
不开 GTID,你得手动找 binlog filename + position,而高流量下这个位置每秒滚动几十次。一次配错,轻则从库跳过关键事务,重则重复执行导致主键冲突或金额翻倍。
- 迁移前必须确认源库已开启
gtid_mode = ON且enforce_gtid_consistency = ON,否则无法安全启用复制 - 从库启动复制时必须用
CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1,禁用基于 position 的手工指定 - 如果源库历史未开 GTID,不要尝试在线转换——
RESET MASTER会清空所有 binlog,导致增量同步断档;应先用逻辑导出工具(如mydumper)做一次全量,再以该时刻为起点开启 GTID 复制
金仓等国产库兼容MySQL时,主从迁移要额外验什么
语法兼容不等于行为兼容。比如金仓数据库虽支持 INSERT ... ON DUPLICATE KEY UPDATE,但其内部锁机制与MySQL不同,可能导致主从间死锁顺序不一致,进而引发复制中断。
- 必须开启
mysql_compatibility_mode = on,并在从库侧显式设置SET SESSION sql_mode = 'STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER',否则某些隐式类型转换行为会不一致 - 重点校验
TINYINT(1)是否被当作布尔类型处理、DATETIME(6)微秒精度是否完整保留、JSON_EXTRACT()返回值是否带多余空格 - 使用
KES-Migrator扫描存量存储过程和触发器,它能识别出REPLACE INTO在金仓中实际被重写为INSERT ... ON CONFLICT DO UPDATE的语义差异,避免迁移后逻辑错乱
真正难的从来不是让数据跑起来,而是让数据在跑的过程中不丢、不错、不慢。主从迁移里最易被忽略的,是把“复制链路通了”当成“业务可切了”,而实际卡点永远在应用层写入控制和GTID边界校验上。











