Oracle数据库无备份强制恢复的实战指南

 更新时间:2026年05月15日 08:43:05   作者:许彰午  
这不是教程,这是一次真实恢复过程记录,海关项目的Oracle数据库,没有备份,控制文件损坏,日志文件损坏,数据文件有损坏,最终虽然没有完全恢复成功,但过程中积累的SCN机制、oradebug修改SCN、隐藏参数等知识,值得记录,需要的朋友可以参考下

背景

某项目Oracle数据库挂了。现象:

  • 登录不了(重置了密码,orapwd命令)
  • 启动提示控制文件不一致(复制了备份的控制文件,但这步有问题)
  • 控制文件损坏(发现有数据文件也有损坏,去除后能够建立控制文件)
  • 清理了日志文件
  • 恢复了数据文件
  • 修改了_allow开头的隐藏参数
  • 打开数据报ORA-00600 [2662]错误

没有RMAN备份,没有expdp导出。只能硬着头皮强制恢复。

一、强制打开数据库的关键步骤

如果实在要强制打开数据库,参考如下关键点,再有其他错误就要一个一个看了,很麻烦。

步骤1:允许resetlogs时有脏数据

_alter system set "_allow_resetlogs_corruption"=true scope=spfile;

这个参数允许在open resetlogs时数据文件中有不一致数据。Oracle官方不建议使用,但没备份的时候,这就是最后一根稻草。

步骤2:处理ORA-01555错误

如果出现ORA-01555错误导致数据库无法open,设置:

_CORRUPTED_ROLLBACK_SEGMENTS
undo_management = 'MANUAL'

把回滚段标记为损坏,用MANUAL模式绕过自动undo管理。

步骤3:处理ORA-600 [2662]——SCN不一致

ORA-600 [2662]是SCN不一致的典型错误。参数含义:

参数含义
Arg [a]Current SCN WRAP:当前(控制文件)的SCN WRAP
Arg [b]Current SCN BASE:当前(控制文件)的SCN BASE
Arg [c]dependent SCN WRAP:目标SCN WRAP
Arg [d]dependent SCN BASE:目标SCN BASE

SCN的计算公式:

SCN = (SCN_WRAP × 4294967296) + SCN_BASE

其中4294967296 = 2^32。SCN_WRAP是高位,SCN_BASE是低位。当SCN_BASE足够大时,SCN_WRAP就会加1。

处理方法:先通过多次重启open的方法来观察Current SCN BASE增长速度。如果Current SCN BASE和dependent SCN BASE相差不远,重启几次数据库就可能打开。

步骤4:用10015事件加速SCN增长

如果差距较远,mount之后执行:

alter session set events '10015 trace name adjust_scn level 10';

然后尝试open。这个事件会加速Current SCN BASE的增长。

步骤5:启用错误模拟让10015事件生效

如果加入10015事件adjust_scn之后,Current SCN BASE增长还是很慢,某些版本必须加入:

_allow_error_simulation = TRUE

才能使10015事件生效。

步骤6:用_smu_debug_mode加速SCN WRAP增长

如果Current SCN BASE增长还是很慢:

_smu_debug_mode = 268435456

这个参数直接增长SCN WRAP,需要和_allow_error_simulation=true同时使用。

步骤7:用_minimum_giga_scn大步推进

_minimum_giga_scn = n

把SCN向前推进nG。只有Current SCN和dependent SCN相差nG时这个参数才起作用,否则无效。

步骤8:处理ORA-600[6006]和ORA-600[4137]

如果SCN号一致以后报ORA-600[6006]或ORA-600[4137],需要添加:

*.event="10513 trace name context forever,level 2"
*.db_block_checking=false

步骤9:open resetlogs后的建议

对于open resetlogs打开以后的数据库,最好将业务用户导出以后重建数据库,以防止数据库出现不可预知的错误。Oracle官方建议是open resetlogs之后需要重建数据库。

二、Oracle 11.2.0.4的SCN改法——oradebug实战

上面的参数方法在某些版本不够直接。Oracle 11.2.0.4可以用oradebug直接修改SGA中的SCN值。

第一步:计算目标SCN的十六进制值

SQL> select to_char(2723797,'XXXXXXXXXXXXXXXX') from dual;

TO_CHAR(2723797,'
-----------------
           298FD5

2723797的十六进制是0x298FD5。

第二步:设置oradebug跟踪自己的进程

SQL> oradebug setmypid
Statement processed.

第三步:查看当前SGA中的SCN值

SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00000000 00000000 00000000 ...

当前SCN是0,数据库处于mount状态。

第四步:用oradebug poke直接修改SCN

SQL> oradebug poke 0x06001AE70 8 0x0000000000298FD5
BEFORE: [06001AE70, 06001AE78) = 00000000 00000000
AFTER:  [06001AE70, 06001AE78) = 00298FD5 00000000

poke命令的参数:地址、长度、新值。8表示8字节。

第五步:验证修改后的SCN

SQL> oradebug dumpvar sga kcsgscn_
kcslf kcsgscn_ [06001AE70, 06001AEA0) = 00298FD5 00000000 ...

SCN已经从0变成了0x298FD5(即2723797)。

第六步:打开数据库

SQL> alter database open;

Database altered.

第七步:验证checkpoint SCN

SQL> select checkpoint_change#, checkpoint_change#/1024/1024/1024 SCN_WARP
     from v$database;

CHECKPOINT_CHANGE#   SCN_WARP
------------------ ----------
           2723798 .002536735

数据库成功打开,checkpoint SCN已经更新。

参数速查表

参数/事件作用备注
_allow_resetlogs_corruption=TRUE允许resetlogs时有脏数据强制打开的最后手段
_allow_terminal_recovery_corruption=TRUE允许终端恢复时有损坏配合上面一起用
_CORRUPTED_ROLLBACK_SEGMENTS标记损坏的回滚段处理ORA-01555
undo_management=MANUAL手动undo管理绕过损坏的undo表空间
event 10015 adjust_scn加速SCN BASE增长需要配合_allow_error_simulation
_allow_error_simulation=TRUE允许内部错误模拟让10015事件生效
_smu_debug_mode=268435456直接增长SCN WRAP配合_allow_error_simulation
_minimum_giga_scn=nSCN向前推进nG差距大时使用
event 10513 level 2禁止事务恢复处理ORA-600[6006]
oradebug poke直接修改SGA中的SCN11.2.0.4可用

反思

这次恢复最终没有完全成功。但过程中学到的教训:

  1. 没有备份就不要碰生产数据库——这次是从"没备份"开始的灾难链
  2. SCN是Oracle的心跳——理解SCN的WRAP/BASE结构是处理ORA-600[2662]的前提
  3. oradebug poke是核武器——直接修改SGA内存,用错了数据库就彻底废了
  4. 强制恢复后的数据库不可信——Oracle官方建议重建,这不是建议,是忠告

结果:未完全恢复,但积累了宝贵的强制恢复经验

以上就是Oracle数据库无备份强制恢复的实战指南的详细内容,更多关于Oracle无备份强制恢复的资料请关注脚本之家其它相关文章!

相关文章

  • Oracle如何通过执行计划查看查询语句是否使用索引

    Oracle如何通过执行计划查看查询语句是否使用索引

    这篇文章主要介绍了Oracle如何通过执行计划查看查询语句是否使用索引问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Oracle数据块损坏之10231内部事件不完全恢复

    Oracle数据块损坏之10231内部事件不完全恢复

    其实对于坏块来说,修复的办法还是很多的,下面这篇文章主要给大家介绍了关于Oracle数据块损坏之10231内部事件不完全恢复的相关资料,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • oracle定义常用函数的过程

    oracle定义常用函数的过程

    这篇文章主要介绍了oracle定义常用函数的过程,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Oracle通过procedure调用webservice接口的全过程

    Oracle通过procedure调用webservice接口的全过程

    存储过程是一组为了完成特定功能的sql语句集合,经过编译后存储在数据库中,用户通过制定存储过程的名字并给出参数(如果该过程带有参数)来执行他,本文介绍了Oracle通过procedure调用webservice接口的全过程,需要的朋友可以参考下
    2024-07-07
  • Oracle存储过程与函数的详细使用教程

    Oracle存储过程与函数的详细使用教程

    存储过程和函数在Oracle中被称为子程序,是指被命名的PL/SQL块,这种块可以带有参数,可以被多次调用,下面这篇文章主要给大家介绍了关于Oracle存储过程与函数的详细使用,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Oracle游标的使用实例详解

    Oracle游标的使用实例详解

    这篇文章主要给大家介绍了关于Oracle游标使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或着工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • Oracle数据块实现原理深入解读

    Oracle数据块实现原理深入解读

    Oracle对数据库数据文件(datafile)中的存储空间进行管理的单位是数据块(data block),本文将详细介绍
    2012-11-11
  • oracle 层次化查询(行政区划三级级联)

    oracle 层次化查询(行政区划三级级联)

    现在将上面的行政区划按代码分为三个级别:省(后四位为0)/市(后两位为0)/县,同时分别标出他们的级别,这样的话,便于后期根据不同的级别查询。
    2009-07-07
  • Oracle账户被锁错误:the account is locked解决方法

    Oracle账户被锁错误:the account is locked解决方法

    the account is locked意思是账户被锁定了,这种情况需要大家去解锁,这篇文章主要给大家介绍了关于Oracle账户被锁错误:the account is locked的解决方法,需要的朋友可以参考下
    2023-12-12
  • Oracle数据库的安全策略

    Oracle数据库的安全策略

    Oracle数据库的安全策略...
    2007-03-03

最新评论