Windows7蓝屏导致Oracle回滚段损坏(ORA-01115和ORA-27070)数据库无法启动的问题处理

    技术2022-05-20  36

    我平时开发都是用Windows2003,但笔记本是自带了WIN7,当时偷懒没重装系统。在搞了几个月的Android嵌入开发后,装了一堆不知名的USB驱动,结果现在经常动不动就蓝屏,什么中断、驱动之类的错误。由于也不常用来开发代码,所以也不在意。

     

    今天由于要搞个演示系统,于是开笔记本启动ORACLE,准备导数据。正在启动过程中,系统突然又蓝屏了。过一会重启后,ORACLE再也起不来了,一登录就报“ORA-01033: ORACLE initialization or shutdown in progress”。显然ORACLE只启动到一半,数据库没有打开成功。在咨询了数据库高人后,尝试用SQLPLUS手工打开,果然启动过程出错了:

      D:/>sqlplus / as sysdba  SQL*Plus: Release 10.2.0.1.0 - Production on 星期一 2月 28 23:48:57 2011 Copyright (c) 1982, 2005, Oracle.  All rights reserved. 连接到: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> startup ORACLE 例程已经启动。   Total System Global Area  293601280 bytes Fixed Size                  1248624 bytes Variable Size              92275344 bytes Database Buffers          197132288 bytes Redo Buffers                2945024 bytes 数据库装载完毕。 ORA-01115: 从文件 2 读取块时出现 IO 错误 (块 # 16539) ORA-01110: 数据文件 2: 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/UNDOTBS01.DBF' ORA-27070: 异步读取/写入失败 OSD-04016: 异步 I/O 请求排队时出错。 O/S-Error: (OS 1117) 由于 I/O 设备错误,无法运行此项请求。 ORA-01115: 从文件 2 读取块时出现 IO 错误 (块 # 16587) ORA-01110: 数据文件 2: 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/UNDOTBS01.DBF' ORA-27070: 异步读取/写入失败 OSD-04016: 异步 I/O 请求排队时出错。 O/S-Error: (OS 1117) 由于 I/O 设备错误,无法运行此项请求。  

    从错误信息看,是回滚段的数据文件UNDOTBS01.DBF被损坏无法读写了。高人建议最快的办法是重建。但我还是想保留旧有数据,于是尝试按网上的资料修复回滚段。

       

    我参照了这个帖子http://bbs.51cto.com/topic/thread-6449.html,把回滚段文件删除并卸下后,就可以启动了:

      D:/oracle/product/10.2.0/oradata/orcl>del UNDOTBS01.DBF   D:/oracle/product/10.2.0/oradata/orcl>sqlplus / as sysdba   ...   SQL> startup force ORACLE 例程已经启动。   Total System Global Area  293601280 bytes Fixed Size                  1248624 bytes Variable Size              92275344 bytes Database Buffers          197132288 bytes Redo Buffers                2945024 bytes 数据库装载完毕。 ORA-01157: 无法标识/锁定数据文件 2 - 请参阅 DBWR 跟踪文件 ORA-01110: 数据文件 2: 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/UNDOTBS01.DBF'   SQL> alter database datafile 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/UNDOTBS01.DB F' offline drop;   数据库已更改。   SQL> alter database open;   数据库已更改。   SQL>

    但这时数据库的回滚段仍在,并且仍指向旧的数据文件。这时如果做修改数据或导入操作仍然会报错:

     

    IMP-00017: 由于 ORACLE 错误 604, 以下语句失败:  "CREATE SEQUENCE "SEQ_XXXXYYYYZZZZ" MINVALUE 1 MAXVALUE 9999999999999999999"  "99999999 INCREMENT BY 1 START WITH 1 CACHE 20 NOORDER NOCYCLE" IMP-00003: 遇到 ORACLE 错误 604 ORA-00604: 递归 SQL 级别 1 出现错误 ORA-00376: 此时无法读取文件 2 ORA-01110: 数据文件 2: 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/UNDOTBS01.DBF'

     

    我们需要创建一个新的回滚段,代替旧的,并删除旧的:

     

    create undo tablespace UNDOTBSB02 datafile 'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/UNDOTBSB02.DBF' size 10M; alter system set undo_tablespace=UNDOTBSB02; drop tablespace UNDOTBS1 including contents and datafiles;

    不幸的是,最后一句删除原表空间的命令失败了,错误如下:

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

     

    这时,即使已经有新的回滚段,旧的也是无法去除的。解决办法只能是通过参数配置强行设置这些回滚段失效。我参考了这个帖子:http://www.itpub.net/thread-779247-1-1.html,先是查了下有哪些回滚段:

    SQL> select segment_name ,tablespace_name,status from dba_rollback_segs; SEGMENT_NAME                   TABLESPACE_NAME                STATUS ------------------------------ ------------------------------ ---------------- SYSTEM                         SYSTEM                         ONLINE _SYSSMU1$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU2$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU3$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU4$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU5$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU6$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU7$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU8$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU9$                      UNDOTBS1                       NEEDS RECOVERY _SYSSMU10$                     UNDOTBS1                       NEEDS RECOVERY SEGMENT_NAME                   TABLESPACE_NAME                STATUS ------------------------------ ------------------------------ ---------------- _SYSSMU11$                     UNDOTBSB2                      ONLINE _SYSSMU12$                     UNDOTBSB2                      ONLINE _SYSSMU13$                     UNDOTBSB2                      ONLINE _SYSSMU14$                     UNDOTBSB2                      ONLINE _SYSSMU15$                     UNDOTBSB2                      ONLINE _SYSSMU16$                     UNDOTBSB2                      ONLINE _SYSSMU17$                     UNDOTBSB2                      ONLINE _SYSSMU18$                     UNDOTBSB2                      ONLINE _SYSSMU19$                     UNDOTBSB2                      ONLINE _SYSSMU20$                     UNDOTBSB2                      ONLINE 已选择21行。

    然后根据上面的列表写了个简单的PFILE:

     

    undo_management=manual undo_retention=10800 undo_tablespace=UNDOTBS02 _CORRUPTED_ROLLBACK_SEGMENTS =(_SYSSMU1$,_SYSSMU2$,_SYSSMU3$,_SYSSMU3$,_SYSSMU4$,_SYSSMU5$,_SYSSMU6$,_SYSSMU7$,_SYSSMU8$,_SYSSMU9$,_SYSSMU10$)

     

    另存为initORCL.ora,然后带参数启动:

     

    SQL> startup pfile='D:/oracle/product/10.2.0/db_1/admin/orcl/pfile/initORCL.ora' ORA-01506: missing or illegal database name

     

     

    又出错了。研研究究了一番,发现原版的参数文件是有db_name的,于是在头上加了句db_name=ORCL,接着再启动:

     

     

    SQL> startup pfile='D:/oracle/product/10.2.0/db_1/admin/orcl/pfile/inithuz.ora' ORACLE 例程已经启动。 Total System Global Area  113246208 bytes Fixed Size                  1247588 bytes Variable Size              58721948 bytes Database Buffers           50331648 bytes Redo Buffers                2945024 bytes ORA-00205: ?????????, ??????, ???????

    还是出错,真是不给面子。再上网查了下,据说是要合并到spfile参数文件里才行。于是就合并呗(合并前备份):

     

    SQL> shutdown immediate ORA-01507: ?????? ORACLE 例程已经关闭。 SQL> create spfile from pfile='D:/oracle/product/10.2.0/db_1/admin/orcl/pfile/inithuz.ora'; 文件已创建。 SQL> startup ORACLE 例程已经启动。 Total System Global Area  293601280 bytes Fixed Size                  1248624 bytes Variable Size              92275344 bytes Database Buffers          197132288 bytes Redo Buffers                2945024 bytes 数据库装载完毕。 数据库已经打开。 SQL> drop tablespace undotbs1 including contents and datafiles; 表空间已删除。 SQL>

     

     

    终于启动成功地把损坏的回滚段干掉了。这时再查回滚段信息:

     

    SQL> select segment_name ,tablespace_name,status from dba_rollback_segs; SEGMENT_NAME                   TABLESPACE_NAME                STATUS ------------------------------ ------------------------------ ---------------- SYSTEM                         SYSTEM                         ONLINE _SYSSMU11$                     UNDOTBSB2                      OFFLINE _SYSSMU12$                     UNDOTBSB2                      OFFLINE _SYSSMU13$                     UNDOTBSB2                      OFFLINE _SYSSMU14$                     UNDOTBSB2                      OFFLINE _SYSSMU15$                     UNDOTBSB2                      OFFLINE _SYSSMU16$                     UNDOTBSB2                      OFFLINE _SYSSMU17$                     UNDOTBSB2                      OFFLINE _SYSSMU18$                     UNDOTBSB2                      OFFLINE _SYSSMU19$                     UNDOTBSB2                      OFFLINE _SYSSMU20$                     UNDOTBSB2                      OFFLINE 已选择11行。 SQL>

    原有UNDOTBS1的回滚段已经消失了。这时我们把spfile恢复再启动,并重新用UNDOTBSB2创建一个公用回滚段,就一切正常了。

     


    最新回复(0)