# Oracle数据库无备份强制恢复:SCN不一致、oradebug与ORA-600[2662]

Oracle数据库无备份强制恢复实战:SCN不一致、oradebug与ORA-600[2662]

这不是教程,这是一次真实恢复过程记录。海关项目的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=n SCN向前推进nG 差距大时使用
event 10513 level 2 禁止事务恢复 处理ORA-600[6006]
oradebug poke 直接修改SGA中的SCN 11.2.0.4可用

反思

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

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

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

相关推荐
lolo大魔王1 小时前
Go 语言原生 SQL 操作 MySQL 超详细全解 + 生产级项目模板(纯官方库无ORM)
数据库·sql·golang
六月雨滴2 小时前
Oracle 数据库 ASM 自动存储管理
数据库·oracle·dba
老年DBA2 小时前
ZFS存储池配置终极指南
运维·数据库
CableTech_SQH2 小时前
江苏理工学院武进绿建区协同创新园智能化建设 F5G 全光方案百盛分析报告
大数据·网络·数据库·5g·信息与通信
jimy12 小时前
Oracle云e2.1.micro优化tailscale的exit模式网速
linux·服务器·oracle
楼田莉子2 小时前
Linux网络:网络多路IO模型详解
linux·网络·数据库
wen_zhufeng2 小时前
python-dotenv 使用文档
数据库·python·oracle
phltxy2 小时前
Redis Java 集成到 Spring Boot
数据库·redis·git
dadaobusi2 小时前
PCIe的ATS和PRS
java·网络·数据库