我平时开发都是用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创建一个公用回滚段,就一切正常了。