数据是当今Web,移动,社交,企业和云应用程序的流行货币。确保数据始终可用是任何组织的头等大事。几分钟的停机时间可能会导致收入和声誉严重损失。
没有提供高可用性(HA)的“一刀切”的方法。独特的应用程序属性,业务需求,运营能力和传统基础架构都可以影响HA技术的选择。技术只是提供HA的要素之一:人员和流程与技术本身一样关键。
MySQL已部署到许多要求可用性和可伸缩性的应用程序中。
由于每个应用程序都有不同的操作和可用性要求,因此MySQL提供了一系列经过认证和受支持的解决方案,可提供适当级别的高可用性(HA)和可伸缩性,以满足服务级别的要求。此类解决方案从复制一直到虚拟化和地理冗余的多数据中心解决方案,可实现99.999%的正常运行时间。
为应用程序选择正确的高可用性解决方案主要取决于:
MySQL支持的主要解决方案包括:
用于实现高可用性数据库服务的每种体系结构都通过其提供的正常运行时间级别来区分。这些体系结构可以分为三个主要类别:
如下图所示,这些体系结构中的每种体系结构都提供了越来越高的正常运行时间,必须将其与可能产生的更高水平的成本和复杂性进行权衡。仅部署高可用性体系结构并不能保证实际交付HA。实际上,与简单的数据复制解决方案相比,实施不当和维护不善的无共享群集可能很容易提供较低级别的可用性。
高可用依赖的是数据复制,数据复制的本质就是从一个库备份数据,然后恢复到另外一个库中去。
我们看向最简单的数据复制方案。
定期备份数据,这样即使数据丢失,也可以通过备份记录来恢复。
问题来了,如何备份?
最简单的备份方式。
备份的时候,把所有的数据复制,存放到文件中,恢复的时候再把文件中的数据复制回去,这样可以保证恢复之后数据库中的数据和备份时是完全一样的。
在MySQL中,可以使用mysqldump执行全量备份。
比如我们要全量备份数据库shop:
$mysqldump -u root -p shop > shop.sql
备份出来的文件就是一个SQL文件,就是创建数据库、表,写入数据等等这些SQL,如果要恢复数据,直接执行这个备份的SQL文件就可以了:
$mysql -uroot test < test.sql
不过,全量备份的代价非常高
不能经常全量备份。
一般来说,每天执行一次全量备份已是非常频繁。如果数据库中的数据丢了,那只能恢复到最近一次全量备份的那个时间点,这个时间点之后的数据还是丢了。
也就是说,全量备份不能做到完全无损地恢复。
有没更好方法,少丢甚至不丢数据?
每次只备份相对于上一次备份变化的那部分数据,所以每次增量备份速度更快。
MySQL自带的Binlog,就是实时的增量备份。
Binlog里面记录的就是MySQL数据的变更的操作日志,开启Binlog之后,我们对MySQL中的每次更新数据操作,都会被记录到Binlog。
Binlog可以回放,回放Binlog,就相当于把之前对数据库所有数据更新操作按照顺序重新执行了一遍,回放完成之后数据自然就恢复了。
很多数据库都有类似于MySQL Binlog的日志,原理和Binlog是一样的,备份和恢复方法也类似。
用Binlog把数据恢复到删库跑路之前的那个时刻:
$mysqlbinlog --start-datetime "2020-05-16 00:00:00"
--stop-datetime "2020-05-16 18:00:00"
/usr/local/var/mysql/binlog.000001 | mysql -uroot
这时候,数据已经恢复到当天的18点了。
定期的全量备份 + Binlog,就可以把数据恢复到任一历史时间点。
恢复数据时间很长,这期间系统一直不可用,怎么搞?
不要等着数据库宕机,才开始做恢复,平时就要恢复。
一主一从,性能佳。
实时地在主备数据库之间来同步Binlog,主库做了一次数据变更,生成一条Binlog,我们就把这一条Binlog复制到备用库并立即回放,这样就可以让备用库里面的数据和主库中的数据一直保持是一样的。一旦主库宕机,就可以立即切换到备用库上继续提供服务。
方案的问题。当我们对主库执行一次更新操作的时候,主从两个数据库更新数据实际的时序是这样的:
从库的数据有可能比主库上的数据旧。
正常情况下,主从延迟基本都是毫秒级别,可认为就是实时保持同步。
不正常的,一旦主库或者从库繁忙的时候,会出现明显的主从延迟。
很多情况下,数据库都不是突然宕机的,而是先繁忙,性能下降,最终宕机。这种情况下,很有可能主从延迟很大,如果我们把业务直接切到从库上继续读写,主从延迟这部分数据就丢了,并且这个数据丢失是不可逆的。即使事后你找回了当时主库的Binlog也是没法做到自动恢复的,因为它和从库的数据是冲突的。
简单地说,如果主库宕机并且主从存在延迟的情况下,切换到从库继续读写,可以保证业务的可用性,但是主从延迟这部分数据就丢失了。
这个时候你就需要做一个选择题了
能不能既保证数据不丢,还高可用?
自动切换,性能最差。
MySQL支持同步复制,开启同步复制时,MySQL主库会等待数据成功复制到从库之后,再给客户端返回响应。
从库宕机了怎么办?本来从库宕机对主库是完全没影响的,因为现在主库要等待从库写入成功再返回,从库宕机,主库就会一直等待从库,主库也卡死了。
得加一个从库,主库配置成:成功复制到任意一个从库就返回,只要有一个从库还活着,就不会影响主库写入数据,这样就解决了从库宕机阻塞主库的问题。
如果主库发生宕机,在两个从库中,至少有一个从库中的数据是和主库完全一样的,可以把这个库作为新的主库,继续提供服务。
至少用三台数据库服务器,但这三台的服务性能,还不如一台。