摘要:好消息!OceanBase现推出「产品模块原理系列」内容,通过完整13篇文章帮助数据库从业者建立更系统完善的数据库知识体系。备份恢复是商业数据库中必不可少的组件之一,它为数据的可用性和可靠性提供了最后一层屏障。第八期我们来聊聊OceanBase的备份恢复。Tips:关注OceanBase公众号回复“产品原理”获取OceanBase产品模块原理简介系列已发布的7篇文章合集(该系列持续更新中)。
前言
数据库在现代IT系统中的重要性不言而喻,而数据的可用性和可靠性也是数据库的重要特性之一。备份恢复作为商业数据库必不可少的组件之一,为数据的可用性和可靠性提供了最后一层屏障。在数据库由于种种原因导致不可用时,如果有数据备份,那么就可以通过恢复功能将数据库恢复到故障之前的状态,继续为应用提供服务。
有别于常见的传统商业数据库,OceanBase是分布式的、基于无共享(Share Nothing)架构的关系型数据库,数据分布在不同可用区的节点上,由于每个可用区都有数据的完整副本,OceanBase本身就对数据可用性提供了很高的保证,能够实现RPO=0,RTO<30秒。然而从数据可用性的更高要求出发,同时为了满足某些其他的需求,OceanBase也提供了备份恢复的功能。本文从OceanBase备份恢复模块的实现出发,介绍了OceanBase备份恢复的原理,同时给OceanBase的用户提供一些关于备份恢复使用方面的建议。本文不是使用手册,不会介绍备份恢复的使用方法,详细的使用步骤请参考OceanBase官方文档库中的备份恢复使用手册。
概述
OceanBase是阿里巴巴和蚂蚁金服完全自主研发的分布式关系型数据库。与传统关系型数据库不同,OceanBase是基于LSM-Tree算法的数据库,用户数据分为内存中的部分(称为增量数据)和硬盘上的部分(称为基线数据)。用户对于数据的变更在事务提交后并不写到硬盘上,只有事务日志被写入硬盘用作崩溃恢复和同步;内存中的数据定期写入硬盘,这一过程称为合并(Major Freeze)。与传统关系型数据库相比,OceanBase的备份恢复有不同的挑战,设计和实现上也有很明显的差异。
传统单机关系型数据库或基于共享数据(Shared Data)的分布式数据库(如Oracle RAC、DB2 pureScale),数据集中在一个节点上或者分部署存储系统上(比如GPFS),此时只需在一个节点上执行备份命令,数据库实例会启动一个线程来备份数据,此时数据都在本地能够访问,容易找到一个数据全局一致快照进行备份,但备份过程通常会对应用造成一些影响。对于传统的无共享架构的分布式数据库(如DB2 DPF、Oracle Sharding)来说,数据分布在不同的数据节点上,备份则需要分别对数据库的每一个节点进行备份,每个数据库节点做与单机数据库类似的本地备份,这时候要找到全局一致的快照点较为困难。
OceanBase是基于无共享的分布式数据库,用户数据也分布在集群中的不同节点上,如果每个节点单独备份则较为难以处理和同步;同时,由于各个节点之间数据存在冗余,如果每个节点单独执行备份,则会导致备份数据重复;而要消除备份数据中的重复数据,则需要在备份时协调各个节点。因此,备份恢复采用了单独的外部模块来实现,通过元数据库(Meta Database,简称Meta DB)来分配和调度备份恢复任务。在带宽允许的情况下,该架构下的备份可以线性扩展,实现备份恢复的高可用的同时,可以按照服务器的负载和网络延时选择合适服务器读取用户数据,减少备份恢复对于应用的影响。
因此,OceanBase的备份恢复分为五个模块:Meta DB、基线备份、增量备份、基线恢复以及增量恢复。基线备份和增量备份相对独立,而基线恢复和增量恢复则联系紧密,接下来对这几个模块做逐一介绍。
元数据库Meta DB
元数据库是OceanBase备份恢复系统的大脑,控制着所有的备份恢复任务。发起、调度、操控备份恢复任务都需要通过Meta DB来实现。按照用途来分,元数据库中的表可以分为以下几类:
1. 备份配置
用作记录备份任务的参数配置,通过修改表中的数据,能够动态更改备份的相关参数;同时这些表还会记录备份运行时所需要的中间配置;
2. 基线备份
用作记录基线备份的任务信息,包括备份源集群、备份目的地、备份进度、备份结果以及备份的历史记录,要发起基线备份任务往base_data_backup表中插入相关记录即可,备份的进度可在表base_data_backup_task中看到,备份的结果和历史记录在base_data_backup_task_history表中;
3. 增量备份
用作记录增量备份的任务信息,包括备份源集群、备份目的地和备份的当前位点(checkpoint),这些信息记录在inc_data_backup表中;
4. 恢复
用作记录恢复的任务信息,恢复过程分为基线恢复和增量恢复,任务的总控信息记录在oceanbase_restore表中,基线恢复记录在base_data_restore表中,增量恢复记录在inc_data_restore表中,恢复结果和历史任务记录在oceanbase_restore_history表中。要发起、暂停备份恢复任务,都通过操作Meta DB中的表来完成,要检查备份恢复任务的状态和进度,需要查询Meta DB中的表。备份恢复模块目前可以通过OCP(OceanBase Cloud Platform,OceanBase的管控平台)来部署和调度。
备份恢复的最小粒度为租户,同时支持备份到阿里云对象存储OSS和文件系统中。
基线数据的备份
OceanBase的基线数据是合并时生成的、硬盘上的用户数据,并且仅在合并时发生变化。顾名思义,基线数据的备份指的是对这一部分数据的备份。
备份恢复中执行基线备份的模块叫做AgentServer ,图1是基线备份的架构图。
【图1】 基线备份示意图
可以看到,Meta DB的表中记录着基线备份任务的控制信息,AgentServer定期去任务总控表(base_data_backup)中查询,以获取基线备份任务;在获取任务之后,AgentServer会将基线备份任务按照一定规则拆分为若干子任务,将子任务插入到子任务表(base_data_backup_task)中,随后每个子任务由一个相关线程来执行,执行时随机选择延时低的从库(Follower),通过RPC调用来读取宏块数据,经过处理后异步写入到备份介质中,直到所有子任务都完成之后,任务记录被移动到历史表(base_data_backup_task_history)中。基线数据中既包含逻辑备份数据,也包含物理备份数据,其中包括建表语句等在内的DDL以逻辑的方式备份,用户数据则以物理的方式(即文件复制)备份,在备份数据中,也有记录备份进度元信息的索引文件。
由于基线备份通过RPC端口来拉取基线数据,而不是SQL接口,即无法通过OBProxy来进行备份,因此要求AgentServer能够直接访问到OBServer的RPC端口,建议AgentServer与OBServer部署在同一网络内。由于OceanBase架构的特点,在两次合并之间基线数据都不会发生变化。基线备份在发生合并时会被挂起,直到合并结束之后继续进行,这时候会检查已经备份的宏块,如果在新的合并中没有发生变化,则保留,否则会重新备份。为了使基线备份尽快完成,建议将基线备份的发起时间设置为合并完成之后,避免基线备份收到干扰由于合并被挂起而影响备份效率。如果一个集群的基线备份由于数据量太大而不能高效完成,可以将集群备份任务按照租户拆分为较小的任务,同时可以对备份服务进行横向扩展,即多个服务器上部署备份服务AgentServer,一起对指定集群的基线数据进行备份。
基线数据是按照合并的版本来分的,即同一个版本只需备份一次,同一版本备份多次不仅没有意义,还会对服务器负载、带宽等造成影响,因此基线备份的频率应该小于或等于合并的频率。通常来说,OceanBase在每天晚上发生一次合并,而基线数据的备份一天或者多于一天进行一次即可。具体的频率可视业务需求而定,但同时需要考虑两次基线备份之间的时间相隔越长,那么恢复到这两个版本中间某一时间点所需的时间可能就越多。
Part 5 增量数据的备份
增量备份通过拉取OceanBase的事务日志(即Clog)来备份用户实时变化的增量数据,这一过程类似于Oracle和DB2中的日志归档(log archive)。增量备份的模块是incbackupserver,与基线备份的总体架构类似,incbackupserver定期查询Meta DB中的任务控制表(inc_data_backup),获取任务后通过RPC调用读取OceanBase的Clog,然后对日志进行解析,按照事务组装成特定的格式后输出至备份介质。
与基线数据备份不同的是,增量备份是一个持续的过程,任务在发起后会一直执行,不断地备份数据变更生成的事务日志,因此增量备份任务没有历史表,任务的状态记录在inc_data_backup表中。除了任务的状态,inc_data_backup表中的另一个重要参数是增量备份位点(checkpoint),代表这个增量备份任务已经备份到的时间点,这是衡量增量备份任务进度以及是否正常运行的重要指标。增量备份虽然与基线备份集成在一起,不需单独启动进程,但是发起备份任务需要单独执行。同时增量备份也是通过RPC接口来读取数据的,因此也需要与OB部署在同一网络中。值得一提的是,OceanBase的增量备份是逻辑备份,不是物理备份,也就是说,增量备份出来的数据所包含的用户数据的变更与MySQL的binlog类似,只包含了变化的内容,没有包含数据在内存或硬盘上的物理变更。
恢复概述
OceanBase的恢复过程包含了基线恢复和增量恢复。恢复的最小粒度为租户,用户可以指定恢复结束的具体时间点,恢复程序会找到这个时间点前最近的一个基线备份,基于该版本的基线备份执行基线恢复;等基线恢复完成后,再从基线数据生成的时间点开始执行增量恢复,直至用户指定的恢复结束时间完成增量恢复。等增量恢复完成后,整个恢复任务完成。
可以看到,基线恢复和增量恢复二者密不可分,不能只执行基线恢复而不执行增量恢复,也不能跳过基线恢复只执行增量恢复。
基线数据的恢复
用户在启动恢复时,可以指定恢复具体的版本,也可以不指定版本。不指定版本时,恢复程序会去查找基线备份数据中离用户指定的恢复结束之前最近的一个成功的基线备份版本作为恢复的版本。
执行恢复的模块叫做AgentRestore,这是一个Java程序。程序启动后,会不断查询恢复任务总控表(oceanbase_restore),查找新的恢复任务。在获取新任务之后,会往基线恢复的控制表(base_data_restore)中插入一条数据,启动基线恢复。本质上来说,基线恢复是由恢复的目标集群来执行的。AgentRestore中的基线恢复线程发现基线恢复任务后,会向恢复目标集群发送一条执行基线恢复的命令:
ALTER SYSTEM RESTORE tenantFROM restoreUri
恢复的目标集群执行该命令即开始基线恢复,通过读取备份的基线数据来重构恢复租户,基线恢复的架构如图2所示。
【图2】 基线恢复的架构
可以看到,基线恢复由恢复目标集群的总控服务(RootServer)执行,通过读取基线备份中的DDL来重构原租户的元数据,通过读取和复制备份中的宏块来恢复原租户的数据。
基线恢复的进度、结果和历史信息记录在恢复目标集群sys租户的相关表中,如图中所示。AgentRestore不断通过相关表获取基线恢复任务的状态,一旦基线恢复任务完成,立刻向增量恢复的任务控制表(inc_data_restore)中插入一条数据,启动增量恢复。
Part 8 增量数据的恢复
OceanBase的增量恢复由AgentRestore来执行,增量恢复的示意图如图3所示。
【图3】 增量恢复在AgentRestore启动后,增量恢复线程开始不断扫描增量恢复任务控制表(inc_data_restore),发现新的任务后,启动下载线程开始下载增量备份的日志文件,下载完毕后,会对日志进行解压和解析,拼装成SQL语句并组装成事务,并写入恢复的目标集群租户中。下载、解析、写入这三个模块都通过多线程来提升执行效率。增量恢复的起始点是生成生成基线数据的合并发生的冻结时间(Frozen Timestamp)。基线数据中包含了备份租户在合并时的全量数据,通过执行增量恢复,能够回放从合并时间到用户指定恢复结束时间之间的数据变更,从而实现恢复到指定时间点。
虽然AgentRestore通过SQL访问目标恢复集群,但是并没有通过OBProxy来连接,而是直接连接OBServer,因此AgentRestore也需要部署在恢复集群OBServer的同一网络中。
Part 9 结论
OceanBase的分布式架构为用户数据的可用性提供了强有力的保障,备份恢复作为数据库的不可或缺的功能,为用户的数据提供了更高层次的保护。通过备份恢复功能,用户可以将数据恢复到指定的时间点,在保证数据可用性的同时,也为回滚误操作提供了解决方案。
<完>
Tips:关注OceanBase公众号回复“产品原理”获取OceanBase产品模块原理简介系列已发布的7篇文章合集(该系列持续更新中)。