删除表空间,提示ORA-14404
某客户删除一个空闲的表空间时,提示ORA-14404错误。具体如下所示:
SQL> drop tablespace DATA_P1 including contents and datafiles; drop tablespace DATA_P1 including contents and datafiles * ERROR at line 1: ORA-14404: partitioned table contains partitions in a different tablespace
SQL> select owner, segment_name, segment_type, tablespace_name 2 from dba_segments 3 where tablespace_name = 'DATA_P1'; no rows selected SQL> |
可以看出,DATA_P1表空间中已经没有任何数据,但删除该表空间时,提示ORA-14404,从错误提示可以看出有分区表在其他的表空间中存在分区,同时这张分区表可能也使用到了DATA_P1表空间。
查询分区表相关的信息,看哪些分区表会涉及到DATA_P1表空间
SQL> select table_owner, table_name, partition_name 2 from dba_tab_partitions 3 where tablespace_name = 'DATA_P1';
TABLE_OWNER TABLE_NAME PARTITION_NAME ----------------- ------------------ ----------------- TEST APP APP_P1
SQL> SQL> select count(*) from test.app;
COUNT(*) ---------- 70001
SQL> select count(*) from test.app partition(APP_P1);
COUNT(*) ---------- 0
SQL> |
可以看出,TEST.APP这张分区表的APP_P1分区使用到了DATA_P1表空间。但APP_P1分区在DATA_P1表空间中没有任何的数据段,这说明APP_P1分区中未插入任何数据,所以没有分配数据段。
为了解决这个故障,我们只需要将TEST.APP这张分区表的APP_P1分区从DATA_P1表空间移动至其他的表空间即可。
SQL> alter table test.app move partition APP_P1 tablespace data_default;
Table altered.
SQL> drop tablespace DATA_P1 including contents and datafiles;
Tablespace dropped.
SQL> |
问题虽然已经解决。但由此想到了另外一种情况,如果刚才是一张普通的空表存在于DATA_P1表空间,那DATA_P1表空间能否被成功删除呢?为了解答这个疑问,我做了如下测试。
(1)、创建一个空闲的DATA_P1表空间,然后创建一张空表存放在DATA_P1表空间中 SQL> create tablespace data_p1 datafile '+DG_DATA' size 100M;
Tablespace created.
SQL> create table APP 2 ( 3 ID number, 4 addr varchar2(200) 5 ) 6 tablespace data_p1;
Table created.
SQL> select object_name, object_type, created 2 from dba_objects 3 where owner = 'TEST';
OBJECT_NAME OBJECT_TYPE CREATED -------------- ------------------- ------------------- APP TABLE 2023-08-14 16:24:31
SQL>
(2)、尝试删除掉空闲的DATA_P1表空间 SQL> drop tablespace DATA_P1 including contents and datafiles;
Tablespace dropped.
SQL> select object_name, object_type, created 2 from dba_objects 3 where owner = 'TEST';
no rows selected SQL> 发现空闲的DATA_P1表空间已经成功删除,但该表空间中的那张APP空表也被同时删除。这个动作是非常危险的。 |
所以,删除空闲的表空间,正确的做法是:
1、先检查dba_segments视图,将该表空间中已经分配了数据段的对象全部迁移至其他表空间。
2、再检查dba_tables、dba_indexes、dba_tab_partitions和dba_ind_partitions视图,将一些涉及该表空间的对象也迁移至其他表空间。