[Oracle Troubleshooting] Get Oracle Bounces When Data File Is Missing
今天同事遇到个问题,他手动删除了一些数据文件(本来尝试去drop一个schema的,但是发现太耗时了,所以来个“暴力”方法,直接删除数据文件),从而导致数据库不能打开了。 这个是很容易理解的,因为在数据库open阶段,会进行数据库一致性检查 (control文件记录的文件都应该存在),在这种情况下control文件中记录了数据库中有这个数据文件,但是数据库却发现该文件丢失了,所以数据库就不能打开了。从alert文件中可以看到类似如下的信息,
ORA-01157: cannot identify/lock data file XXX - see DBWR trace file
ORA-01110: data file XXX: 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\XXX.DBF'
ORA-27041: unable to open file
OSD-04002: 无法打开文件
O/S-Error: (OS 2) 系统找不到指定的文件
现在来简单模拟这种情况,在测试之前看下数据库中有那些数据文件,
FILE_NAME FILE_ID TABLESPACE_NAME
------------------------------------------------------------ ---------- --------------------
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF 4 USERS
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF 3 SYSAUX
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF 2 UNDOTBS1
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF 1 SYSTEM
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF 5 EXAMPLE
现在创建一个测试表空间TEST,相应的数据文件TEST.DBF,如下
SQL> CREATE TABLESPACE test
2 DATAFILE 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF'
3 SIZE 2m
4 AUTOEXTEND OFF;
表空间已创建。
现在再查询下dba_data_files视图,
FILE_NAME FILE_ID TABLESPACE_NAME
------------------------------------------------------------ ---------- -------------------
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF 4 USERS
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF 3 SYSAUX
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF 2 UNDOTBS1
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF 1 SYSTEM
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF 5 EXAMPLE
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF 6 TEST
已选择6行。
关闭数据库,删除数据文件test.dbf (手动删除)
SQL> shutdown immediate;
数据库已经关闭。
已经卸载数据库。
ORACLE 例程已经关闭。
SQL>
现在重新启动数据库,发现出现问题,
SQL> startup
ORACLE 例程已经启动。
Total System Global Area 532676608 bytes
Fixed Size 1249968 bytes
Variable Size 180358480 bytes
Database Buffers 343932928 bytes
Redo Buffers 7135232 bytes
数据库装载完毕。
ORA-01157: 无法标识/锁定数据文件 6 - 请参阅 DBWR 跟踪文件
ORA-01110: 数据文件 6: 'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF'
在这种情况下,如果有数据文件6的备份,只需要把这个备份文件放倒原来数据文件的目录,在本例中为 ‘D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL',然后进行数据库的recover即可,然后就可以打开数据库了。
但是现在情况是该数据文件没有备份,而且也不需要这个数据文件了,因此现在要解决的问题就是能让数据库open就可以了,不用关心数据的丢失。由于数据文件是在数据库关闭的情况下手动删除的,控制文件以及日志文件没有先关的记录反映,所以数据库在打开的时候发现数据库处于不一致的状态,因此打不开数据库。
现在能做的就是“骗过”数据库,“显示”告诉数据库去drop该数据文件,如下,
SQL> alter database datafile 6 offline drop;
数据库已更改。
SQL> alter database open;
数据库已更改。
现在数据库就可以打开了,但是可以看到数据库还是存在如下记录的,
SQL> select file_name, file_id, tablespace_name from dba_data_files;
FILE_NAME FILE_ID TABLESPACE_NAME
------------------------------------------------------------ ---------- -------------------
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF 4 USERS
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF 3 SYSAUX
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF 2 UNDOTBS1
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF 1 SYSTEM
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF 5 EXAMPLE
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\TEST.DBF 6 TEST
已选择6行。
现在需要做些清理工作,删除表空间TEST, 如下,(如果表空间非空,需要用drop tablespace xxx including contents and datafiles)
SQL> drop tablespace test;
表空间已删除。
SQL> select file_name, file_id, tablespace_name from dba_data_files;
FILE_NAME FILE_ID TABLESPACE_NAME
------------------------------------------------------------ ---------- -----------------
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\USERS01.DBF 4 USERS
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSAUX01.DBF 3 SYSAUX
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\UNDOTBS01.DBF 2 UNDOTBS1
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\SYSTEM01.DBF 1 SYSTEM
D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\EXAMPLE01.DBF 5 EXAMPLE
至此,就把这个“多余”的表空间删除了,数据库也能正常打开工作了。
但是要注意的是,这个只适应于测试环境,正常的数据库应该都要有备份,在数据文件丢失的情况下,可以借助备份文件进行数据库的恢复。
--------------------------------------
Regards,
FangwenYu