oracle undo数据文件坏,Oracle数据库模拟Open下Undo损坏和修复

如果数据库在打开时,当前undo数据文件坏掉的话,比如UNDOTBS2出现了介质损坏,那么数据库就不能继续DML操作了。如果这时UNDOTBS2表空间上还有active状态的事务(未提交),Oracle会将其下的所有段都标志为NEEDS RECOVERY,这时我们首选使用备份恢复UNDOTBS2,但如果没有备份,那你只能用新建的UNDO替代损坏的UNDO,而损坏UNDO上的未提交事务也将不得不丢弃。如果你想删除这个损坏的UNDO表空间,必须另做处理(需要系统择时重启),我们模拟一下这种情况:

$ rm

undotbs02.dbf

SQL>alter system checkpoint;

cmd端再做update语句时会报错

SQL> update emp1 set sal=1000 where

empno=7902;

ORA-01116: 打开数据库文件3时出错

ORA-01110: 数据文件3:

'/u01/oradata/prod/undotbs02.dbf'

ORA-27041: 无法打开文件

SQL> startup force mount    //一定要到mount下

SQL> select file#,checkpoint_change#

from v$datafile;

FILE# CHECKPOINT_CHANGE#

---------- ------------------

1            6708724

2            6708724

3            6708724

4            6708724

5            6708724

6            6708724

SQL> select file#,checkpoint_change#

from v$datafile_header;

FILE# CHECKPOINT_CHANGE#

---------- ------------------

1            6708724

2            6708724

3                  0

4            6708724

5            6708724

6            6708724

SQL> alter database datafile 3 offline;

SQL> alter database open;

SQL> select * from v$rollname;

USN NAME

---------- ------------------------------

0 SYSTEM

SQL> select segment_name,status from

dba_rollback_segs; //这个静态视图可以列出所有(online或offline)UNDO段信息

SEGMENT_NAME                   STATUS

------------------------------

----------------

SYSTEM                         ONLINE

_SYSSMU20_1357956213$          NEEDS RECOVERY

_SYSSMU19_1357956213$          NEEDS RECOVERY

_SYSSMU18_1357956213$          NEEDS RECOVERY

_SYSSMU17_1357956213$          NEEDS RECOVERY

_SYSSMU16_1357956213$          NEEDS RECOVERY

_SYSSMU15_1357956213$          NEEDS RECOVERY

_SYSSMU14_1357956213$          NEEDS RECOVERY

_SYSSMU13_1357956213$          NEEDS RECOVERY

_SYSSMU12_1357956213$          NEEDS RECOVERY

_SYSSMU11_1357956213$          NEEDS RECOVERY

SQL>create undo tablespace undotbs1

datafile '/u01/oradata/prod/undotbs01.dbf' size 100m autoextend on;

SQL>select * from v$tablespace;

TS# NAME

INC BIG FLA ENC

---------- ------------------------------

--- --- --- ---

0 SYSTEM

YES NO  YES

1 SYSAUX

YES NO  YES

2 UNDOTBS1YES

NO  YES

4 USERS

YES NO  YES

3 TEMP

NO  NO  YES

6 EXAMPLEYES NO

YES

8 TEST

YES NO  YES

5 UNDOTBS2YES

NO  YES

SQL> alter system set

undo_tablespace=UNDOTBS1;

注意:此时原有活动事务的信息(未提交)可能仍然保存在UNDOTBS2,已经没有恢复的必要了。

SQL> update emp1 set sal=1000 where empno=7902;     //emp1表被锁住,不能做DML操作

update emp1 set sal=1000 where empno=7902

*

第1行出现错误:

ORA-00376: 此时无法读取文件7

ORA-01110: 数据文件7:

'/u01/oradata/prod/undotbs02.dbf'

SQL> drop tablespace undotbs2 including

contents and datafiles;

drop tablespace undotbs2 including contents

and datafiles

*

第1行出现错误:

ORA-01548: 已找到活动回退段'SYSSMU11_1357956213$',终止删除表空间

//这个UNDOTBS2删不掉是因为Oracle把其下的所有段都标志成NEEDS RECOVERY了,再查看一下相关的数据字典:

SQL> select segment_name,status from

dba_rollback_segs;

解决有两个办法:1)使用备份恢复,2)使用oracle提供的隐含参数_CORRUPTED_ROLLBACK_SEGMENTS

我们假设没有备份,就使用第2种方法

SQL>create pfile from spfile;           //建立静态参数文件

SQL>shutdown abort

#vi /u01/oracle/dbs/init.ora        //在静态参数文件里第一行插入以下内容

_CORRUPTED_ROLLBACK_SEGMENTS=(_SYSSMU11_1357956213$,_SYSSMU12_1357956213$,_SYSSMU13_1357956213$,_SYSSMU14_1357956213$,_SYSSMU15_1357956213$,_SYSSMU16_1357956213$,_SYSSMU17_1357956213$,_SYSSMU18_1357956213$,_SYSSMU19_1357956213$,_SYSSMU20_1357956213$)

然后存盘,再使静态参数文件启动数据库

SQL> startup

pfile='/u01/oracle/dbs/init.ora'

SQL> drop rollback segment "_SYSSMU11_1357956213$";

回退段已删除。

......

SQL> drop rollback segment

"_SYSSMU20_1357956213$";

SQL> select segment_name,status from

dba_rollback_segs;

SEGMENT_NAME                   STATUS

------------------------------

----------------

SYSTEM                          ONLINE

_SYSSMU10_1384520126$          ONLINE

_SYSSMU9_1384520126$           ONLINE

_SYSSMU8_1384520126$           ONLINE

_SYSSMU7_1384520126$           ONLINE

_SYSSMU6_1384520126$           ONLINE

_SYSSMU5_1384520126$           ONLINE

_SYSSMU4_1384520126$           ONLINE

_SYSSMU3_1384520126$           ONLINE

_SYSSMU2_1384520126$           ONLINE

_SYSSMU1_1384520125$           ONLINE

已选择11行。

SQL> drop tablespace undotbs2 including

contents and datafiles;

表空间已删除。

如果仍然删除失败(比较少见),则尝试修改字典

SQL>select * from v$tablespace;  记下要删除的undo对应的ts#号,比如是=2,则执行下行语句:

SQL>update seg$ set type# = 3 where

ts#=2;

然后再删除该表空间即可。

你可能感兴趣的:(oracle,undo数据文件坏)