知识卡片

故障切换的三重风险数据丢失外部系统不一致与脑裂

普通读书笔记卡

内容

主库失效后把某个从库提升为新主库的过程称为故障切换,自动故障切换通常包含三步: 用超时机制确认主库确实失效(没有万无一失的检测方法,只能靠超时)、选出新主库 (选举或由控制器指定,理想人选是数据最新的从库)、重新配置系统让客户端和其他 从库切到新主库。这个看似直接的流程隐藏着三重真实风险。第一,数据丢失:如果用的 是异步复制,新主库很可能没收到老主库宕机前的最后几笔写入;如果老主库后来又恢复 加入集群,可能带着新主库没见过的写入——最常见的处理方式是直接丢弃老主库这些未 复制的写入,这会打破客户对数据持久性的预期。第二,外部系统不一致:如果数据库需要 和其他外部存储协调,丢弃写入可能极其危险——GitHub真实发生过的事故:一个过时的 MySQL从库被提升为主库,因为它的自增ID计数器落后,新主库重新分配了一些已经被老 主库分配过的主键ID;这些ID同时被Redis使用,主键重用导致MySQL和Redis数据不一致, 最终造成部分私有数据泄漏给错误的用户。第三,脑裂:某些故障场景下可能同时出现两个 节点都自认为是主库的情况,如果两者都能接受写入又没有冲突解决机制,数据就可能丢失 或损坏;有些系统靠”检测到双主时关闭其中一个”(屏蔽机制)来防范,但设计粗糙时可能 导致两个节点都被误关。此外,超时时长本身也是个两难:太长意味着故障期间恢复慢, 太短又可能因临时负载峰值或网络抖动触发不必要的故障切换,反而在系统已经承压时 雪上加霜——这些没有简单解法,是不少运维团队宁愿手动做故障切换的原因。

参考来源

- 位置:《数据密集型应用系统设计》第五章《复制》"主库失效:故障切换"(源文件: _epub-src/ch5_split_001.html) - 结论依据:原文详述自动故障切换的三步流程,说明异步复制下新主库可能丢失最后 写入、GitHub事故中主键重用导致MySQL与Redis数据不一致泄漏隐私数据的真实案例、 以及脑裂场景下两个主库同时接受写入可能导致数据损坏,直接支撑本卡片对三重风险 的归纳。 - 原始内容:如果使用异步复制,则新主库可能没有收到老主库宕机前最后的写入操作…… 例如在GitHub的一场事故中,一个过时的MySQL从库被提升为主库……主键重用使得 MySQL和Redis中数据产生不一致,最后导致一些私有数据泄漏到错误的用户手中…… 这种情况称为脑裂……如果两个主库都可以接受写操作,却没有冲突解决机制,那么 数据就可能丢失或损坏。