ORACLE数据库备份入门:第二部分:4-全量和增量的恢复
1. 数据库运行状态
在开始介绍恢复前,有必要了解一下数据库的运行状态。例如,
当前数据的运行状态是READ WRITE,意为可读可写,类似的状态还有READ ONLY,他们同属于OPEN状态,可以对外提供服务。还有另外两种状态,即MOUNT和NOMOUNT。我们需要了解的是哪些操作要对应在哪个状态下进行。
1.1 NOMOUNT状态
该状态下,启动数据库主要的进程,例如PMON、SMON、LGWR、DBW等。
RMAN> startup nomount;
启动到NOMOUNT状态,需要参数文件。参数文件有两种格式,一是SPFILE,它不可编辑,由内存导出;二是PFILE,它是纯文本格式,可编辑。启动数据库时,系统自动使用SPFILE文件,默认位置为$ORACLE_HOME/dbs,文件名默认为SPFILE.ORA文件。如果SPFILE不存在,在相同位置再查找INIT.ORA。如果默认位置没有找到SPFILE和PFILE,可以指定PFILE位置,但是不支持指定SPFILE位置。
RMAN> startup nomount pfile='/home/oracle/bk/pfile.ora';
什么场景下需要这类操作?例如,将生产数据库全量备份在测试环境中进行恢复。在没有参数文件的情况下,首先要启动数据库主进程,
RMAN> startup nomount force;
恢复参数文件,
RMAN> restore spfile to '/home/oracle/bk/spfile.ora' from '/home/oracle/bk/spfile-2kkjsd8il_1_1';
创建PFILE,用于编辑修改,
RMAN> create pfile='/home/oracle/bk/pfile.ora' from spfile='/home/oracle/bk/spfile.ora';
将PFILE中参数按照测试环境进行修改,主要是路径要正确。使用编辑后的PFILE重启数据库,
RMAN> shutdown abort;
RMAN> startup nomount pfile='/home/oracle/bk/pfile.ora';
使用新的PFILE创建SPFILE,不需要指定路径,按照默认位置保存。下次启动时,不需要指定参数,可自动从SPFILE启动,
RMAN> create spfile from pfile='/home/oracle/bk/pfile.ora';
进入到NOMOUNT状态,主要的目的是恢复控制文件。
1.2 MOUNT状态
在NOMOUNT基础上启动额外的进程,如归档进程、日志传输进程等。在MOUNT状态下,数据库已经按照控制文件中记录信息加载了数据库结构,但是它不会对数据文件进行校验。启动到MOUNT状态,需要有控制文件。
从NOMOUNT状态启动到MOUNT状态,
RMAN> alter database mount;
或从停止状态直接启动到MOUNT状态,
RMAN> startup mount;
在MOUNT状态下,主要的目的是恢复数据文件和归档日志,也支持备份操作。没有打开归档模式的数据库,要求在MOUNT状态下进行备份。
1.3 OPEN状态
在数据库恢复到一致状态后,才允许打开。OPEN状态,数据库对外提供服务,允许进行备份,但是要求打开归档模式。不允许操作数据库恢复,但是它允许操作部分恢复,如数据文件、表空间等。
从MOUNT状态启动了OPEN状态,
RMAN> alter database open;
或者直接启动数据库进入OPEN状态,
RMAN> startup;
按照时间点恢复的场景下,归档的包含的内容与控制文件的内容有差距,因此需要RESET日志。例如,备份数据包含的归档,最后的SCN是200001。由于控制文件备份是最后进行的,因此它记录的最后的SCN编号是200010。这两个SCN编号之间的数据,是写在ONLINE REDO中的,不可能被包含在已经备份的归档文件中。因此,在恢复时,应用归档结束的位置就是200001,并且已经满足了一致性要求,可以打开。但是控制文件记录的结束时间点是SCN 200010,因此要在200001处进行重置,并重新开始计算SCN,最终控制文件中记录的200002到200010的信息就被丢弃掉了。重置的语法,
RMAN> alter database open resetlogs;
重置后,数据库生成新的INCARNATION,在后续章节介绍。
2. 恢复的目标时间点
在了解如何操作恢复之前,我们不得不先说一下控制文件,两者息息相关。我们先举例说明,假设的场景是所有数据都丢失了,需要从零开始恢复。
$rman target / --打开rman命令行终端
RMAN> startup nomount force; --因为参数文件没有了,所以要强制启动数据库进程。
RMAN> restore spfile from '/tmp/o1_mf_s_1072105983_j9h2vzq4_.bkp'; --从备份集中恢复参数文件
RMAN> shutdown abort; --停止数据库进程
RMAN> startup nomount; --使用恢复的参数文件启动数据库进程
RMAN> restore controlfile from '/tmp/o1_mf_s_1072105983_j9h2vzq4_.bkp'; --从备份集中恢复控制文件
RMAN> alter database mount; --有了控制文件,也就是数据库的结构信息,可以数据库启动了MOUNT状态
RMAN> restore database; --恢复所有数据文件
RMAN> set until time "to_date('2025-01-30 12:30:05','yyyy-mm-dd hh24:mi:ss')"; --设置需要将数据库恢复到的时间点
RMAN> recover database; --按照上一条命令指定的目标,恢复所有相关归档,并使所有数据文件处于一致状态
RMAN> alter database open resetlogs; --打开数据库
整体过程中,是不是在restore语句时有些疑问?为什么没有指定备份数据存放的位置?在恢复参数文件和控制文件的时候为什么要指定备份数据存放的位置?原因就在于控制文件中保存了备份的所有相关信息(catalog),包括数据文件的序号,对应的保存位置,归档日志的保存位置,日志里包括的时间和SCN等信息。在恢复控制文件之前,数据库对备份数据一无所知,所有要指定位置。恢复控制文件后,位置信息在控制文件里面了,所以不再需要指定位置了。
第二个疑问,set until是什么作用?我们知道,恢复的目标时间点的选择,是在最后一个数据文件备份结束到归档日志备份结束之间的任意时间点。如果我们不设置set until,系统将默认恢复到最新的数据,也就是将全部归档日志进行应用。如果我们需要恢复到某一时间点,就需要set until。数据库的一致点,是通过SCN号来保证的,指定恢复时间的时候,系统会找到最对应的SCN号来对应命令行中指定的时间点来进行恢复。请注意,恢复时间和SCN的对应是近似值,精确度控制在3秒之内。
我们再来看另外一种恢复语法:
RMAN> recover database until time "to_date('2025-03-04 09:44:54','yyyy-mm-dd hh24:mi:ss')";
系统会自动计算出时间对应的SCN为2000291,
也可以直接指定恢复的SCN编号,
RMAN> recover database until scn 2000291;
系统也可以计算出SCN对应的时间点。
3. 可恢复的目标范围
在计划恢复前首先要确定数据库是否满足恢复条件,判断备份数据中包含的归档文件的SCN范围,是否能覆盖一致性的最小要求。在备份开始时,系统进行Checkpoint,将buffer中的数据写入磁盘。备份数据中的归档,超始的SCN要小于等于最早的一个数据文件的checkpoint时间。例如,备份的数据文件,最小的SCN是4961812,来自于数据文件1和16(2129008的SCN来自于只读的PDB$SEED,可以忽略)。
最大的是5194150,来自于数据文件9、11、12。因此,用于恢复的归档要覆盖这个SCN范围,这是最小要求。在某些场景下,这还不能满足要求,后续章节内容会介绍。
在满足最小可恢复条件后,再来判断可恢复的范围。范围是指在进行恢复操作时,数据库可能达到的最早的时间点和最近的时间点。最早的时间点,就是最后一个数据文件备份的Checkpoint时间点,是保证数据一致性的最小的SCN号。最近的时间点,就是备份的归档日志中包含的最后的时间点,是数据库可恢复到最大的SCN号。
3.1 可恢复的最大SCN
最新的时间点的概念非常清晰,判断非常容易,通过查询归档的备份信息即可获得。例如,我们在恢复了控制文件后,即可查看归档的备份情况。
在示例中,备份数据中包括了4个归档文件,顺序号分别是74到77,对应的最大SCN号是文件77的Next SCN对应的5661627再减去1,即5661626。因为Next SCN是下一个归档的开始SCN,不包括在当前文件中。
3.2 可恢复的最小SCN
最早的时间点的判断,情况要复杂一些。数据文件的Checkpoint时间(SCN),记录在v$datafile_header视图中。一般情况下,我们找到所有数据文件中Checkpoint最大值,按照这个恢复所有的数据文件就可以达到一致。
例如,我们查看视图得到了所有数据文件的checkpoint,最大值为5194150,如果将所有数据文件通过归档应用到这个时间点,数据库会达到一致时间点。为什么只能用最大值?因为数据文件不能回退,只能向前,如果使用了一个非最大值SCN作为恢复目标,会提示ORA-01194错误。
我们尝试使用最大值SCN来恢复数据库,
出错了!还是ORA-01194,文件11需要更多的恢复才能达到一致。为什么会出现这样的问题?需要回过头看v$datafile_header视图中的FUZZY的值。我们注意到,文件11的FUZZY状态是YES,这代表什么?数据文件头中记录了Checkpoint的时间,但是在备份过程中有些数据块发生了变化,比checkpoint的时间更新。这种情况下,系统给数据文件标记为FUZZY。
可以通过查看v$datafile_copy视图,确定数据文件中数据块最大的SCN号。此视图的ABSOLUTE_FUZZY_CHANGE#字段为所有数据文件中的数据块的最大SCN号。
因此,最早的可恢复时间点就是5255755,来自于数据文件11。如果想了解每个数据文件的FUZZY情况,可以查看视图X$KCVFH,这属于高级内容,本文不作介绍,有兴趣的朋友可以自行检索。我们使用这个SCN进行恢复,
数据库完成了一致性恢复。
4. 恢复计划
当需要进行数据恢复时,要提前制定好计划,并按照计划严格地执行。计划是需要论证的,并且要进行验证的,因此在恢复前临时制定计划很难做到严谨。在设计备份策略时,我们就要同时考虑到恢复计划,并落实到文档中。有些企业比较在这方面非常成熟和专业,制定要包括恢复场景在内的《运维应急手册》,在出现问题时值班人员严格按照《手册》操作即可。《手册》的形成也经历了反复的论证和验证,根据实际运维情况进行调整,这对企业来说是非常重要的。
我们可以进行什么样的恢复?应该如何制定恢复计划?制定计划时,有一些问题需要认真的分析:
1) 恢复目的
在不同的场景下,考虑不同的恢复目标时间点。例如在存储故障后,需要恢复进行全库的最新数据恢复;在开发测试环境中,需要获得某个时间点的数据;数据文件损坏后,需要恢复单个数据文件;操作失误导致的数据删除,可能需要恢复一个表空间或一个表。不同的恢复目的,对应采用不同的恢复方法。
2) 恢复目标
包括恢复到什么位置,原机恢复还是异机恢复。恢复到什么时间点,最新的数据副本,还是某个指定的时间点。
3) 恢复控制文件选择
从哪个备份集中恢复参数文件和控制文件。我们前面说过了,控制文件里记录了备份的元数据(catalog),先备份的控制文件中不可能记录了后面发生了什么。因此,只能使用控制文件中记录了的备份数据来进行恢复。虽然我们可以手工将后面发生的备份数据进行导入控制文件中,但是依然建议恢复新的控制文件,因为它除了备份元数据还记录了数据库的结构信息。在多数情况下,恢复的目标时间是最后一次备份的时间点,因此恢复该备份数据中的控制文件即可。
如果计划按照时间点进行恢复,有一个需要特别注意的地方,控制文件中只保存最近7天的备份元数据。因此在选择恢复的控制文件时,要同时兼顾两个要素,一是,最新时间的控制文件;二是,要恢复的备份数据和控制文件时间差小于7天。举个例子:
从10月1日开始了每天的备份,最后一次备份的日期是10月20日。我们要恢复的数据可能存在于10月5日到10月15日之间,应该选择哪个日期的备份控制文件进行恢复?选择10月10日的控制文件,可以操作10月5日到10月10日的备份恢复;选择10月15日的控制文件,可以操作10月9日到10月15日的备份恢复。因此,如果恢复的可能范围大于7天,就要分两次进行。Oracle提供了另外一种技术来解决这个问题,即Catalog数据库,记录更长时间的备份元数据。这在后面的章节中会介绍。
另外,在Data Guard场景中,恢复的控制文件角色也要考虑,是primary还是standby。
结合以上问题,充分考虑到场景的可能性,制定详细的恢复计划,详细到执行的命令语法和顺序。
5. 恢复举例
有一个经典备份策略:周日做了全量备份,周一到周六都进行了增量备份,每次备份都包括归档、控制文件和参数文件,备份时间窗口为23:00到04:00。备份数据周日全量存放在/bk/full中,周一到周六的增量分别保存至/bk/1到/bk/6目录中。
5.1 全部数据恢复
场景为存储硬件在周四中午11:00发生故障,导致数据全部丢失,需要进行最新的数据副本(周三的备份)恢复。
1) 在恢复前,确认存储与文件系统路径恢复
2) 在没有参数文件情况下强制启动数据进程
[oracle ~]$ export ORACLE_SID=test
RMAN> startup nomount force;
3) 恢复SPFILE到系统默认位置
RMAN> restore spfile from '/bk/3/c-xxxxxxxxxxx.bkp';
RMAN> shutdown abort;
4) 使用恢复的SPFILE启动数据库
RMAN> startup nomount;
5) 恢复控制文件
RMAN> restore controlfile from '/bk/3/c-xxxxxxxxxxx.bkp';
6) 挂载数据库
RMAN> alter database mount;
7) 恢复全部数据文件
由于恢复了周三的控制文件,记录的备份信息包括了周日的全量和后续的三次增量备份。在没有指定恢复时间点的情况下,默认恢复全部备份数据文件。
RMAN> restore database;
8) 恢复归档日志并进行应用
不指定恢复的时间点,默认恢复并应用全部归档。
RMAN> recover database;
9) 打开数据库
备份数据中不可能存在online redo,虽然数据具备了一致性,但是不能达到控制文件中记录的最新SCN,因此必需要进行日志重置。
RMAN> alter database open resetlogs;
过程是不是比我们相像的更简单些?我们只需要保证备份的数据存在,数据库会自动调用这些备份数据,不需要考虑如何组织全量、增量和日志备份数据。这都是控制文件中记录的信息带来的好处,因此可以看出控制文件备份的重要性。
5.2 时间点恢复(PITR)
在前一个例子中,演示了如何恢复到最新的数据备份,这一部分将演示恢复到指定的时间点。如果希望恢复到某一个时间点,在语法上只需要添加until语法即可。我们再来看一个例子:周五时开发测试团队希望得到周四(假设为2025年3月13日)中午12:00的数据库,需要利用现有的备份数据来完成要求。首先,我们要考虑恢复的方法。恢复到周四中午的数据,需要周日全量,周一、周二和周三的增量。另外还是需要周三备份结束后的时间到周四中午12点之间的归档,这部分数据在周四的备份数据中可以获取。
1) 通常情况下,测试环境的存储路径和生产环境有所不同。记录好新的路径信息,为后续修改PFILE做准备。
2) 在没有参数文件情况下强制启动数据进程
[oracle ~]$ export ORACLE_SID=test
RMAN> startup nomount force;
3) 恢复SPFILE到系统默认位置
RMAN> restore spfile to '/tmp/spfile.ora' from '/bk/4/c-xxxxxxxxxxx.bkp';
RMAN> create pfile='/tmp/pfile.ora' from spfile='/tmp/spfile.ora';
RMAN> shutdown abort;
4) 修改PFILE
在PFILE中,有一些与路径相关的信息,例如:
db_recovery_file_dest='/u01/app/oracle/fast_recovery_area'
control_files='/u01/app/data/dbtest/controlfile/controlfile_01.ctl'
audit_file_dest='/u01/app/oracle/admin/dbtest/adump'
5) 使用编辑后的PFILE启动数据库
RMAN> startup nomount pfile='/tmp/pfile.ora';
RMAN> create spfile from pfile='/tmp/pfile.ora';
6) 恢复控制文件
RMAN> restore controlfile from '/bk/4/c-xxxxxxxxxxx.bkp';
7) 挂载数据库
RMAN> alter database mount;
8) 恢复数据文件
这里需要指定恢复的时间点,
RMAN> restore database until time "to_date('2025-03-13 12:00:00','yyyy-mm-dd hh24:mi:ss')";
这个命令执行的是恢复指定时间点之前的数据文件备份。因此在这个场景中,它恢复的是周日全量和周一、周二、周三增量的数据文件备份,并且自动叠加。如果不指定时间点,默认恢复全部数据,即将周四的增量也进行叠加。这与恢复全部数据文件后再应用归档是等效的。
9) 恢复归档日志并进行应用
指定恢复的时间点,
RMAN> recover database until time "to_date('2025-03-13 12:00:00','yyyy-mm-dd hh24:mi:ss')";
这个命令是按照指定的时间点,恢复归档文件并进行应用。如果不指定时间点,它将会恢复到什么时间点?答案是周四备份数据包括的全部归档。
10) 打开数据库
备份数据中不可能存在online redo,虽然数据具备了一致性,但是不能达到控制文件中记录的最新SCN,因此必需要进行日志重置。
RMAN> alter database open resetlogs;
5.3 单个表空间恢复
从我个人的使用经验来说,不建议使用单个表空间的恢复。我们先介绍一下原理,再来说原因。首先,在生产库中创建一个辅助库(auxiliary),也就是一个临时库(这在后续章节会有介绍)。在辅助库中利用RMAN来恢复所需的表空间,以及相关联的系统表空间等。再通过DUMP工具将表空间导出,并导入生产库中。即使系统层面保证了一致性,可以保证数据库正常运行,但是数据层的一致性呢?一个表空间回退了,其它表空间没有回退,极大可能导致应用的数据不一致。因此,这种方式试用的场景非常有限,要在应用层保证恢复的表空间与其它表空间没有逻辑的关联。
我们来简单的介绍一下语法:
1) 确认表空间与其它表空间没有逻辑的关联
恢复过程中强制执行,因此建议在开始前自行执行并检查结果。
如果视图返回为空,表示没有关联。如果返回了数据,按照提示将关联的表空间也要共同恢复。建议将关联的表空间一起再次进行查询,直到视图返回为空。
2) 执行恢复
将表空间与关联的表空间共同恢复
[oracle ~]$ rman target /
RMAN> recover tablespace ts01, ts02
until time "to_date('2025-03-19 19:00:00','yyyy-mm-dd hh24:mi:ss')"
auxiliary destination '/home/oracle/clone';
执行过程完全自动化,包括创建辅助库,临时文件保存在/home/oracle/clone路径中。恢复完成后,表空间状态为offline,需要手动启用。
SQL> alter tablespace ts01 online;
SQL> alter tablespace ts02 online;
5.4 单表恢复
单表恢复的过程与表空间恢复基本相同,差别在于最后的DUMP仅导出所需要的表。恢复过程也需要对表空间进行关联性校验。语法如下:
RMAN>recover table pdbuser01.t1 of pluggable database db23pdb01
until time "to_date('2025-03-19 21:40:00','yyyy-mm-dd hh24:mi:ss')"
auxiliary destination '/home/oracle/clone'
remap table pdbuser01.t1:t1new;
这里,我们以恢复PDB中的一个表为例。恢复过程中自动启用辅助库,恢复的临时文件保存在/home/oracle/clone中。语法中添加了REMAP,以重新命名的方式恢复到数据,不需要覆盖原表。请注意!恢复的表,没有导入主键等约束。
语法中可以支持仅创建DUMP文件,而不进行数据导入。设置导出路径(datapump destination)和文件名(dump file),生成的文件可以传输到其它系统中进行导入。
RMAN>recover table pdbuser01.t1,pdbuser01.t2 of pluggable database db23pdb01
until time "to_date('2025-03-19 21:40:00','yyyy-mm-dd hh24:mi:ss')"
auxiliary destination '/home/oracle/clone'
datapump destination '/home/oracle/clone/temp'
dump file 'emp_dept_exp_dump.dat'
notableimport;
6. 恢复顾问
Oracle内置的Recovery Advisor的功能,可以为一些场景提供恢复的建议。当系统检测出故障时,会自动生成一个恢复脚本。当然,这个功能不能保证在任何情况下都有效,但是作为初学者的管理员使用这个功能还是很有必要的。
还是通过一个例子来说明它的使用方法:
手工删除一个数据文件,模拟故障的发生。这时当我们执行一些语句时,系统会报出数据文件无法找到的错误。如图,
这时,在RMAN中查看错误信息。如图,
查看回复建议,
进行恢复预览,
预览中,给出了建议的恢复语法。在执行前,我们可以对这些命令进行校验,查看是否满足执行条件。语法如下,
RMAN> restore datafile 13 validate;
RMAN> recover datafile 13 validate header;
如果校验成功,可以执行恢复脚本。如图,
https://edu.csdn.net/course/detail/40454
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)