ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 10g删除表没有进入回收站(二)

10g删除表没有进入回收站(二)

原创 Linux操作系统 作者:yangtingkun 时间:2008-03-19 19:54:18 0 删除 编辑

今天在删除一个表的时候以外发现被删除的表没有进入回收站。

定位导致具体问题的真正原因。

10g删除表没有进入回收站(一):http://yangtingkun.itpub.net/post/468/457565

 

 

继续昨天的问题,根据重现问题的过程,怀疑问题可能与以下的一个或多个方法有关:分区表、表空间改名以及导入9i版本的表。

个人认为由于9i没有回收站的功能,因此9i导入的表很可能在某些情况下删除时不放入回收站中;而表空间改名也很可能是导致问题的原因,至于分区表,似乎可能性并不大,这个放到最后进行测试。

首先测试是否是表空间重命名造成的问题,这里仍然可以使用前一篇文章步骤中导出的文件,只需要在目标数据库中添加一个新的表空间,使得导入可以顺利完成。

SQL> CONN YANGTK/YANGTK@YTK102
已连接。
SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T_LOGMNR                       TABLE
TEST_LOB                       TABLE
T2                             TABLE
T1                             TABLE
T                              TABLE

SQL> SELECT TABLESPACE_NAME FROM DBA_TABLESPACES;

TABLESPACE_NAME
------------------------------
SYSTEM
UNDOTBS1
SYSAUX
TEMP
USERS
EXAMPLE
YANGTK
LOB_SPACE

已选择8行。

SQL> CREATE TABLESPACE TEST DATAFILE 'E:\ORACLE\ORADATA\YTK102\TEST01.DBF' SIZE 10M;

表空间已创建。

下面执行导入操作:

E:\>imp yangtk/yangtk@ytk102 file=t_partition.dmp tables=t_partition

Import: Release 10.2.0.1.0 - Production on 星期三 3 19 15:31:06 2008

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

经由常规路径由 EXPORT:V09.02.00 创建的导出文件

警告: 这些对象由 TEST 导出, 而不是当前用户

已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入
.
正在将 TEST 的对象导入到 YANGTK
.
正在将 TEST 的对象导入到
YANGTK
. .
正在导入分区              "T_PARTITION":"P1"导入了           0

. .
正在导入分区              "T_PARTITION":"P2"导入了           0
成功终止导入, 没有出现警告。

然后检查这个对象删除后是否进入回收站。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T_LOGMNR                       TABLE
TEST_LOB                       TABLE
T2                             TABLE
T1                             TABLE
T                              TABLE

既然没有执行RENAME TABLESPACE的操作,问题就出现了,说明这个问题应该和RENAME TABLESPACE没有关系,那么下面就可以排查是否和9i版本导入的表有关。

SQL> ALTER USER YANGTK DEFAULT TABLESPACE SYSTEM;

用户已更改。

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  PARTITION BY RANGE (ID)
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE TEST,
  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE TEST);

表已创建。

10g环境下使用同样的脚本建立分区表。下面对这个表进行导出操作:

E:\>exp yangtk/yangtk@ytk102 file=t_partition_10g.dmp tables=t_partition

Export: Release 10.2.0.1.0 - Production on 星期三 3 19 15:37:13 2008

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
已导出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集

即将导出指定的表通过常规路径...
. .
正在导出表
                     T_PARTITION
. .
正在导出分区                              P1导出了           0

. .
正在导出分区                              P2导出了           0
成功终止导出, 没有出现警告。

删除分区表和对应的表空间:

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

SQL> DROP TABLESPACE TEST INCLUDING CONTENTS AND DATAFILES;

表空间已删除。

现在为了确保10g的导出结果可以导入,仍然采用第一篇文章中提到的修改表空间名称的方法:

SQL> ALTER TABLESPACE YANGTK RENAME TO TEST;

表空间已更改。

执行导入操作:

E:\>imp yangtk/yangtk@ytk102 file=t_partition_10g.dmp tables=t_partition

Import: Release 10.2.0.1.0 - Production on 星期三 3 19 15:43:28 2008

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

经由常规路径由 EXPORT:V10.02.01 创建的导出文件
已经完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的导入
.
正在将 YANGTK 的对象导入到 YANGTK
.
正在将 YANGTK 的对象导入到
YANGTK
. .
正在导入分区              "T_PARTITION":"P1"导入了           0

. .
正在导入分区              "T_PARTITION":"P2"导入了           0
成功终止导入, 没有出现警告。

下面恢复表空间的名称,并测试删除操作:

SQL> ALTER TABLESPACE TEST RENAME TO YANGTK;

表空间已更改。

SQL> ALTER USER YANGTK DEFAULT TABLESPACE YANGTK;

用户已更改。

SQL> DESC T_PARTITION
 
名称                                               是否为空? 类型
 -------------------------------------------------- -------- --------------
 ID                                                          NUMBER
 NAME                                                        VARCHAR2(30)

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T_LOGMNR                       TABLE
TEST_LOB                       TABLE
T2                             TABLE
T1                             TABLE
T                              TABLE

SQL> PURGE TABLE T_PARTITION;
PURGE TABLE T_PARTITION
*
1 行出现错误:
ORA-38307:
对象不在回收站中

居然问题也重现了。如果说通过第一个测试,问题变得逐渐明朗,那么测试的结果使得问题变得扑朔迷离了。

如果说采用10g版本进行导入仍然出现问题,那么说明这个问题似乎和跨数据库版本也没有关系。也就是说问题是由于分区表操作的,但是前面的多次测试已经证明,普通建立一个分区表删除后会进入到回收站中,这里可以假设,导致问题的原因不仅是分区表,还有IMP操作,而跟EXP/IMP的版本没有关系。

除了这种推测外,是否还可以做一种假设,就是RENAME TABLESPACE操作,和数据库跨版本的导入都可以造成这个问题的产生,以至于使用排除法进行推断是不准确的。

当然还有另外一种可能性,问题可能和当前数据库的状态有关,也就是说,这个错误很可能在其他数据库中无法重现。

至于问题到底是什么因素造成的,还需要一系列的测试才能说明,先测试一个最简单的,分区表加导入:

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  PARTITION BY RANGE (ID)
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE YANGTK);

表已创建。

脚本稍做调整,然后建立分区表,并利用10gexp导出,然后删除该表,并利用10gimp导入,为了节省篇幅,这里将导出、导入的步骤省略:

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

下面验证删除问题:

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T_LOGMNR                       TABLE
TEST_LOB                       TABLE
T2                             TABLE
T1                             TABLE
T                              TABLE
T_PARTITION                    TABLE

已选择6行。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T_LOGMNR                       TABLE
TEST_LOB                       TABLE
T2                             TABLE
T1                             TABLE
T                              TABLE
BIN$lXZi01z6RL+pzvELmsdRfQ==$0 TABLE

已选择6行。

SQL> PURGE TABLE T_PARTITION;

表已清除。

这次倒是没有重现问题,看来仅靠导入分区表是无法重现问题的。那么前面第一个推测似乎已经站不住脚了,难道真的是两种方法都可能造成这种问题,这个概率也太小了吧。不妨先检测一下第三种情况,删除一个当前已经存在的表,看是否进入回收站:

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
T_LOGMNR                       TABLE
TEST_LOB                       TABLE
T2                             TABLE
T1                             TABLE
T                              TABLE

SQL> DROP TABLE T2;

表已删除。

SQL> PURGE TABLE T2;

表已清除。

其他表似乎也没有问题,尝试修改表空间后手工建表,然后重命名删除:

SQL> ALTER TABLESPACE YANGTK RENAME TO TEST;

表空间已更改。

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  PARTITION BY RANGE (ID)
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE TEST,
  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE TEST);

表已创建。

SQL> ALTER TABLESPACE TEST RENAME TO YANGTK;

表空间已更改。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

目前似乎没有了头绪,仔细观察重现问题的操作,检查有哪些因素是遗漏掉的,结果突然发现了一个重要的共同点,出现这个问题分区表的默认表空间是SYSTEM。当时在9i上建立测试用户的时候没有指定默认的表空间,导致虽然分区表的分区存放在TEST表空间,但是分区表本身的表空间是SYSTEM表空间。前两次的测试都使用的是9i导出的dmp文件,也就是说,表最终的表空间都是SYSTEM,而第三次测试一方面是为了最大限度和前面的测试保持一致,另一方面是由于当前的YANGTK表空间需要修改为TEST,因此也选择了将当前用户的默认表空间暂时置为了SYSTEM表空间下。看来问题已经基本上确定了。

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  TABLESPACE SYSTEM PARTITION BY RANGE (ID)
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE YANGTK);

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;
PURGE TABLE T_PARTITION
*
1 行出现错误:
ORA-38307:
对象不在回收站中


SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  TABLESPACE USERS PARTITION BY RANGE (ID)
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE YANGTK);

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

这个测试结果已经足以说明问题了,测试一下SYSAUX表空间是否会出现同样的问题:

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  TABLESPACE SYSAUX PARTITION BY RANGE (ID)
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE YANGTK);

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

再测试一下是否和分区表有关:

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  TABLESPACE YANGTK;

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
  2  TABLESPACE SYSTEM;

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;
PURGE TABLE T_PARTITION
*
1 行出现错误:
ORA-38307:
对象不在回收站中

问题和分区表也没有关系,现在已经可以确认,是由于SYSTEM表空间的特点导致。

相信这个特性再在Oracle的文档上肯定有描述,果然在SQL REFERENCES文档中查到,如果要对一个表执行FLASHBACK TABLE TO BEFORE DROP要求表所处的表空间必须是LOCAL MANAGEMENT的非SYSTEM表空间。

对文档和新特性不熟悉,导致跑了这么大的圈子,以此为戒。

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/4227/viewspace-211703/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1955
  • 访问量
    10355655