当前位置:首页 > 问答 > 正文

ORA-45904错误导致数据文件瞬时恢复失败,远程修复方案分享

ORA-45904错误导致数据文件瞬时恢复失败,远程修复方案分享 基于一次真实的Oracle数据库远程支持案例记录)

那次晚上十点多,我接到一个紧急电话,是一位合作公司的数据库管理员打来的,电话那头的声音非常焦急,他说他们在进行一个常规的数据文件恢复操作时,遇到了一个从来没见过的错误,导致一个关键的业务数据库无法正常打开,业务已经完全中断。

他描述的情况是这样的:他们尝试将一个处于离线状态的数据文件进行瞬时恢复,这本应是Oracle数据库一个很常见的操作,但这次执行RECOVER DATAFILE命令后,系统没有像往常一样顺利应用归档日志,而是直接报出了一个错误:ORA-45904: 使用备份控制文件时不允许使用增量备份恢复

这个错误信息让他非常困惑,因为他非常确定,他没有使用备份的控制文件进行恢复,他使用的是当前数据库正在使用的、最新的控制文件,他反复检查了命令,确认无误,但错误依旧,由于这个错误阻止了恢复进程,数据文件一直处于需要恢复的状态,数据库自然也就无法打开,在尝试了各种他能想到的方法无果后,他选择了求助。

我通过远程桌面连接到了他的服务器,我让他复现了错误操作,确实,在执行RECOVER DATAFILE ‘/path/to/datafile.dbf’之后,控制台立刻抛出了ORA-45904错误,这个错误信息的核心意思是:恢复进程检测到当前环境被认定为“使用了备份的控制文件”,但恢复源中却包含增量备份,这是Oracle不允许的组合。

问题的关键在于,为什么系统会“认为”我们用了备份的控制文件?我们明明用的是最新的控制文件,我让他查询了视图来确认控制文件的状态,结果显示确实是当前的控制文件,这说明问题不是出在控制文件本身,而是出在恢复的上下文环境上。

ORA-45904错误导致数据文件瞬时恢复失败,远程修复方案分享

我回想起Oracle的恢复机制,在进行基于时间点恢复时,有一个重要的概念叫“INCARNATION”,你可以把它理解成数据库的“人生篇章”,每当用RESETLOGS方式打开数据库,数据库就会开启一个新的“篇章”,这个新篇章和之前的旧篇章就断开了联系。

我问他:“在这次恢复操作之前,这个数据库有没有做过不完全恢复,并且用RESETLOGS选项打开过?”

他想了想,突然记起来,大概一周前,因为一次误操作,他们确实对另一个表空间进行过时间点恢复,并用RESETLOGS打开了数据库,这就对了!这就是问题的根源。

我向他解释:虽然我们现在使用的是最新的控制文件,但这个控制文件记录的是数据库当前篇章的信息,而我们现在要恢复的这个数据文件,它的备份很可能是在上一个“人生篇章”(即RESETLOGS之前)做的,当我们尝试用当前篇章的控制文件,去恢复一个来自旧篇章的备份文件时,Oracle的恢复机制就会产生混淆,为了保护数据的一致性,它会错误地将此情景判断为“使用了不匹配的备份控制文件”,从而抛出ORA-45904错误,阻止恢复继续进行。

ORA-45904错误导致数据文件瞬时恢复失败,远程修复方案分享

我们犯了“张冠李戴”的错误:用“今生”的“身份证”(控制文件),去恢复“前世”的“身体部件”(数据文件备份),系统当然会报错。

找到了根本原因,解决方案就清晰了,我们需要告诉恢复进程:“我们现在要处理的这个数据文件备份,是属于旧篇章的,请你切换到那个上下文环境下去工作。”

具体的修复步骤如下:

第一步,我们需要先确认数据库当前的篇章信息,我让他执行了SQL命令:SELECT INCARNATION#, STATUS, RESETLOGS_CHANGE#, RESETLOGS_TIME FROM V$DATABASE_INCARNATION ORDER BY INCARNATION#;,结果果然显示,数据库目前处于第3个篇章(INCARNATION#=3),而我们要恢复的数据文件备份是在第2个篇章期间创建的。

ORA-45904错误导致数据文件瞬时恢复失败,远程修复方案分享

第二步,将数据库的恢复进程重置到正确的篇章,我让他执行:RESET DATABASE TO INCARNATION 2;,这个命令的作用就是告诉Oracle:“接下去的恢复操作,请你在第2个篇章的背景下进行。”

第三步,重新挂载数据库,执行:STARTUP MOUNT;

第四步,这也是最关键的一步,再次尝试恢复那个离线的数据文件:RECOVER DATAFILE ‘/path/to/datafile.dbf’;,这一次,命令没有报错!恢复进程开始正常地提示需要应用归档日志,并顺利地自动应用了一系列日志文件,最终显示“介质恢复完成”。

第五步,恢复完成后,将数据文件在线:ALTER DATABASE DATAFILE ‘/path/to/datafile.dbf’ ONLINE;

第六步,打开数据库:ALTER DATABASE OPEN;

当屏幕上出现“Database altered.”的成功提示时,电话那头传来了如释重负的感叹,他们立刻验证了相关业务表的数据,确认一切完整无误,整个修复过程,从定位问题到最终解决,大约用了半个小时。

这次远程修复给我们最大的启示是:在进行任何恢复操作前,尤其是对经历过RESETLOGS的数据库,一定要先搞清楚备份文件和当前数据库所处的“INCARNATION”是否一致,ORA-45904错误虽然提示信息看起来有点令人费解,但它本质上是一个保护性的措施,背后隐藏的是数据库版本一致性的重要逻辑,下次再遇到类似问题,先查V$DATABASE_INCARNATION视图,很可能就会柳暗花明。