主从切换前必须确保Seconds_Behind_Master稳定为0至少30秒,检查IO/SQL线程均为Yes,用pt-heartbeat校验延迟,停写前断开所有客户端连接,旧主执行RESET SLAVE ALL后重配复制,DNS切换需预热并规避缓存问题。
主从切换前必须验证
为 0
从库延迟没追上就切,业务立刻丢数据。不是“接近 0”,是监控里稳定显示
至少 30 秒以上。
常见错误现象:
里
忽高忽低,或卡在
(说明 IO/SQL 线程异常);这时切过去等于把断点当起点。
先检查
和
都是
用
比
更准,尤其跨机房场景
如果延迟大,别硬等,先查慢日志、主库写入突增、从库磁盘 I/O 压力
停写主库前要确认所有客户端已断开连接
MySQL 不会自动踢掉活跃连接,
只阻塞新写入,老连接还在跑 UPDATE/INSERT,一释放锁就写回旧主,造成双写分裂。
使用场景:你执行了
和锁表,但应用层连接池没回收,或者长连接还在发事务。
用
查活跃会话
配合
主动终止非系统线程(注意避开
或复制线程)
更稳妥的做法是提前在代理层(如 ProxySQL、HAProxy)下线主库节点,再操作
必须在旧主上执行,而不是新主
切完后旧主转从库,很多人顺手在新主上执行这个命令,结果清掉了新主的
,导致它无法再作为主库被其他从库连——因为 binlog 位置信息丢了。
参数差异:
只清复制元数据;
还删
和中继日志文件,更适合彻底重置角色。
旧主转从库时,在旧主上执行
,再
指向新主
新主不需要、也不应该执行该命令
执行前确保
(默认),否则中继日志残留可能撑爆磁盘
业务 DNS 切换比 VIP 漂移更容易出问题
DNS 缓存不可控,
不代表客户端 30 秒内一定刷新,Java 应用默认缓存 DNS 5 分钟(
),Go 默认永久缓存(除非显式设
)。
性能影响:VIP 方案需 keepalived + ARP 刷新,网络层生效快;DNS 方案依赖客户端行为,故障窗口难收敛。
如果必须用 DNS,应用启动时加
预热 + 定期刷新逻辑
数据库连接串里避免写死域名,改用配置中心下发 IP 或短 TTL 域名
切完立刻验证:从应用机器
,别只信本地
真正麻烦的不是命令怎么敲,是那些没打印在日志里的连接、缓存和中间件状态——它们不会报错,只会悄悄把数据写到错误的地方。
Seconds_Behind_Master0SHOW SLAVE STATUSSeconds_Behind_MasterNULLSlave_IO_RunningSlave_SQL_RunningYespt-heartbeatSeconds_Behind_MasterFLUSH TABLES WITH READ LOCKSTOP SLAVESELECT * FROM performance_schema.threads WHERE TYPE = 'FOREGROUND'KILLsystem_userRESET SLAVE ALLmaster.infoRESET SLAVERESET SLAVE ALLrelay-log.infoRESET SLAVE ALLCHANGE MASTER TO ...relay_log_purge = ONTTL=30snetworkaddress.cache.ttlGODEBUGInetAddress.getByName(...)dig +short your-db.example.comnslookup