作者介绍
颜廷义,中国农业银行研发中心系统支持部高级工程师,主要从事数据脱敏技术研究、数据库管理与维护等相关工作。
Oracle 12C中一个重要特性多租户特性被引入。12C之前,数据库实例(Oracle Instance)与数据库之间为多对一或一对一关系,若服务器上同时运行多个Oracle数据库,必须同时运行多个数据库实例,资源耗费非常大。
因此12C之前的版本中业务数据之间的隔离一般通过Schema-Tablespace模式实现;而在12C多租户体系中,一个数据库实例下可以同时运行和管理多个数据库,数据库在更高级别实现了数据的隔离。
本文以实际工作中具体数据申请为背景,对多租户体系下数据库的备份与恢复技术进行研究,形成一套详细、可用的数据备份、恢复方法,该方法既可为生产系统管理员日常备份与恢复提供参考,也值得数据恢复人员借鉴。
一、基本概念
1、多租户架构
Oracle 12C引入的新特性,主要包括多租户容器数据库(CDB)和可插拔数据库(PDB)。
CDB容器库是多租户架构下数据与元数据的逻辑容器,每个CDB由一个根容器(CDB$ROOT)、一个种子容器(PDB$SEED)和多个可插拔数据库(PDB)组成,可以在不同的PDB库中存放各个系统的业务数据,实现业务数据的隔离。
每个PDB在CDB中是相互独立存在的,在单独使用PDB时,与普通数据库无区别。
2、RMAN
RMAN(Recovery Manager)是Oracle软件自带的备份与恢复工具,主要应用于全库或数据库部件(如表空间,数据文件,控制文件等)进行物理级备份与恢复,备份方式一般分为全量备份和增量备份。
RMAN备份主要使用backup命令进行,恢复包括restore和recover两个过程,其中restore主要用于从备份集中将数据文件恢复至数据库中,recover用于在restore基础上使用日志重做事务。
3、表空间
表空间(TableSpace)是Oracle数据库中的逻辑存储结构,主要用于存放表,索引,视图等数据库对象。
在Oracle数据库中,表空间由若干segment组成,segment包含若干extent,而一个extent又包含多个连续block。
数据文件是与表空间对应的物理存储结构,一个表空间一般包括一个或多个数据文件。
4、SCN
SCN(System Change Number)系统改变号,Oracle数据库中内置的时间机制,主要用于记录检查点(checkpoint)、事务提交(commit)等重要事件发生的时间及先后顺序,SCN值主要存放在控制文件、数据文件头以及日志文件中,在数据库备份、恢复与管理过程中起重要作用。
5、控制文件(control file)
Oracle数据库中最重要的物理文件,记录了数据库的物理结构(如数据文件、日志文件的名称与具体存储位置)、检查点等信息,控制文件在数据库启动、运行及恢复时起到很重要的作用。
鉴于其重要性,为防止控制文件损坏或丢失,强烈建议在数据库中存储多份备份。
二、问题背景与分析
1、问题背景
作者在受理测试数据申请时遇到数据恢复失败问题,当按单租户数据库的恢复方法将生产数据恢复至脱敏环境时遇到大量报错,具体恢复脚本与报错信息如下,由于篇幅问题,在此只列出关键步骤:
RMAN>
run{
startup nomount pfile=/tmp/initPOOL1DB.ora ;(参数文件存放目录为/tmp/initPOOL1DB.ora)
restore controlfile from ‘/data/backup/itapdb.cf’;
alter database mount;
catalog start with ’/data/backup/’;
set newname for database to '/data/itapdb/%U';-------------->指定恢复路径
restore database ;
switch datafile all ;
recover database;
}
RMAN-03002: failure of restore command at 01/25/2018 17:39:54
RMAN-06026: some targets not found - aborting restore
RMAN-06023: no backup or copy of datafile 99 found to restore
RMAN-06023: no backup or copy of datafile 98 found to restore
RMAN-06023: no backup or copy of datafile 67 found to restore
从报错信息判断似乎是一些数据文件找不到,在反复确定恢复操作无误后初步判断是备份数据不全导致。
在与生产系统管理员多次沟通后得知该项目生产上部署在Oracle12C的多租户架构下,具体生产部署架构如下所示:
生产系统多租户部署架构
从上图中可以看出,项目(图中ITAPDB库)与其他多个项目部署在多租户架构下,每一个系统的业务数据分别存放在各自独立的PDB数据库中,所有PDB由一个容器库(CDB)来管理,共享计算资源,生产管理员只负责备份自己管理的PDB数据,主要备份脚本如下:
RMAN>backup as compressed backupset pluggable database itapdb format '/new/%d_itapdb_%t_%U_%p';
RMAN>backup archivelog all format '/new/arch%t_%s_%p';
RMAN>backup current controlfile format '/new/cf_%U';
2、问题分析
从多租户架构的定义知道,所有PDB共享一个数据库实例、一份控制文件、一份在线REDO日志文件和一组UNDO撤销数据文件。
在控制文件中记录了所有数据文件的记录和数据库的物理性更改(如新建表空间、数据文件备份、检查点发生的SCN等)。
当执行restore database、recover database操作进行全库恢复时,由于备份数据只包括ITAPDB数据库的备份文件,那么恢复时自然会报数据文件找不到错误。
为了验证分析,首先查询控制文件中包含哪些数据文件:
RMAN> report schema;
从查询结果发现报错信息中找不到的数据文件编号都是其他项目PDB数据库中的数据文件,再查询v$datafile_header动态视图:
SQL> select FILE#,CHECKPOINT_CHANGE# from v$datafile_header;
可以发现ITAPDB库的相关数据文件的文件头Checkpoint SCN值已经变化,而其他库的数据文件头SCN为零,这说明ITAPDB库的相关数据文件已经完成restore操作,SCN值已经恢复到备份时的SCN,而其他PDB库由于缺少数据文件备份,restore时报错,因此SCN值还为0,这进一步验证了分析的正确性。
对于上面的分析,有如下思考:
① 前面章节提到,在CDB容器库中包括一个CDB$ROOT、一个PDB$SEED和多个PDB数据库,其中CDB$ROOT库主要用于存储元数据等管理数据,PDB$SEED库是只读种子库,主要作为模板为其他PDB库建立时提供模板。那么CDB$ROOT、PDB$SEED两个库的备份数据是否是数据恢复必需的?
② 控制文件中记录了所有多租户架构下的数据文件、表空间等信息,当只恢复ITAPDB数据库时是否可以采用显示跳过方式规避掉其他不需要恢复的数据文件?
三、多租户备份、恢复方法研究
带着上面的疑问,经过多次数据恢复测试、问题查找与研究,我们总结出一整套Oracle 12C多租户数据库的备份、恢复方法,具体步骤如下:
① 首先联系生产管理员对CDB$ROOT、PDB$SEED和ITAPDB三个库重新进行备份,而不再只备份ITAPDB数据库的数据,备份脚本变为:
RMAN>backup as compressed backupset pluggable database "CDB$ROOT","PDB$SEED",itapdb format '/new/%d_itapdb_%t_%U_%p';
RMAN>backup archivelog all format '/new/arch%t_%s_%p';
RMAN>backup current controlfile format '/new/cf_%U';
之后将将备份数据放置到脱敏环境指定目录下(为便于后面说明,假设目录为/data/backup)。
② 创建数据库参数文件并启动至nomount状态。
参数文件中一般需要制定如下参数:
Control_files
Sga_target
Db_name
Compatible
Diagnostic_dest
SQL> startup nomount pfile=/tmp/initPOOL1DB.ora ;(参数文件存放目录为/tmp/initPOOL1DB.ora)
③ 恢复控制文件并将数据库启动到mount状态。
Rman> restore controlfile from ‘/data/backup/itapdb.cf’;
Rman> alter database mount;
④ 重新编目控制文件。
Rman>catalog start with ’/data/backup/’;
说明:由于生产系统部署在ASM存储+RAC架构下,而脱敏环境为本地磁盘+非RAC架构,生产与恢复环境的数据存放目录不一致,需要将备份文件编目至控制文件中。
⑤ 执行restore恢复数据文件。
在开始restore恢复数据文件之前,可以使用crosscheck命令对备份集有效性进行检查,对于在控制文件中记录而在数据库服务器上没有存储的备份集会被标记为expired状态。
Rman>crosscheck backup;
之后开始进行三个库的数据文件恢复,命令如下:
Rman>run{
set newname for database to '/data/itapdb/%U';-------------->指定恢复路径
restore database root ; ----------------->CDB$ROOT
restore database "PDB$SEED"; ------------->PDB$SEED
restore database ITAPDB; --------------->ITAPDB
switch datafile all ;
}
⑥ 使用归档日志进行数据恢复。
与单租户数据恢复不同,由于控制文件中记录了所有PDB数据库及其表空间信息,如果在恢复时不跳过相应PDB对应的表空间,使用recover database恢复会报如下错误:
RMAN-06067: RECOVER DATABASE required with a backup or created control file
通过显式跳过,可以offline并drop掉不需要恢复的PDB和对应的表空间。具体恢复方法如下:
Rman> Run {
recover database skip forever tablespace
PDB2:SYSTEM,
PDB2:USER,
PDB2:SYSAUX,..... ; ----此处需要根据具体情况进行修改
}
此外在恢复过程中可能会遇到restore或recover过程缓慢甚至停滞的问题,主要表现为在alert<SID>.log日志文件中报大量ASMB进程错误,该问题主要由Oracle bug导致,触发条件一般为生产上部署架构(ASM+RAC)与数据恢复环境(非RAC+本地磁盘)部署架构不一致导致,针对该问题可登录MOS网站(My Oracle Support)下载相应补丁并进行打补丁操作。
启动数据库:
Rman> Alter database open resetlogs ;
最后通过resetlogs方式启动数据库,至此数据恢复成功。
四、问题总结
本文就测试数据申请中遇到的具体问题为切入点,对Oracle12C多租户架构下的备份与还原方法进行了研究和总结,从整个过程来看,其备份与恢复方法与单租户架构恢复有较大差异,具体差异主要体现在以下三个方面:
① 在数据备份方面,除需备份存放有业务数据的PDB数据库外,也许备份CDB$ROOT和PDB$SEED库。
② 在restore恢复数据文件阶段,由于多个PDB可插拔数据库共用一份控制文件及存储与计算资源,需在数据恢复时显示指定需恢复的数据库。
③ 在使用日志文件进行数据恢复的过程中,需要使用recover database skip forever tablespace命令显示跳过不需恢复的PDB对应表空间。
目前,考虑到生产系统的重要性,生产系统基本都部署在物理机+RAC集群环境中。
若为数据量较小项目单独提供物理机+RAC环境势必会对服务器资源提出更高的要求。
Oracle 12C多租户体系特性可以在一定程度上解决服务器资源瓶颈的问题,可以考虑将多个数据量较小项目部署在多租户架构下,每个PDB数据库独立存放各自的业务数据,多个PDB数据库共享一个实例。
后期在Oracle多租户逐渐成为主流的情况下,该方法具有较强的前瞻性,对Oracle数据库的管理与维护是一个很好的补充,很值得生产管理员、数据导入与脱敏人员的借鉴。