Some times we have to deal with a tablespace that for some reason, its datafiles were deleted. In that case, we have two options, either restore the deleted datafiles and apply a recovery process or drop the tablespace if its data is not needed anymore. I won't explain how to restore and recover the datafiles, since this is not the approach that I want to talk about. I will explain how to delete a tablespace when some of its datafiles (or all of them) were deleted and its data is not needed anymore. Firstable I will create a tablespace with 4 datafiles: SQL> create tablespace tbs_test datafile '/home/oracle/datafile1.dbf' size 10M; Tablespace created. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile2.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile3.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile4.dbf' size 10M; Tablespace altered. So here are our 4 datafiles: SQL> select file#, name, status, enabled from v$datafile where TS# = (select TS# from v$tablespace where name='TBS_TEST') FILE# NAME STATUS ENABLED ---------- ------------------------------ ------- ---------- 6 /home/oracle/datafile1.dbf ONLINE READ WRITE 7 /home/oracle/datafile2.dbf ONLINE READ WRITE 8 /home/oracle/datafile3.dbf ONLINE READ WRITE 9 /home/oracle/datafile4.dbf ONLINE READ WRITE SQL> Now we will delete 2 datafiles, simulating a failure: [oracle@a1 ~]$ rm -rf /home/oracle/datafile2.dbf [oracle@a1 ~]$ rm -rf /home/oracle/datafile3.dbf [oracle@a1 ~]$ Here is where we will start our topic, If we try to drop the tablespace directly we will get an error like the following: SQL> drop tablespace tbs_test including contents and datafiles; drop tablespace tbs_test including contents and datafiles * ERROR at line 1: ORA-01116: error in opening database file 7 ORA-01110: data file 7: '/home/oracle/datafile2.dbf' ORA-27041: unable to open file Linux-x86_64 Error: 2: No such file or directory Additional information: 3 Some poeple could think about to offline the tablespace, perhaps using one of the following options: OFFLINE NORMAL Specify NORMAL to flush all blocks in all data files in the tablespace out of the system global area (SGA). You need not perform media recovery on this tablespace before bringing it back online. This is the default. OFFLINE TEMPORARY If you specify TEMPORARY, then Oracle Database performs a checkpoint for all online data files in the tablespace but does not ensure that all files can be written. Files that are offline when you issue this statement may require media recovery before you bring the tablespace back online. OFFLINE IMMEDIATE If you specify IMMEDIATE, then Oracle Database does not ensure that tablespace files are available and does not perform a checkpoint. You must perform media recovery on the tablespace before bringing it back online. Let's try the options: SQL> alter tablespace tbs_test offline ; alter tablespace tbs_test offline * ERROR at line 1: ORA-01116: error in opening database file 7 ORA-01110: data file 7: '/home/oracle/datafile2.dbf' ORA-27041: unable to open file Linux-x86_64 Error: 2: No such file or directory Additional information: 3 SQL> alter tablespace tbs_test offline temporary ; alter tablespace tbs_test offline temporary * ERROR at line 1: ORA-01116: error in opening database file 7 ORA-01110: data file 7: '/home/oracle/datafile2.dbf' ORA-27041: unable to open file Linux-x86_64 Error: 2: No such file or directory Additional information: 3 Even the immediate option doesn't work: SQL> alter tablespace tbs_test offline immediate ; alter tablespace tbs_test offline immediate * ERROR at line 1: ORA-01145: offline immediate disallowed unless media recovery enabled The right approach is offline the datafile or datafiles, not the whole tablespace, that's why we have to use the following option for datafiles: FOR DROP If the database is in NOARCHIVELOG mode, then you must specify FOR DROP clause to take a data file offline. However, this clause does not remove the data file from the database. To do that, you must use an operating system command or drop the tablespace in which the data file resides. Until you do so, the data file remains in the data dictionary with the status RECOVER or OFFLINE. If the database is in ARCHIVELOG mode, then Oracle Database ignores the FOR DROP clause. It is very import to know that this option has a condition, if no-archivelog and if archivelog mode. This is important and we will see why. If the database is in no-archivelog mode, then this is the way to drop the tablespace: SQL> archive log list Database log mode No Archive Mode Automatic archival Disabled Archive destination /u01/app/oracle/product/11.2/db_1/dbs/arch Oldest online log sequence 22 Current log sequence 24 SQL> SQL> alter database datafile '/home/oracle/datafile2.dbf' offline for drop ; Database altered. SQL> alter database datafile '/home/oracle/datafile3.dbf' offline for drop ; Database altered. SQL> SQL> select file#, name, status, enabled from v$datafile where TS# = (select TS# from v$tablespace where name='TBS_TEST') FILE# NAME STATUS ENABLED ---------- ------------------------------ ------- ---------- 6 /home/oracle/datafile1.dbf ONLINE READ WRITE 7 /home/oracle/datafile2.dbf RECOVER READ WRITE 8 /home/oracle/datafile3.dbf RECOVER READ WRITE 9 /home/oracle/datafile4.dbf ONLINE READ WRITE SQL> And now we are able to drop the tablespace: SQL> drop tablespace tbs_test including contents and datafiles; Tablespace dropped. SQL> Why it's important if the database is in archivelog or not? Well, things are easier if the database is in archivelog as we will see: turn on archivelog mode: SQL> shutdown immediate; Database closed. Database dismounted. ORACLE instance shut down. SQL> startup mount; ORACLE instance started. Total System Global Area 1870647296 bytes Fixed Size 2254304 bytes Variable Size 503319072 bytes Database Buffers 1358954496 bytes Redo Buffers 6119424 bytes Database mounted. SQL> alter database archivelog; Database altered. SQL> alter database open; Database altered. SQL> archive log list Database log mode Archive Mode Automatic archival Enabled Archive destination /u01/app/oracle/product/11.2/db_1/dbs/arch Oldest online log sequence 22 Next log sequence to archive 24 Current log sequence 24 SQL> Let's create again our tablespace with 4 datafiles: SQL> create tablespace tbs_test datafile '/home/oracle/datafile1.dbf' size 10M; Tablespace created. SQL> SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile2.dbf' size 10M; Tablespace altered. SQL> SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile3.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile4.dbf' size 10M; Tablespace altered. Deleting some datafiles: SQL> !rm -rf /home/oracle/datafile2.dbf SQL> !rm -rf /home/oracle/datafile3.dbf Now we don't need "FOR DROP", since the database is in archivelog we can use only "offline": SQL> alter database datafile '/home/oracle/datafile2.dbf' offline; Database altered. SQL> alter database datafile '/home/oracle/datafile3.dbf' offline ; Database altered. SQL> drop tablespace tbs_test including contents and datafiles; Tablespace dropped. But the story doesn't finish there... the things are even easier with archivelog. Let's create the problem again: SQL> create tablespace tbs_test datafile '/home/oracle/datafile1.dbf' size 10M; Tablespace created. SQL> SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile2.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile3.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile4.dbf' size 10M; Tablespace altered. Deleting 2 datafiles: SQL> !rm -rf /home/oracle/datafile2.dbf SQL> !rm -rf /home/oracle/datafile3.dbf Look at this: SQL> alter tablespace tbs_test offline immediate; Tablespace altered. SQL> drop tablespace tbs_test including contents and datafiles; Tablespace dropped. And... even easier: SQL> create tablespace tbs_test datafile '/home/oracle/datafile1.dbf' size 10M; Tablespace created. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile2.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile3.dbf' size 10M; Tablespace altered. SQL> alter tablespace tbs_test add datafile '/home/oracle/datafile4.dbf' size 10M; Tablespace altered. SQL> !rm -rf /home/oracle/datafile2.dbf SQL> !rm -rf /home/oracle/datafile3.dbf Directly to dropping the tablespace: SQL> drop tablespace tbs_test including contents and datafiles; Tablespace dropped. SQL> Follow me:
↧