MySQL GTID 主从切换的检查清单
来源:17golang原创
时间:2026-10-16 22:28:29 391浏览 收藏
MySQL 主库需要切换时,最容易漏掉的不是一条 SQL,而是三个状态没有同时对齐:候选节点到底执行到了哪些 GTID、旧主库是否还允许客户端写入、应用连接池是否已经离开旧地址。GTID 的价值是让副本按事务集合自动定位,但它不会替你完成角色保护和应用摘流。
官方文档:https://dev.mysql.com/doc/refman/8.4/en/
可以把切换拆成一张小清单:先对比候选节点的执行集合,再冻结旧主库写入;然后提升候选节点、用
SOURCE_AUTO_POSITION让其它副本重新跟随,最后切换应用写入口并重建连接池。任何一项没有完成,都不要把切换当成结束。
先看候选节点有没有资格接管
我处理这类切换时,第一眼不会看“延迟几秒”,而是看候选节点的 GTID 执行集合。GTID 自动定位会让副本把自己已经接收或提交的事务集合发给源库,源库只发送缺少的事务;因此检查重点是候选节点是否已经覆盖业务要求,而不是记一个旧主库的 binlog 文件名和 position。
-- 切换前读取候选节点的 GTID 与只读状态,先保存结果再做角色变更。
SELECT @@GLOBAL.gtid_mode,
@@GLOBAL.gtid_executed,
@@GLOBAL.read_only,
@@GLOBAL.super_read_only;
-- 查看复制线程和执行集合;\G 便于在运维终端逐项阅读。
SHOW REPLICA STATUS\G
如果候选节点仍有明显未应用事务,先不要提升。尤其要留意 Retrieved_Gtid_Set 与 Executed_Gtid_Set 的差别:前者表示收到的范围,后者才更接近已经执行的范围。候选节点可以暂时保持 read_only=ON 和 super_read_only=ON,复制线程仍可以应用来自源库的更新。

先挡住旧主库的写入窗口
确认候选节点能接管后,下一步是让旧主库停止接受业务写入。只停应用入口还不够,旧节点上的人工连接、后台任务或遗留连接池仍可能写入。super_read_only 会禁止客户端更新,即便连接拥有 CONNECTION_ADMIN 或旧的 SUPER 权限;复制线程仍可在副本上应用复制更新。
-- 在旧主库执行:先停复制,再阻止客户端继续写入。 STOP REPLICA; SET GLOBAL super_read_only = ON; SET GLOBAL read_only = ON; -- 再次读取变量,确认角色保护已经落地。 SELECT @@GLOBAL.read_only, @@GLOBAL.super_read_only;
这里的关键不是把变量改成 ON 就结束,而是确认应用没有继续向旧地址发写请求。切换窗口里如果旧主库仍能被业务连接写入,就可能出现两个节点各自产生新事务,后续即使 GTID 能识别事务,也不能替你解决业务分叉。
提升候选节点并重新挂接副本
候选节点成为新主库后,先解除它对客户端写入的限制。MySQL 文档说明,将 super_read_only 设为 ON 会同时打开 read_only;而关闭 read_only 时也会关闭 super_read_only。为了让检查记录更直观,可以把两个变量都显式写出。
-- 在新主库执行:关闭客户端只读保护,允许业务写入。 SET GLOBAL super_read_only = OFF; SET GLOBAL read_only = OFF; -- 在其它副本执行:改为从新主库按 GTID 自动定位。 STOP REPLICA; CHANGE REPLICATION SOURCE TO SOURCE_HOST = 'new-primary.example', SOURCE_PORT = 3306, SOURCE_USER = 'repl_user', SOURCE_PASSWORD = 'replace-with-secret', SOURCE_AUTO_POSITION = 1; START REPLICA;
SOURCE_AUTO_POSITION=1 的含义是让副本依据 GTID 集合找缺少的事务,不再填写旧源的 SOURCE_LOG_FILE 和 SOURCE_LOG_POS。示例中的主机、账号和密码只是占位符,真实环境应从受控配置注入,不能把明文凭据写进脚本仓库。

应用连接要和数据库角色一起切换
数据库角色已经变了,应用不一定马上知道。写连接如果仍指向旧主库,常见结果是连接超时、只读错误,或者旧节点曾短暂恢复后再次产生写入。更稳妥的做法是让应用只依赖一个可变的写入口,例如代理地址、服务发现记录或配置中心键;切换时更新入口,再让连接池主动失效并重建。
读连接可以继续指向副本池,但要给切换后的复制追平留出判断条件。不要仅凭 TCP 连接成功就认为拓扑完成,应同时看到副本线程在运行、执行集合能够继续增长、应用的新写请求确实进入新主库。
最后按四项复查
| 检查面 | 切换后的期望 | 仍异常时先看什么 |
|---|---|---|
| GTID | 新主库继续产生事务,其它副本按 GTID 跟随 | Executed_Gtid_Set、是否存在已清理但仍需要的 GTID |
| 只读 | 新主库可写,其它副本保持 read_only 与 super_read_only | 变量值、遗留客户端、后台任务 |
| 复制 | 副本 IO/SQL 线程运行且不再跟随旧源 | SHOW REPLICA STATUS 的 source、线程状态和错误 |
| 应用 | 写入口指向新主库,连接池已重建 | 服务发现、连接池缓存、旧地址残留 |
常见追问
有 GTID 还需要记录 binlog position 吗?
GTID 自动定位场景通常不需要依赖旧源的文件与位置,但切换记录仍应保存切换前后的 GTID 集合,便于解释候选节点是否追平以及排查缺失事务。
只设置 read_only 就够了吗?
如果需要阻止拥有高权限的客户端写入,通常还要启用 super_read_only。副本复制线程仍可应用复制更新,但人工连接和后台任务的行为要单独排查。
为什么数据库已切换,应用还是报错?
最常见原因是应用仍使用旧连接池或固定主机地址。切换数据库角色后,还要更新写入口并让连接池建立新连接,不能把数据库端的角色变更当作应用端的自动重连。
MySQL GTID 主从切换可以记成一句话:先确认执行集合,再封住旧写入;提升新主库后用自动定位重挂副本,最后让应用连接跟着新的写入口移动。把这四个现场检查点写进运行手册,切换时就不容易只完成“数据库命令”而漏掉真正影响业务的状态。
-
374 收藏
-
499 收藏
-
384 收藏
-
184 收藏
-
265 收藏
-
数据库 · MySQL | 59分钟前 | MySQL · 数据库运维 · RESOURCE_GROUP Performance Schema MySQL RESOURCE GROUP CPU 资源 SET RESOURCE GROUP369 收藏
-
数据库 · MySQL | 1小时前 | MySQL · 主从复制 · 数据一致性 MySQL复制 replicate-wild-do-table 复制过滤 CHANGE REPLICATION FILTER102 收藏
-
470 收藏
-
133 收藏
-
450 收藏
-
114 收藏
-
324 收藏
-
163 收藏
-
333 收藏
-
256 收藏
-
296 收藏
-
439 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习