# 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_corruptiontrue scopespfile;这个参数允许在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 WRAPArg [b]Current SCN BASE当前控制文件的SCN BASEArg [c]dependent SCN WRAP目标SCN WRAPArg [d]dependent SCN BASE目标SCN BASESCN的计算公式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_simulationtrue同时使用。步骤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]需要添加*.event10513 trace name context forever,level 2 *.db_block_checkingfalse步骤9open 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, ----------------- 298FD52723797的十六进制是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直接修改SCNSQL oradebug poke 0x06001AE70 8 0x0000000000298FD5 BEFORE: [06001AE70, 06001AE78) 00000000 00000000 AFTER: [06001AE70, 06001AE78) 00298FD5 00000000poke命令的参数地址、长度、新值。8表示8字节。第五步验证修改后的SCNSQL oradebug dumpvar sga kcsgscn_ kcslf kcsgscn_ [06001AE70, 06001AEA0) 00298FD5 00000000 ...SCN已经从0变成了0x298FD5即2723797。第六步打开数据库SQL alter database open; Database altered.第七步验证checkpoint SCNSQL select checkpoint_change#, checkpoint_change#/1024/1024/1024 SCN_WARP from v$database; CHECKPOINT_CHANGE# SCN_WARP ------------------ ---------- 2723798 .002536735数据库成功打开checkpoint SCN已经更新。参数速查表参数/事件作用备注_allow_resetlogs_corruptionTRUE允许resetlogs时有脏数据强制打开的最后手段_allow_terminal_recovery_corruptionTRUE允许终端恢复时有损坏配合上面一起用_CORRUPTED_ROLLBACK_SEGMENTS标记损坏的回滚段处理ORA-01555undo_managementMANUAL手动undo管理绕过损坏的undo表空间event 10015 adjust_scn加速SCN BASE增长需要配合_allow_error_simulation_allow_error_simulationTRUE允许内部错误模拟让10015事件生效_smu_debug_mode268435456直接增长SCN WRAP配合_allow_error_simulation_minimum_giga_scnnSCN向前推进nG差距大时使用event 10513 level 2禁止事务恢复处理ORA-600[6006]oradebug poke直接修改SGA中的SCN11.2.0.4可用反思这次恢复最终没有完全成功。但过程中学到的教训没有备份就不要碰生产数据库——这次是从没备份开始的灾难链SCN是Oracle的心跳——理解SCN的WRAP/BASE结构是处理ORA-600[2662]的前提oradebug poke是核武器——直接修改SGA内存用错了数据库就彻底废了强制恢复后的数据库不可信——Oracle官方建议重建这不是建议是忠告结果未完全恢复但积累了宝贵的强制恢复经验