MySQL开启GTID模式后匿名复制报错,远程帮忙修复故障过程分享
- 问答
- 2025-12-27 17:49:33
- 4
(引用来源:某运维技术社区用户“漂泊的IT人”的故障处理记录帖)
那天下午,我正喝着茶,突然收到监控系统的报警短信,说是一台从库的MySQL同步进程中断了,状态是NO,心里咯噔一下,这套业务系统最近才做了主从复制的高可用改造,把复制模式改成了GTID,图的就是以后切换方便和数据一致性更可靠,没想到这才安稳了几天,就出问题了。
我赶紧连上那台报错的从库服务器,打开MySQL命令行,输入了检查复制状态的命令SHOW SLAVE STATUS\G,一大片信息刷出来,我直接盯着Last_IO_Error这个字段看,果然有报错信息,错误大意是说,尝试用一个空的GTID(就是全局事务ID)来启动复制线程,但服务器不允许这么干,因为ENFORCE_GTID_CONSISTENCY被设置成了ON,强制要求GTID的一致性。

(引用来源:故障现场MySQL错误日志截图)
错误信息原文大概是这样的:The replication receiver thread cannot start because the master has GTID_MODE = ON and the server does not have GTID_MODE = ON, and the master has ENFORCE_GTID_CONSISTENCY = ON. ... 看到这个我有点懵,因为我明明记得主从库都已经开启了GTID模式啊,为了确认,我分别在主库和从库上执行了SELECT @@GTID_MODE;查询,结果主库显示是ON,而从库显示的也是ON,这就奇怪了,两边设置一样,为什么还会报这个错?
我静下心,又把SHOW SLAVE STATUS的输出仔细看了一遍,这次我注意到了Retrieved_Gtid_Set和Executed_Gtid_Set这两个字段。Executed_Gtid_Set显示的是从库已经执行过的事务ID集合,而Retrieved_Gtid_Set显示的是从主库接收到了但还没执行的事务ID集合,我发现Retrieved_Gtid_Set这一栏是空的!这意味着从库的IO线程(负责从主库拉日志的线程)根本就没有成功接收到任何带有GTID的事件。

问题可能出在连接阶段,我重新检查了复制用户的权限,在GTID模式下,复制用户需要额外的REPLICATION SLAVE权限,这个我早就配置了,没问题,那会不会是之前某个时候,主库上还有匿名事务(就是没有GTID标识的老式事务)没同步完,导致链条断了?我又去查主库的日志,但时间点不太好找。
(引用来源:MySQL官方文档关于GTID复制的章节)
我想起之前看文档时有个印象,在开启GTID的过渡阶段,要确保主从库的数据是绝对一致的,一个常见的做法是先将主从库设置为只读,确保没有新数据写入,然后等从库完全追上主库后,再同时切换GTID模式,我怀疑是不是当初切换时,有极少量匿名的更新操作在主库上发生了,而这些操作没有被赋予GTID,从库在GTID模式下就不认这些“黑户”事务了。

时间紧迫,业务方已经在问为什么数据没更新了,我决定采用一个相对稳妥的办法:重新搭建从库,虽然有点耗时,但能彻底避免一些诡异的历史遗留问题,我的步骤是这样的:
我在主库上执行了FLUSH TABLES WITH READ LOCK;命令,让主库暂时变为只读,防止新的数据写入,迅速用mysqldump工具加上--master-data=2和--set-gtid-purged=ON参数对主库进行全量备份,这个操作会记录下备份开始时主库的GTID位置点。
我解除主库的读锁,恢复业务写入,在出问题的从库上,我彻底停止了复制进程STOP SLAVE;,并重置了复制信息RESET SLAVE ALL;,之后,我把刚才备份的数据文件导入到从库中,数据恢复完成后,最关键的一步是根据备份文件里记录的GTID位置点,来重新配置从库指向主库,我使用CHANGE MASTER TO命令,特别指定了MASTER_AUTO_POSITION = 1,这样从库就会自动从主库GTID链条的正确位置开始同步,不再需要手动指定日志文件和位置点了。
配置完成后,我怀着忐忑的心情输入START SLAVE;,立刻再次检查从库状态SHOW SLAVE STATUS\G,这次,我看到了期盼的画面:Slave_IO_Running: Yes,Slave_SQL_Running: Yes,而且Retrieved_Gtid_Set和Executed_Gtid_Set里都开始有内容了,Seconds_Behind_Master这个延迟指标也逐渐从几十秒降到了0,同步恢复了!
长舒一口气后,我反思了一下这次故障,根本原因很可能是在最初开启GTID模式时,虽然主从库设置了相同的GTID_MODE,但可能存在一个非常短暂的时间窗口,有匿名事务被写入主库的二进制日志,导致GTID复制链条在从库端无法被正确识别和接续,以后做这类切换,一定要更加谨慎,确保在绝对没有写操作的情况下进行,并且切换后要持续观察一段时间复制状态,这次算是GTID模式给我上的第一课,虽然过程紧张,但问题最终解决了,收获不小。
本文由召安青于2025-12-27发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://haoid.cn/wenda/69546.html
