Oracle在运行中很不幸遇到undo损坏
当然最好的方法是完全恢复
但如果是在没有备份的情况下undo损坏怎么办?以下就为大家介绍出现这种情况的解决办法
需要的朋友参考下
如果Oracle在运行中很不幸遇到undo损坏当然最好的方法是完全恢复不过如果没有备份可以采用一种非常规的手段(利用Oracle的隐藏参数)如果此时undo包含未提交的事务会造成一点点的数据丢失(一般都是可忍受的)如果没有未提交的事务则不会有数据丢失其主要步骤有
修改undo表空间管理为手动
设置隐藏参数(_offline_rollback_segments或_corrupted_rollback_segments)标识受影响的回滚段使Oracle忽略其上的未提交事务
手动删除受影响的回滚段和undo表空间然后重建新的undo表空间
还原undo表空间管理为自动
实验如下
Step
如果undo数据文件损坏数据库只能到mount状态open时会出现以下错误
ORA: cannot identify/lock data file see DBWR trace file
ORA: data file : I:INTEL_DATAODMSUNDOODMS
说明该undo文件已经损坏或丢失把该文件offline之后就可以打开数据库了
SQL> alter database datafile I:INTEL_DATAODMSUNDOODMS offline drop;
SQL> alter database open;
打开数据库的目的是为了找出受影响的回滚段
SQL> select segment_namestatus from dba_rollback_segs;
SEGMENT_NAME STATUS
SYSTEM ONLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
_SYSSMU_$ OFFLINE
SQL> show parameter undo
NAME TYPE VALUE
undo_management string AUTO
undo_retention integer
undo_tablespace string undo
关闭数据库
SQL> shutdown immediate;
Step
创建一个临时的pfile
SQL> create pfile=H:initODMSora from spfile;
修改pfile如下
*undo_management=manual undo表空间管理方式修改为手动
*undo_tablespace=undo 指定一个新的undo表空间
*_offline_rollback_segments=(_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$_SYSSMU_$) 把所有受影响的回滚段都列在这里
并以改pfile重新启动数据库
SQL> startup pfile=H:initODMSora
Step
手动删除受影响的回滚段
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
SQL>drop rollback segment "_SYSSMU_$";
手动删除旧的undo表空间
SQL> drop tablespace undo including contents;
重建新的undo表空间
SQL> create undo tablespace undo datafile I:INTEL_DATAODMSUNDOODMS size m;
创建新的spfile覆盖旧的spfile
SQL> create spfile from pfile=H:initODMSora;
关闭数据库
SQL> shutdown immediate;
Step
以原来的spfile启动数据库
SQL> startup;
还原undo表空间管理为自动
SQL> alter system set undo_management=auto scope=spfile;
取消隐藏参数的设置
SQL> alter system reset "_offline_rollback_segments" scope=spfile;
重启使其生效
SQL> shutdown immediate;
SQL> startup
SQL> show parameter undo
NAME TYPE VALUE
undo_management string AUTO
undo_retention integer
undo_tablespace string undo
最终检查一下
SQL> select segment_namestatus from dba_rollback_segs;
SEGMENT_NAME STATUS
SYSTEM ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE
_SYSSMU_$ ONLINE