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; //这个静态视图可以列出所有(
onlineofflineUNDO段信息

 

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/

你可能感兴趣的:(数据库)