快速恢复到任意时间点
在动漫哆啦A梦里,有两个让人记忆犹新的神奇法宝:可以直接到达目的地的任意门,和回到过去任何时间的时光机。动漫中的法宝与这篇介绍数据库备份的技术文章有什么关系呢?仔细琢磨一下,在数据库备份领域,这两点不恰好用户梦寐以求的两项功能吗:
- 快速恢复(数据立即可用):对于构建高可用的在线服务意义重大。一旦在线服务的数据库故障,用户希望尽可能快速的恢复新的数据库。当然在数据备份领域,有专门衡量恢复速度的指标RTO(Recovery Time Objective),指从开始恢复到完成恢复的时长。
- 恢复到任意时间点:意义在于数据管理的健壮性。由于代码bug或人工误操作产生的脏数据,是无法通过恢复最新数据修正的,必须恢复到历史时间点,或根据历史时间点的数据进行在线数据订正。通常恢复的数据所对应的历史时刻,与期望恢复的时刻是有时差的,数据备份领域为了衡量这个时差的大小,也有对应的衡量指标是RPO(Recovery Point Objective)。狭义的RPO指可恢复时间点与当前时间的时差,而本文探讨的广义RPO概念,是指可恢复时间点与任意历史时间点(包含当前时间)的时差。
正如哆啦A梦需要用两个不同的法宝,分别实现两种不同的目标。数据备份系统, 通常会使用不同的技术方案分别实现低RTO或低RPO,而难以两者兼得,即很难做到恢复到任意时间点并立即可用。我们以阿里云数据库RDS为例:
- RDS灾备实例:这项功能基于日志实时同步技术,实现多个RDS实例之间的实时同步。当原实例发生故障,业务都可以快速切换使用灾备实例,这就体现了“恢复数据立即可用”,即低RTO。然而灾备实例只能提供当前时间点的灾备恢复,无法回滚数据到过去任意时间点。当用户原实例写入了脏数据,或执行了误操作,灾备实例的数据也会同步引入了脏数据和误操作结果。因此RDS的灾备实例功能,无法做到指定任意时间点的低RPO。另外灾备实例需要用户承担两个RDS的成本,通常成本远高于仅存储备份数据的方案,这也成为用户采用该方案的顾虑之一。
- RDS备份恢复:这项功能基于数据库的冷备份和日志备份技术,通过备份数据恢复以及日志回放,实现创建一个过去任意时间点的实例(也成为RDS克隆实例),这恰好符合“恢复到任意时间点”(低RPO)的需求。然而RDS备份恢复功能并不是立即可用的,与灾备实例相比,RDS恢复功能产生的克隆实例是按需创建的,从备份数据到克隆实例的数据,需要有较长时间的数据拷贝和日志回放过程。因此RDS备份恢复功能,无法做到恢复到任意时间点的低RTO。
有没有一种解决方案能够同时解决RTO和RPO问题呢?2021年云数据库RDS和数据库备份DBS产品,针对这一痛点,联合发布了一项的新的备份恢复功能——应急恢复。该功能在原有的RDS备份恢复功能基础上,结合了基于CDM(Copy Data Management)技术的DBS沙箱功能,赋予用户同时使用任意门和时光机的能力,即分钟级快速恢复生成一个任意时间点的新数据库实例。这项功能的入口在“RDS控制台-实例列表-备份恢复-应急恢复”前端标签下可以找到。用户同样也能使用DBS控制台的导入数据源和沙箱实例功能完成相同功能的配置。
使用RDS应急恢复(DBS沙箱)功能
开启应急恢复功能
在RDS控制台,打开实例的管理页面,选择“备份恢复”标签中的“应急恢复”标签。点击“开启/管理DBS应急恢复”
接下来会跳转到DBS控制台,如果该RDS实例没有开启应急恢复功能,则会显示以下引导页面。其中前2个步骤是自动完成的,需要最多等待1分钟完成,第3步用户可选择付费模式(目前只有容量版可选)和保留天数。点击“确认”后,应急恢复功能就开启成功了。
之后页面会跳转到DBS控制台的“备份任务配置页面”,如果页面提示沙箱状态为“已开启”,表示已开启成功。注意,第一次开启RDS应急恢复(DBS沙箱)功能后,DBS还会有一段时间的数据准备过程。当准备过程结束,该页面的沙箱实例范围栏会提示可恢复的时间范围。
创建RDS应急实例
在RDS控制台应急恢复标签下,点击“创建应急实例(DBS沙箱实例)”按钮,页面会跳转到如下DBS控制台的创建沙箱实例页面。在该页面,首先选择恢复时间点(第一次开启后默认可选时间范围,为最近一次RDS备份时间到当前时间)。然后选择创建沙箱的规格、地域、专有网络,以及虚拟交换机(这些选项是为了生成打通到用户专有网络的沙箱实例IP),接下来就可以点击立即恢复。
接下来页面会跳转到DBS控制台的沙箱实例页面,用户可以看到刚创建的沙箱实例。沙箱实例的初始状态为“创建中”,大约1-2分钟后状态会变为“运行中”,同时会生成沙箱实例的地址(对于RDS MySQL应急实例为用户专有网络IP和3306端口),以及连接到该实例的DMS链接。用户可选择自行连接到沙箱实例,或通过DMS服务白屏化管理实例。
关于创建应急(沙箱)实例,需要注意几点:
- 沙箱实例“创建中”状态的持续时间,可能还与RDS原实例的日志量有关。最坏情况下,最大可能会增加10分钟的创建时间。
- 沙箱实例的账号与RDS原实例完全相同,包括客户端白名单。
- 沙箱实例是可写的,写入的数据不影响原实例,删除沙箱实例后,写入沙箱实例的数据都会丢失。
应用场景
RDS应急恢复(DBS沙箱)功能,相对原有的RDS备份恢复功能,优势在于能够更快生成一个历史时间点的实例。不过在性能、SLA和平台管理能力方面,应急实例都弱于RDS实例(当然计费比RDS实例也更低)。因此应急实例并不适合替代RDS实例作为用户的生产实例。综合以上的优缺点,我们认为应急实例适合以下几种场景:
- 开发测试:许多企业的集成测试,依赖真实的在线数据内容和数据量。面向开发者的高效开发测试平台,对测试速度和即时性的要求很高,对于测试数据库,通常要求实例立即可用,并且多个测试用例能够并发且互不干扰的访问。RDS应急实例就非常满足以上需求,用户可以快速创建多个应急(沙箱)实例,甚至可以通过OpenAPI集成到自己的CI/CD系统,搭建面向线上数据的高性能测试服务。
- 脏数据订正:运维误操作或程序bug,都可能导致用户的生产库实例写入了脏数据,通常这类错误可以被快速发现,但如何订正脏数据,成为了许多企业运维人员最头疼和不想面对的难题。此时运维人员最希望获得的帮助,就是立即有一个状态在误操作或程序bug触发前的数据库实例,作为在线实例的对照,从而通过数据对比来进行脏数据订正。RDS应急恢复例在这一场景就是解决痛点问题的最好方案。
- 历史分析:企业的历史数据分析通常比较复杂,常用的解决方案是将数据库数据导入到离线数据仓库后分析。但对于简单的历史数据报表分析,例如单实例上的SQL查询能够搞定的简单报表,用户可以用应急(沙箱)实例替代数据仓库,不仅技术难度更低,而且成本也会明显下降。
注意以上这些场景中,应急(沙箱)实例仅仅提供了最核心的一个环节,即快速恢复历史数据,并没有解决所有环节的问题。以脏数据订正场景为例,完整的解决方案需要包括数据的对比、数据轨迹查询、生成并订正数据等多个能力。DBS产品今年将主力打造这类基于应急恢复(沙箱)功能的场景化解决方案。
了解DBS沙箱背后的技术
全量、增量和日志备份,与RTO/RPO的关系
主流的数据库,例如MySQL、SQL Server、Oralce,其物理备份方案都可分为三种类型:全量备份、增量备份、日志备份三种类型。他们各自的原理、开销和对RPO影响各部相同,总结如下。
|
增量备份 |
日志备份 |
|
依赖 |
无 |
全量备份 |
全量备份 |
拷贝对象 |
全部物理文件 |
较上次备份物理文件差异 |
数据库日志(例如MySQL binlog) |
资源开销 |
一次性高开销 |
一次性低开销 |
持续低开销 |
对源库影响 |
产生锁阻塞 |
产生锁阻塞 |
无阻塞 |
对RPO影响 |
天级 |
小时/分钟级 |
秒级 |
全量备份和增量备份,产生的RPO与备份周期有关。考虑备份开销等因素,用户通常会每天或每周进行一次全量备份,或每小时或数十分钟进行一次增量备份。日志备份由于是持续运行,因此可以直接将RPO降低到秒级。当这三种备份类型组合起来,整体的RPO等于每种备份RPO的最小值。因此我们可以得到第一个结论
如果需要RPO降低到秒级,那么必须包含日志备份(因为依赖关系,也需要全量备份)
我们接下来分析备份类型与RTO的关系。通常备份数据需要经过数据拷贝,才能会恢复给目标实例使用。考虑1T的全量数据,以100MBps的速度拷贝,那么拷贝的时间将长达3个多小时,也就意味着RTO也会大于3小时。CDM/存储虚拟化技术为解决这个问题提供了全新的思路,通过将备份数据转换为快照,可以使得无论多大的备份数据量,都能在分钟或秒级时间内,完成克隆和远程挂载,即将总体RTO降低到了秒级或分钟级。
然而日志备份无法转换成快照,因此如果需要同时实现分钟/秒级的RPO和RTO,需要将日志回放的时间也考虑进去。也就是说总体RTO等于基于CDM技术的秒/分钟级RPO与日志回放RPO之和。首先,日志回放的时间与回放的数据量成正比;另一方面,全量和增量备份频率越高,那么快照频率越高,日志回放的数据量越小。第三,因为增量备份的开销远小于全量备份,因此需要尽可能使用增量备份而不是全量备份。
如果需要RTO和RPO同时降低到秒/分钟级,那么必须使用CDM/存储虚拟化技术 如果同时还需要降低源库的开销,那么必须使用高频的增量备份和低频的全量备份相结合
接下来我们会继续解读以下2个关键技术点
- 存储虚拟化
- 高频增量备份
存储虚拟化技术
存储虚拟化技术,是解决备份数据到二级数据库的拷贝问题的关键技术,也是业界各种CDM解决方案必不可少的技术点。秒级快照和克隆,是存储虚拟化技术的核心能力。将存储虚拟化技术运用到数据库备份,分为2个阶段:
- 生成只读快照:对于同一个生产库产生的不同时间的备份集,使用存储虚拟化技术的备份系统,不再将这些备份集区分在不同文件路径存储,而是按时间覆盖备份数据,每当完成新数据的写入覆盖,则创建一个新的快照。产生新的快照并写入数据,不会触发数据拷贝,因此新旧快照之间的重复数据是共享的。
- 生成可写克隆:当备份系统需要从一个备份集恢复数据时,需要选择一个快照,然后创建基于该快照的克隆。克隆是可写的,对克隆的写入不会影响已创建的快照数据,也不会影响其他克隆的数据。
业界领先的存储系统实现快照和克隆能力,主要的理论基础都是CoW(Copy-on-Write)和RoW(Redirect-on-Write),这两种设计各有利弊,工业界也有不少对这两项技术的改进实现,本文不展开论述。阿里云DBS产品针对不同的场景,综合采用了CoW和RoW两种的存储解决方案。
高频增量备份技术
数据库高频增量备份,主要关注的问题是两个开销:
- 磁盘IO开销:扫描数据文件差异造成的磁盘IO,为了降低IO开销,数据库通常会引入CBT(Changed Bock Tracking)技术。
- 实例加锁开销:PIT(point-in-time)拷贝通常需要对数据库实例加一定粒度的锁。
本文主要讨论的是RDS/MySQL实例的快速恢复,因此我们将焦点放到如何实现MySQL的CBT和无锁PIT拷贝。与SQL Server和Oracle这些商业数据库不同,MySQL作为开源数据,在CBT和无锁PIT方面,缺乏操作系统或数据库引擎层面的支持。
在CBT方面,开源MySQL都没有CBT功能,获取innodb的数据文件增量,必须扫描所有文件中的块信息。使用过xtrabackup增量备份的朋友应该都发现了这个问题,虽然一次增量备份产生的数据量远小于全量备份,但备份过程产生的磁盘IO却与全量备份相当。而xtrabackup工具的发布厂商Percona,针对这个问题在它发布的商用版本(Percona Server)中为InnoDB引擎加入了CBT功能,从而可以大幅降低增量扫描IO开销。那么问题来了,对于非Percona版本的MySQL,如何解决这个问题呢?
MySQL 5.X | MySQL 8.0 | MySQL(Percona) | SQL Server | Oracle |
|
CBT | 不支持 |
不支持 | 支持 | VSS |
RMAN |
PIT拷贝锁 |
FTRWL锁 | BACKUP锁 | 同开源MySQL版本 | VSS | RMAN |
DBS提供的备份工具针对开源MySQL/InnoDB不支持CBT功能的现状,推出了基于MySQL redolog的旁路CBT方案。帮助用户物理用哪个MySQL版本,都能够将增量备份的磁盘IO开销控制在很低范围。
在PIT拷贝锁方面,MySQL 5.X版本在拷贝Schema数据过程中会加FTRWL锁,阻塞所有DML和DDL操作。而MySQL 8.0版本在拷贝Schema数据过程中会加Backup锁,相比5.X版本的FTRWL锁粒度变轻了,只会阻塞部分的DDL操作,但仍然对源数据库实例上的业务可能产生影响。DBS提供的备份工具,引入了无锁PIT拷贝的技术,完全避免了数据库锁对业务的影响。
欢迎加入钉钉群一起讨论交流,也欢迎加入DBS团队,简历发送到cuiyun.fcy@alibaba-inc.com