如果数据库在打开时,当前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 UNDOTBS1 YES NO YES
4 USERS YES NO YES
3 TEMP NO NO YES
6 EXAMPLE YES NO YES
8 TEST YES NO YES
5 UNDOTBS2 YES 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;
然后再删除该表空间即可。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/27064835/viewspace-2023293/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/27064835/viewspace-2023293/