[Oracle] 解析在没有备份的情况下undo损坏怎么办

如果oracle在运行中很不幸遇到undo损坏,当然最好的方法是完全恢复,不过如果没有备份,可以采用一种非常规的手段(利用oracle的隐藏参数),如果此时undo包含未提交的事务,会造成一点点的数据丢失(一般都是可忍受的),如果没有未提交的事务,则不会有数据丢失。其主要步骤有:

1. 修改undo表空间管理为手动;
2. 设置隐藏参数(_offline_rollback_segments或_corrupted_rollback_segments)标识受影响的回滚段,使oracle忽略其上的未提交事务;
3. 手动删除受影响的回滚段和undo表空间,然后重建新的undo表空间;
4. 还原undo表空间管理为自动。

实验如下:
step 1.
如果undo数据文件损坏,数据库只能到mount状态,open时会出现以下错误:
ora-01157: cannot identify/lock data file 14 – see dbwr trace file
ora-01110: data file 14: ‘i:\intel_data\o06dms0\undo1.o06dms0’
说明该undo文件已经损坏或丢失,把该文件offline之后就可以打开数据库了:
sql> alter database datafile ‘i:\intel_data\o06dms0\undo1.o06dms0’ offline drop;
sql> alter database open;
打开数据库的目的是为了找出受影响的回滚段:
sql> select segment_name,status from dba_rollback_segs;

segment_name                   status
—————————— —————-
system                         online
_syssmu10_1201331463$          offline
_syssmu9_2926456744$           offline
_syssmu8_640224757$            offline
_syssmu7_3984293596$           offline
_syssmu6_3694658906$           offline
_syssmu5_3475919656$           offline
_syssmu4_168502732$            offline
_syssmu3_1987193959$           offline
_syssmu2_3908286755$           offline
_syssmu1_3281912951$           offline

sql> show parameter undo

name                                 type        value
———————————— ———– ————-
undo_management                      string      auto
undo_retention                       integer     900
undo_tablespace                      string      undo1
关闭数据库:
sql> shutdown immediate;

step 2.
创建一个临时的pfile:
sql> create pfile=’h:\inito06dms0.ora’ from spfile;
修改pfile如下:
*.undo_management=’manual’   — undo表空间管理方式修改为手动
*.undo_tablespace=’undo2′     –指定一个新的undo表空间
*._offline_rollback_segments=(‘_syssmu10_1201331463$’,’_syssmu9_2926456744$’,’_syssmu8_640224757$’,’_syssmu7_3984293596$’,’_syssmu6_3694658906$’,’_syssmu5_3475919656$’,’_syssmu4_168502732$’,’_syssmu3_1987193959$’,’_syssmu2_3908286755$’,’_syssmu1_3281912951$’)  –把所有受影响的回滚段都列在这里
并以改pfile重新启动数据库:
sql> startup pfile=’h:\inito06dms0.ora’

step 3.
手动删除受影响的回滚段:
sql>drop rollback segment “_syssmu10_1201331463$”;
sql>drop rollback segment “_syssmu9_2926456744$”;
sql>drop rollback segment “_syssmu8_640224757$”;
sql>drop rollback segment “_syssmu7_3984293596$”;
sql>drop rollback segment “_syssmu6_3694658906$”;
sql>drop rollback segment “_syssmu5_3475919656$”;
sql>drop rollback segment “_syssmu4_168502732$”;
sql>drop rollback segment “_syssmu3_1987193959$”;
sql>drop rollback segment “_syssmu2_3908286755$”;
sql>drop rollback segment “_syssmu1_3281912951$”;
手动删除旧的undo表空间:
sql> drop tablespace undo1 including contents;
重建新的undo表空间:
sql> create undo tablespace undo2 datafile ‘i:\intel_data\o06dms0\undo2.o06dms0’ size 100m;
创建新的spfile,覆盖旧的spfile:
sql> create spfile from pfile=’h:\inito06dms0.ora’;
关闭数据库:
sql> shutdown immediate;

step 4.
以原来的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     900
undo_tablespace                      string      undo2

最终检查一下:
sql> select segment_name,status from dba_rollback_segs;

segment_name                   status
—————————— —————-
system                         online
_syssmu40_1968985325$          online
_syssmu39_4040503138$          online
_syssmu38_4059847715$          online
_syssmu37_2692202156$          online
_syssmu36_2617425201$          online
_syssmu35_1133967719$          online
_syssmu34_1916939664$          online
_syssmu33_99444166$            online
_syssmu32_162619813$           online
_syssmu31_830375278$           online

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐