首页 > 数据库 > MySQL > 关于对我司xx网数据库发生极端问题的猜想
目前,xx网数据库采用mysql AB复制进行灾备,这种方法也是目前大多数公司所使用的。
不过,因mysql AB复制是异步的,也就是说主库并不关心备库是否接收到日志并应用,所以可能会发生备库和主库的数据有延时的现象。举一个极端的例子,在主库业务量很忙的情况下,假设主库突然宕机,这时候可能会发生主库有部分日志没来得及传到备库的现象,那么备库就会比主库少数据,如果这时候启用备库接管任务,势必会造成部分数据丢失。这对于一个金融类的系统,是绝不允许的。
那么对于这个问题,大名鼎鼎的oracle是怎么做的呢?Dataguard是oracle的主从同步, dataguard有三种模式:最大性能、最大可用和最大保护。最大保护模式可以严格保证数据0丢失,但这是有代价的。在最大保护模式下,主库向备库传日志,备库接收日志并应用后,备库再给主库发一个成功应用日志的通知,主库接到这个成功应用的通知后,主库才能继续新的交易,否则主库会一直等待备库的这个成功应用日志的通知。所以说,dataguard的最大保护模式是通过损失“性能”来获取数据的绝对“安全”的。一般来说,很少有人把datagurad置于这种模式,因为性能太差。
回到mysql的AB复制,是否也有像oracle dataguard这种最大保护模式呢?答案是否定的,从mysql 5.5以后,才有一个半同步的功能,但不是真正的同步,也就是说主库也会等待备库发送日志应用成功的通知,但如果主库等了10秒还是没接到这个通知,那么主库也就不等了,继续下一个交易,所以这个同步算作是伪同步吧,也不能保证主从数据库在同一时刻数据严格一致。
针对mysql主从数据库有延时的问题,笔者也翻阅了大量的资料,最后惊讶于mysql的灾备方案种类繁多,真是“百花齐放、百家争鸣”。接下来,笔者就浅谈一下这些方案,也算是一个抛砖引玉,和大家共同探讨。
|
方案 |
描述 |
缺点 |
数据零丢失 |
日志补偿 |
自动ip漂移 |
故障切换时长 |
费用情况 |
本人是否做过该实验 |
|
mysql AB复制 |
单向数据同步 |
|
不支持 |
不支持 |
不支持 |
DBA手工切换 |
免费 |
做过 |
|
mysql AB+keepalived |
双主 |
冗余造成脑裂,主从数据不一致 |
不支持 |
不支持 |
支持 |
秒级 |
免费 |
做过 |
|
mysql+drbd+heartbeat |
这种mysql主从同步不是依赖的传输日志,而是drbd的块复制,主从数据是时时同步的, |
缺点是DBA不能手工干预(binlog是可以手工干预的),并且备库的数据在同步时不能读取。这对于mysql读写分离的架构造成了困扰。 |
支持 |
不支持(不用日志) |
支持 |
秒级 |
免费 |
做过 |
|
MHA |
需要至少三台机器,其中一台机器做为监控器,用来监控主库的状态,当主库宕机后,监控器会找一个接收到主库日志最多的备库,并将其选为新的主库。 |
也不能保证数据零丢失 |
不支持 |
支持 |
支持 |
秒级 |
免费 |
做过 |
|
MMM |
该方案笔者没有做过,不过感觉和MHA方案很像。 |
|
不支持 |
不支持 |
支持 |
秒级 |
免费 |
没做过 |
|
MySQL cluster (同步) |
MySQL cluster是数据同步复制的完美解决方案,每次事务都是双commit,所以说集群中的各个节点数据是完全一致的,不会出现脑裂的情况。如果集群中的一个节点坏了,等修复好后,数据会自动同步。 |
该集群的数据存储量不能超过集群中所有节点内存之和除以2.5。比如我MySQL cluster有5个节点,这五个节点的内存加起来是64G,那么数据存储量不能超过30G(64G/2.5~30G)。该方案费用太贵,不差钱的公司可以考虑。 |
支持 |
支持 |
支持 |
秒级 |
免费 |
没做过 |
|
MySQL+shared Disk 双机主备 |
此方案的的数据在共享存储上,所以数据只有一份,没有冗余。 此外,这个方案的主备两个节点平时只能一个节点(active)对外提供服务;另外一个节点(passive)的mysql服务是关闭状态的,只有发生故障切换时才启动。 |
数据没有冗余,平时只有一个节点对外提供服务。 |
不支持 |
不支持 |
不支持 |
手工 |
免费 |
没做过 |
|
DRBD+Pacemaker+Corosync |
对于这个方案不解释,还没来得及研究。 |
|
|
|
|
|
|
|
|
mysql+transfer |
这个方案来自由淘宝网核心DBA丁奇。他主要的思想是对从库启用了多线程(原生mysql的AB复制的从库一直都是单线程的),来解决备库发生延迟的问题 |
如果有问题,就得求爷爷告奶奶的请淘宝的丁奇来出山。 |
|
|
|
|
|
没做过 |
|
爱可生HA高可用方案(商业软件) |
1、该方案是把binlog日志放在共享存储上(共享存储10G大小就够了),这样当master数据库宕机后,slave数据库读取共享存储上的binlog来追平和master数据库的差异,从而保证slave的数据和master宕机时的数据强一致性,做到了零数据丢失。 |
付费 |
支持 |
支持 |
支持 |
秒级 |
付费 |
没做过 |
|
自己想的一个方案 |
可以把binlog日志放在共享存储上,当主库宕机后,DBA从共享存储上获取binlog,手工补齐备库的中继日志 |
主库宕机后,需要DBA手工干预补齐备库的日志。 |
支持 |
支持 |
不支持 |
手工恢复 |
免费 |
没做过 |
看到上面这些专门针对mysql灾备的方案,是不是感叹方案太多,不知用哪个好。另外,mysql的存储引擎也有好多种,每种各有利弊,所以学mysql也是一件不容易的事情。
结论:
1、针对mysql AB复制数据延迟的问题,可能几乎不会发生,因为我们的服务器在公司内网环境,网络IO或许不是瓶颈。所以备库丢数据的问题可能会是我们杞人忧天了。
不过,最近我通过淘宝核心DBA丁奇的博文,重新认识了mysql AB复制延迟问题产生的原因,他说延迟是由于mysql 主库是多线程进行事务交易,但是备库只用了单线程。为什么Mysql备库不采用多线程呢,因为备库多线程的话,无法保证备库应用日志顺序的(update和insert两条语句,谁先执行,谁后执行,造成的结果可能会是不一样的)。所以,原生的官方Mysql为了保守起见,备库只用单线程来同步日志(单线程能保证顺序应用日志);
2、如果不考虑费用问题,可以采用上表中的爱可生的商业软件来保证数据零丢失;
3、自己想了一个方案(见上表),就是把binlog放在共享存储上,当主库宕机不可用后,DBA获取共享存储上的binlog,手工在备库追平。
4、可以用上述的Mysql cluster,可以保证零数据丢失,但是该方案用的机器多,费用贵,而且数据存储量不能超过所有服务器内存之和除以2.5。
天下就没有完美的事情!
以上,是我对Mysql AB复制数据丢失风险的问题阐述,大家可以一起探讨。
你还可以参见以下链接来了解详细信息:
http://blog.itpub.net/28916011/viewspace-1719675/
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/28916011/viewspace-1752876/ ,如需转载,请注明出处,否则将追究法律责任。