← 每日面试题 学习看板

MySQL主从切换瞬间如何避免丢binlog与旧主双写?请设计可回滚的切换方案?

面试题/01实践场景题/实践场景题目/数据库与存储/MySQL主从切换瞬间如何避免丢binlog与旧主双写?请设计可回滚的切换方案?.md

要求覆盖:半同步/组复制选型、切换判定、旧主隔离、数据补偿与回滚、切换后一致性校验。


面试记录 2026-10-21

题目:MySQL主从切换瞬间如何避免丢binlog与旧主双写?请设计可回滚的切换方案?

难度:high

标签:mysql/replication,mysql/ha

评分:⭐⭐⭐☆☆(3/5)

我的回答

主从切换先要确认什么是丢 binlog 和旧主双写。丢 binlog 一般是新主已对外提供写入,但旧主还没提交滞留的 binlog,这部分就丢了;旧主双写是新主已提供服务,旧主还有写入请求,这里也会丢 binlog。核心是确保切换后恢复服务的时间,丢 binlog 要确保旧主同步完所有 binlog,但切换通常发生在旧主已经有问题时,一直等会扩大不可用,所以要划边界,通过重试、心跳确认旧主状态,并把切换期间产生的 binlog 全量转移;如果旧主已经不能服务,就放弃这部分 binlog。旧主双写则要确保切换前旧主不再提供写,双方通过协议关闭写入后再切换。

点评

优点:正确拆出两种数据风险,并提出「先切断旧主写入再切换」的 fencing 方向。

不足:缺具体机制——半同步 AFTER_SYNC、GTID 集合判定位点、撤 VIP/read_only/KILL/STONITH 四层隔离;可回滚设计缺失(反向复制、回切路径、checksum 校验);旧主彻底挂掉后的补偿方案与可接受丢失窗口没提。

补充:优先 MHA/Orchestrator 自动切换 + 人工确认,或用 Group Replication 让共识层选主,减少脑裂。

完整讲解

第一部分:知识重点剖析

切换安全的本质是「不产生两个可写主节点 + 不丢已向客户端承诺的数据」。丢数据有两种:旧主未同步的 binlog 未转移;旧主仍可写造成分叉。防丢靠半同步 AFTER_SYNC(保证客户端提交成功时至少一个从库收到)+ GTID 对齐;防双写靠 fencing:撤 VIP、set read_only=1、KILL 残留会话、必要时 STONITH 关机。

第二部分:考察方向与延伸递进

  1. 为什么 AFTER_COMMIT 可能丢数据?——主库先提交再等 ACK,崩溃时从库可能没收到。
  2. 切换后如何回滚?——旧主降为只读副本、建立反向复制,校验通过再切回。
  3. 怎么验证切换后数据一致?——GTID 集合比对 + pt-table-checksum。

第三部分:面试者参考回答

【一句话结论】 切换安全靠两件事:用半同步和 GTID 保证不丢已提交数据,用四层 fencing 保证旧主绝不能再写。

【三点展开】 第一,开启 AFTER_SYNC 半同步,客户端提交成功时至少一个从库已收到,切换时按 GTID 集合对齐,缺的部分用中继日志补偿。第二,切换前先隔离旧主:撤 VIP、设 read_only、杀会话,必要时直接关机,宁停勿双写。第三,保留旧主做反向复制,新主异常可回切,切换后跑 checksum 校验并配合业务对账。

【一句边界】 如果旧主彻底损坏,要明确「可接受丢失窗口」并写进 SLA,剩下的差异只能靠业务对账冲正,不能假装零丢失。