共计 4033 个字符,预计需要花费 11 分钟才能阅读完成。
MySQL 是一个 RDBMS(关系型数据库管理系统),由瑞典 MySQL AB 公司开发,目前属于 Oracle 旗下产品。因为其体积小、速度快、领有成本低,尤其是开放源码这一特点,广受各大企业欢送,包含腾讯,阿里,百度,网易,Google,FaceBook 等互联网巨头企业。
随着互联网的高速倒退,互联网服务可用性变得越发重要,数据容灾也随之成为各企业的要害工作。在数据容灾中,数据库集群如何解决数据一致性也成为了各企业须要解决的问题。特地在一些新兴的金融服务中,MySQL 也逐步成为其外围数据库,如何保障金钱的准确性则尤为重要。MySQL 也从一开始的异步复制,到 Google 开发的半同步复制,到 MySQL 5.7 更新的 lossless 半同步复制,始终在优化集群的数据一致性问题。
尽管 MySQL 始终在优化数据的一致性问题,但问题仍然存在,使得各大企业纷纷各自设计一套 MySQL 补丁来保证数据统一。腾讯数平的 TDSQL,腾讯微信的 PhxSQL,阿里的 AliSQL,网易的 InnoSQL 等设计都是为了保证数据一致性。MySQL5.7 公布的 lossless 半同步,尽管声称 zero loss,解决了 5.6 版本中有可能呈现的 data lost 问题,但其数据一致性仍未齐全解决。
对于 MySQL 的具体介绍能够参考 MySQL 官网 PPT http://www.slideshare.net/and…
MySQL 半同步复制的问题
图 1 MySql 半同步流程
图 1 形容了 MySQL 的 Binlog 半同步过程。Wait ACK 是半同步的关键步骤,Master 把 Binlog 发给 Slave 之后,须要期待 Slave 的 ACK。Master 直到胜利收到 ACK 之后,才执行 Engine Commit 把数据长久化到 Storage。具体细节可参考:http://my-replication-life.bl…
MySQL 启动时,Wait ACK 过程会被跳过,导致 Engine Commit 会被间接执行。具体细节请参考:https://jira.mariadb.org/brow…
上面对 MySQL 的数据在 Master 和 Slave 之间是否能保障统一进行简略剖析。探讨均基于各机器数据最终是否统一来开展。 上面的剖析只针对半同步复制,且假如半同步失败后不会进化成异步复制。
场景 1:Master 失常工作
Master 的数据复制到 Slave,Slave 与 Master 保持数据统一。
场景 2:Master Crash 且不切换 Master
场景 2.1
Master 曾经收到 ACK,并执行 Engine Commit。Slave 与 Master 保持数据统一。
场景 2.2
Master 处于 Wait ACK 阶段,存在 PendingBinlog(未执行 Engine Commit 的 Binlog)。
图 2 Master 重启时执行 EngineCommit,并把 Binlog 从新复制给 Slave
Master 重启时执行 EngineCommit。Slave 从新连贯 Master,Binlog 从新开始复制,随后 Slave 数据和 Master 统一。如图 2。
因而,在 MySql5.7 的状况下,场景 2.2 能保障 Master 和 Slave 之间的数据一致性。然而在 MySQL5.6 及之前的版本,场景 2.2 是不能保证数据一致性的,具体请参考:http://my-replication-life.bl…
场景 3:Master Crash 且切换 Master
场景 3.1
旧 Master Crash 时,曾经收到至多一台 Slave 的 ACK 并执行 Engine Commit。
数据已复制到至多一台 Slave,该 Slave 与旧 Master 的数据保持一致。
场景 3.2
旧 Master 处于 Wait ACK 阶段时 Crash,新 Master 被切换到了一台领有最新 Binlog 的 Slave。
场景 3.2 中,旧 Master 中的 PendingBinlog 存在两种场景。
场景 3.2.1
旧 Master Crash 时 Binlog 发送失败,未复制给任何 Slave。
图 3 机器 A 重启 Commit Transaction X。机器 A / B 数据不统一。
图 4 机器 B 接管到事务 X 的重试申请(事务 X’)且复制到机器 A。
机器 A / B 数据可能不统一。
假如机器 A 为旧 Master,执行事务 X 时,复制失败并 Crash。随后机器 B 成为新 Master。机器 A 重启时执行 Engine Commit,事务 X 被 Commit。此时机器 A 和机器 B 的数据一致性被毁坏。两台机器上数据可能不统一。如图 3,图 4。
数据不统一的起因是机器 A 在重启时对 PendingBinlog 执行 Engine Commit。在切换了 Master 的状况下,只能通过回滚 PendingBinlog 解决。
MySQL 半同步插件的维护者也提到了相似的想法:http://my-replication-life.bl…
场景 3.2.2
旧 Master Crash 时 Binlog 发送胜利,但还未执行 Engine Commit。
!
图 6 机器 A 重启马上执行 Engine Commit,数据统一
假如机器 A 为旧 Master,执行事务 X 时在执行 Commit 前 Crash,但机器 B 收到事务 X。随后机器 B 成为新 Master。
机器 A 重启时对 PendingBinlog 执行 Engine Commit,执行胜利后机器 A 的数据是机器 B 的子集。此时机器 A 可从机器 B 中拉取最新的数据。另外一台 Slave 机器 C 能够从这两台机器中任意拉取。
从图 6 能够看出,机器 A 在呈现故障时,因为 TransactionX 曾经复制给其中一台 Slave 和重启时立即 Commit Transaction X,使得该 Slave 和 Master 的数据能保障统一。
!
图 7 两台机器呈现故障,Master 切换可能会失落数据
上述探讨都是基于领有最新数据的 Slave 和 Master 不能一起呈现故障。当这两台机器一起呈现故障时,进行 Master 切换则会造成数据失落。如图 7。
对于较小的集群(机器数目小于或者等于 3),当呈现两台机器一起产生故障时,可认为集群已无奈提供服务(半同步复制无奈工作)。
对于较大的集群(机器数目大于 3),当呈现两台机器一起产生故障,且无奈得悉该两台机器的数据状态时,该集群也无奈提供服务(无奈确认领有最新数据的 Slave 是否蕴含在故障机器中)。因而,对于较大的集群,通常减少半同步复制期待 ACK 的数目,使得呈现上述情况时,仍能进行 Master 切换(非故障机器中,存在领有最新数据的机器)。
减少期待 ACK 的数目,解决了数据失落的问题,但同时给数据回滚带来了难题。
![8]
图 8
如图 8。假如 MySQL 集群有 5 台机器,半同步复制须要期待 2 台 Slave 的 ACK。机器 A 为旧 Master,在执行 Wait ACK 阶段,机器 B 收到 Binlog 后,机器 A 和机器 B 同时 Crash 或者被隔离,导致 Binlog 复制失败。依据场景 3.2.1 的剖析,当机器 C 成为 Master 后,机器 A 和机器 B 在复原服务前须要对其进行数据回滚。但对 Slave 进行数据回滚较为艰难。且若回滚失败,则会呈现数据不统一。
对于较小的集群,回滚 PendingBinlog 比拟容易实现。但对于较大的集群,回滚 PendingBinlog 自身就是一个未解决的难题。
MySQL 的 Master 切换问题
Master 如何切换同时也是 MySQL 容灾中的一个难题。
一个简略的 Master 切换步骤:
- Pause 旧 Master
- Start 新 Master
- 更换 MySQLClient 的 Master 指向 IP
存在以下几个问题:
- 当 Master 被隔离时,如何将其变更为 Slave
解决办法:可批改 MySQL 的代码,应用 zookeeper 等内部辅助服务来主动保护 Master 的状态, 可解决 Master 被隔离后不能操作的问题。
- 如何定位领有最新 Binlog 数据的 MySQL
解决办法:能够通过人工,或者应用内部工具来检测集群每台 MySQL 的数据。但当呈现故障机器无法访问时,无奈定位。
- 如何进行数据回滚
解决办法:能够通过运维进行人工操作。
- 如何同时更换 MySQLClient 的 Master 指向 IP
同时更换所有 MySQLClient 的 Master 指向 IP 是一件不可能的事件,因为不可能同一时刻操作所有机器。
不能同时更换所有 MySQLClient 的 Master 指向 IP,导致局部 Client 会向旧 Master 发送申请,即呈现多个 Master 同时服务。在应用半同步复制的状况下,多台 MySQL 不能同时晓得 Master 的去向,使得数据可能产生不统一的状况。
![9]
图 9
图 10
假如机器 A 是旧 Master,机器 B 是新 Master,机器 C 还没收到 Master 更换的告诉依然向机器 A 复制 Binlog。User1 在 Master 切换前曾经连上机器 A 并继续写入数据。User2 在 Master 切换后开始向机器 B 写入数据。因为机器 A 能把数据复制给机器 C,机器 B 能把数据复制给机器 A,因而机器 A 和机器 B 都能胜利写入。如图 9。
因为机器 A 和机器 B 同时写入数据,数据一致性无奈保障。如图 10。
总结
从下面剖析来看,MySQL 的半同步复制和 Master 切换都存在一些有余。数据复制存在回滚难题,Master 切换存在多 Master 难题。只有解决了这两大难题,能力保障 MySQL 集群的数据一致性。
本文系微信后盾团队, 如有进犯, 请分割咱们立刻删除
OpenIMgithub 开源地址:
https://github.com/OpenIMSDK/…
OpenIM 官网:https://www.rentsoft.cn
OpenIM 官方论坛:https://forum.rentsoft.cn/
更多技术文章:
开源 OpenIM:高性能、可伸缩、易扩大的即时通讯架构
https://forum.rentsoft.cn/thr…
【OpenIM 原创】简略轻松入门 一文解说 WebRTC 实现 1 对 1 音视频通信原理
https://forum.rentsoft.cn/thr…