zoukankan      html  css  js  c++  java
  • UNDO表空间的ORA1122错误解决(二)转

    前一段时间解决了一个ORA-1122错误,正好本机的数据库环境由于Windows的自动重起,导致数据库无法打开,出现错误信息也是ORA-1122

    这次出现错误的表空间是UNDO表空间。

    上一篇介绍了利用备份进行恢复的方法,这篇尝试重建UNDO表空间的方法。

    UNDO表空间的ORA-1122错误解决(一):http://yangtingkun.itpub.net/post/468/455691


    由于数据库存在备份,因此可以轻松的对数据库进行恢复,不过难得碰到一个错误的情况,尝试一下是否可以在缺少备份的基础上进行数据库的恢复:

    再看一下问题,尝试打开数据库,则会报错:

    SQL> CONN /@TEST AS SYSDBA已连接到空闲例程。
    SQL> STARTUP MOUNT
    ORACLE
    例程已经启动。

    Total System Global Area 76619308 bytes
    Fixed Size 454188 bytes
    Variable Size 50331648 bytes
    Database Buffers 25165824 bytes
    Redo Buffers 667648 bytes
    数据库装载完毕。
    SQL> ALTER DATABASE OPEN;
    ALTER DATABASE OPEN
    *
    ERROR
    位于第 1 :
    ORA-01122:
    数据库文件 2 验证失败

    ORA-01110:
    数据文件 2: 'F:ORACLEORADATATESTUNDOTBS01.DBF'
    ORA-01200: 25600
    的实际文件大小小于26880块的正确大小

    如果没有备份,那么就只能采用其他的方式来进行恢复,如果出现问题的数据文件中的内容不是关键内容的话,也可以考虑使用ALTER DATABASE DATAFILE OFFLINE的方式。

    方法可以参考一个类似的案例:一次ORA-1122错误的解决:http://yangtingkun.itpub.net/post/468/455467

    不过这里出现问题的是UNDO表空间,如果UNDO表空间中没有要回滚的数据,那么问题比较简单,因为Oracle可以更换UNDO表空间,只需要直接将UNDO表空间的数据文件OFFLINE,启动数据库后,新建一个UNDO表空间,并切换当前的UNDO表空间即可。

    但是如果UNDO表空间中记录了要回滚的数据,那么恢复操作就会更复杂了。

    尝试OFFLINE出现问题的数据文件:

    SQL> ALTER DATABASE DATAFILE 'F:ORACLEORADATATESTUNDOTBS01.DBF' OFFLINE;

    数据库已更改。

    SQL> ALTER DATABASE OPEN;

    数据库已更改。

    下面可以为系统创建新的UNDO表空间,并实现切换:

    SQL> CREATE UNDO TABLESPACE UNDOTBS2 DATAFILE 'F:ORACLEORADATATESTUNDOTBS02.DBF' SIZE 200M;

    表空间已创建。

    SQL> SHOW PARAMETER UNDO_TABLESPACE

    NAME TYPE VALUE
    ------------------------------------ ----------- ------------------------------
    undo_tablespace string UNDOTBS1
    SQL> ALTER SYSTEM SET UNDO_TABLESPACE = UNDOTBS2;

    系统已更改。

    虽然数据库已经启动完成,UNDO表空间也已经切换,但是问题并没有结束,如果尝试删除UNDO表空间UNDOTBS1则会报错:

    SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;
    DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES
    *
    ERROR
    位于第 1 :
    ORA-01548:
    已找到活动回退段'_SYSSMU1$',终止删除表空间


    SQL> SELECT COUNT(*) FROM YANGTK.T;
    SELECT COUNT(*) FROM YANGTK.T
    *
    ERROR
    位于第 1 :
    ORA-00376:
    此时无法读取文件
    2
    ORA-01110:
    数据文件 2: 'F:ORACLEORADATATESTUNDOTBS01.DBF'

    在查询包括需要进行回滚操作的表时,同样会遇到错误。而对于其他没有问题的表,则可以正常访问:

    SQL> SELECT COUNT(*) FROM YANGTK.T1;

    COUNT(*)
    ----------
    20

    现在问题就是前面所提到的,OFFLINEUNDO表空间中保存着需要进行回滚的记录,而这些记录会导致数据库部分内容还没有最终恢复完成,在此之前受影响的部分对象是无法正常访问的。

    SQL> SELECT SEGMENT_NAME, OWNER, TABLESPACE_NAME, STATUS
    2 FROM DBA_ROLLBACK_SEGS;

    SEGMENT_NAME OWNER TABLESPACE_NAME STATUS
    -------------------- ------ -------------------- ----------------
    SYSTEM SYS SYSTEM ONLINE
    _SYSSMU1$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU2$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU3$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU4$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU5$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU6$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU7$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU8$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU9$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU10$ PUBLIC UNDOTBS1 NEEDS RECOVERY
    _SYSSMU11$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU12$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU13$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU14$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU15$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU16$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU17$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU18$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU19$ PUBLIC UNDOTBS2 ONLINE
    _SYSSMU20$ PUBLIC UNDOTBS2 ONLINE

    已选择21行。

    检查系统的回滚段信息,发现UNDOTBS1中的所有回滚段都需要恢复。在没有备份的情况下,只能尝试使用隐含参数将数据库打开,不过这个过程会破坏数据库的一致性,而且可能造成数据库出现逻辑错误。采用下面的方法打开数据库后,应该马上执行EXP备份,重建数据库后,再导入。

    下面开始尝试恢复数据库,首先创建PFILE,并关闭数据库:

    SQL> CREATE PFILE='F:INITTEST.ORA' FROM SPFILE;

    文件已创建。

    SQL> SHUTDOWN IMMEDIATE数据库已经关闭。已经卸载数据库。
    ORACLE
    例程已经关闭。

    手工编辑PFILE,修改UNDO_MANAGEMENTMANUAL,并添加隐含参数_OFFLINE_ROLLBACK_SEGMENTS=(_SYSSMU1$,_SYSSMU2$,……_SYSSMU10$)

    *.undo_management='MANUAL'
    _offline_rollback_segments=(_SYSSMU1$,_SYSSMU2$,_SYSSMU3$,_SYSSMU4$,_SYSSMU5$,_SYSSMU6$,_SYSSMU7$,_SYSSMU8$,_SYSSMU9$,_SYSSMU10$)

    下面重起数据库:

    SQL> STARTUP PFILE=F:INITTEST.ORA
    ORACLE
    例程已经启动。

    Total System Global Area 76619308 bytes
    Fixed Size 454188 bytes
    Variable Size 50331648 bytes
    Database Buffers 25165824 bytes
    Redo Buffers 667648 bytes
    数据库装载完毕。数据库已经打开。

    由于设置了隐含参数,现在可以删除回滚段了:

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU1$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU2$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU3$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU4$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU5$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU6$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU7$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU8$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU9$";

    回退段已删除。

    SQL> DROP ROLLBACK SEGMENT "_SYSSMU10$";

    回退段已删除。

    下面就可以删除UNDOTBS1表空间了:

    SQL> DROP TABLESPACE UNDOTBS1 INCLUDING CONTENTS AND DATAFILES;

    表空间已丢弃。

    表空间删除后,通过重起来去掉加载的隐含参数。至此,恢复操作告一段落:

    SQL> SHUTDOWN IMMEDIATE数据库已经关闭。已经卸载数据库。
    ORACLE
    例程已经关闭。
    SQL> STARTUP
    ORACLE
    例程已经启动。

    Total System Global Area 76619308 bytes
    Fixed Size 454188 bytes
    Variable Size 50331648 bytes
    Database Buffers 25165824 bytes
    Redo Buffers 667648 bytes
    数据库装载完毕。数据库已经打开。
    SQL> SHOW PARAMETER UNDO

    NAME TYPE VALUE
    ------------------------------------ ----------- --------------
    undo_management string AUTO
    undo_retention integer 10800
    undo_suppress_errors boolean FALSE
    undo_tablespace string UNDOTBS2
    SQL> SELECT COUNT(*) FROM YANGTK.T;

    COUNT(*)
    ----------
    1273614

    由于数据库处于逻辑损害的状态,而且使用了隐含参数,很可能造成未知的危害,因此这个时候应该对数据库中的全部数据执行导出操作,然后重建数据库,再导入回去。

    即使采用了上面的操作,也无法确保数据库中数据的一致性。这是由于采用了上面的恢复方法,导致UNDO表空间中记录的需要回滚的信息丢失,而这部分对应的数据会被认为是已经提交的数据,从而破坏了数据库的事务性。

    上一篇文章采用恢复的方法打开数据库后,查询T表的记录是:

    SQL> SELECT COUNT(*) FROM YANGTK.T;

    COUNT(*)
    ----------
    636807

    这里不难看出二者的差别有多大。因此,这种方法的恢复,只是没有备份时不得已而为之。

    原址:http://yangtingkun.itpub.net/post/468/455743

  • 相关阅读:
    js拷贝
    git
    移动端网页电话号码的拨打
    es6 promise对象
    h5调用qq客户端
    ActiveMQ中的Destination高级特性(一)
    ActiveMQ集群下的消息回流功能
    ActiveMQ的静态网络链接
    深入理解IoC/DI
    ActiveMQ启动多个broker
  • 原文地址:https://www.cnblogs.com/datalife/p/1985267.html
Copyright © 2011-2022 走看看