我申请这个blog是为了督促自己,把自己平时的一些想法和思考结果保留下来。 本博客所有内容均为原创,如有转载请注明作者和出处

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

上一篇 / 下一篇  2008-03-19 19:54:18 / 个人分类:ORACLE

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

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

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

 

 

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

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

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

SQL> CONN YANGTK/YANGTK@YTK102ITPUB个人空间9y%dpE j
已连接。
7RS(Ety3q0SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERIDITPUB个人空间m_%t#rO@5T/_*D
------------------------------ ------- ----------
"{x#G gTf#{)j["vS0T_LOGMNR                       TABLE
\+e4DpJ[0` jQ.l0TEST_LOB                       TABLE
[^h t+C'r`1M0T2                             TABLEITPUB个人空间z!L4w\#T$w
T1                             TABLEITPUB个人空间$F u A.JR OQ
T                              TABLE

SQL> SELECT TABLESPACE_NAME FROM DBA_TABLESPACES;

TABLESPACE_NAMEITPUB个人空间+\I NGE KC1Ac/xg
------------------------------
B j&R;k Z N0\h0SYSTEM
s8m"nS9La0UNDOTBS1ITPUB个人空间"iT F/iw(T8Y8d.\
SYSAUX
LF4`'Vw1||H0TEMP
%\2_*| JLS8s0USERS
RAhN3g/D.R j#O9lX0EXAMPLEITPUB个人空间5k1Oa4g2Eh-c
YANGTK
ApB9BW!L2|)\0LOB_SPACE

已选择8行。

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

表空间已创建。

下面执行导入操作:

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

Import: Release10.2.0.1.0 - Production on星期三319 15:31:06 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


2AX s_ gyW8zo0
连接到: Oracle Database10gEnterprise Edition Release10.2.0.1.0 - Production
wT0UE}0With the Partitioning, OLAP and Data Mining options

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

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

已经完成ZHS16GBK字符集和AL16UTF16 NCHAR字符集中的导入ITPUB个人空间 O.WPHe j
.
正在将TEST的对象导入到YANGTKITPUB个人空间4`"zZZ2RL+E{&ob/N C9]
.
正在将TEST的对象导入到
YANGTK
)VRm MZ-y.t V|b"|0. .
正在导入分区              "T_PARTITION":"P1"导入了           0

S:]~y8Y\z)G0. .
正在导入分区              "T_PARTITION":"P2"导入了           0ITPUB个人空间4YH6J)j%\"Z9Wd3r
成功终止导入,没有出现警告。

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

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERIDITPUB个人空间.h `t0fm Ud2Z
------------------------------ ------- ----------ITPUB个人空间%?"jU4ryW
T_LOGMNR                       TABLEITPUB个人空间T.U8|2BA*d f,R
TEST_LOB                       TABLEITPUB个人空间3{ZK#g*yMkY/H
T2                             TABLEITPUB个人空间)A6}-l)]!B[
T1                             TABLE
%Y%M Gw {z0T                              TABLE

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

SQL> ALTER USER YANGTK DEFAULT TABLESPACE SYSTEM;

用户已更改。

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
3_"X*F0@c(V0  2  PARTITION BY RANGE (ID)
$qr9y `8SQ!dk+y0  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE TEST,
,vH-`6Pir0  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE TEST);

表已创建。

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

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

Export: Release10.2.0.1.0 - Production on星期三319 15:37:13 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.

ITPUB个人空间o+u"v EaV3o{,F
连接到: Oracle Database10gEnterprise Edition Release10.2.0.1.0 - Production
_.H e,F Q-h8x0With the Partitioning, OLAP and Data Mining optionsITPUB个人空间a]LdF)\2N F
已导出ZHS16GBK字符集和AL16UTF16 NCHAR字符集

即将导出指定的表通过常规路径...ITPUB个人空间e:Lq:L.F
. .
正在导出表
                     T_PARTITIONITPUB个人空间D:O6JJ~O
. .
正在导出分区                              P1导出了           0
ITPUB个人空间3KM O)p Jk;K
. .
正在导出分区                              P2导出了           0ITPUB个人空间m/b5L"l&imr T
成功终止导出,没有出现警告。

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

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: Release10.2.0.1.0 - Production on星期三319 15:43:28 2008

Copyright (c) 1982, 2005, Oracle.  All rights reserved.


d+g}w/np0
连接到: Oracle Database10gEnterprise Edition Release10.2.0.1.0 - ProductionITPUB个人空间A @&a$].F`&` c
With the Partitioning, OLAP and Data Mining options

经由常规路径由EXPORT:V10.02.01创建的导出文件
+}/d+EL0{*ts0
已经完成ZHS16GBK字符集和AL16UTF16 NCHAR字符集中的导入
q ~&o+[2Y:T I"Ns0.
正在将YANGTK的对象导入到YANGTKITPUB个人空间"k&\f9g(IL1j
.
正在将YANGTK的对象导入到
YANGTK
I p*j:d2N P0. .
正在导入分区              "T_PARTITION":"P1"导入了           0

rd&r1|#Z0. .
正在导入分区              "T_PARTITION":"P2"导入了           0ITPUB个人空间n/Mc$yHvL6]
成功终止导入,没有出现警告。

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

SQL> ALTER TABLESPACE TEST RENAME TO YANGTK;

表空间已更改。

SQL> ALTER USER YANGTK DEFAULT TABLESPACE YANGTK;

用户已更改。

SQL> DESC T_PARTITION
$D-g:[|'a0 
名称                                              是否为空?类型
V&_.i"z$g*d[c0 -------------------------------------------------- -------- --------------ITPUB个人空间-VQ(UD(RJa.\
 ID                                                          NUMBERITPUB个人空间5{+Up S AN+POs
 NAME                                                        VARCHAR2(30)

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
+[1fj$} @7F?/P.m)b J0------------------------------ ------- ----------ITPUB个人空间3Vrr6c7yk*T
T_LOGMNR                       TABLEITPUB个人空间 ] ^1o5?k!@i,?5GWVW
TEST_LOB                       TABLE
U }U~6l%b5e0T2                             TABLE
DuyZU$N8u0T1                             TABLE
0hAK&?2Eu j0T                              TABLE

SQL> PURGE TABLE T_PARTITION;
xd]#q-F!m0PURGE TABLE T_PARTITIONITPUB个人空间.Nn`XE uw\/R
*ITPUB个人空间w6B Fr2uJ{hv\
1行出现错误:ITPUB个人空间w*gp2f$I:l@f4r$Y
ORA-38307:
对象不在回收站中

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

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

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

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

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

SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
Dq ul7S:h&Bqrk0  2  PARTITION BY RANGE (ID)
{%K&Q+r-J0  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
6S'prb:k'j0  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
U#q ~ NhIr+w X[0------------------------------ ------- ----------
,s Q(h:E e0T_LOGMNR                       TABLE
'y/I?dU:m\W0TEST_LOB                       TABLEITPUB个人空间 ~B"s"IJ9}8L
T2                             TABLEITPUB个人空间%[(k6]OE/Y3h@k
T1                             TABLEITPUB个人空间:n&v[+tj
T                              TABLE
xa P7_#Oc+j0T_PARTITION                    TABLE

已选择6行。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERIDITPUB个人空间2[#r `.l Z J
------------------------------ ------- ----------
%gK4Q0UuJ3w+k6Wu0T_LOGMNR                       TABLE
0q%s1gN(P6`2ELb0TEST_LOB                       TABLE
/bx9}P.v0T2                             TABLE
2p)eDr1I1rhp0T1                             TABLEITPUB个人空间's |+q:y~P d4F
T                              TABLEITPUB个人空间)G#Hh{D r+pL4n
BIN$lXZi01z6RL+pzvELmsdRfQ==$0 TABLE

已选择6行。

SQL> PURGE TABLE T_PARTITION;

表已清除。

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

SQL> SELECT * FROM TAB;

TNAME                          TABTYPE  CLUSTERID
+c;y{$x~0f2^r|:l0------------------------------ ------- ----------
#r,b-q5Q ^ T0T_LOGMNR                       TABLE
G1L0zjYI4E F l-^e0TEST_LOB                       TABLE
U$\k4~ R8}W/k0A0T2                             TABLE
$w6ve~ bZ{-T0T1                             TABLEITPUB个人空间 jpv9HK }
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))
XeL tl'n0  2  PARTITION BY RANGE (ID)ITPUB个人空间NO$Z ap&NX r
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE TEST,
(|dO-H#N)N0  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))ITPUB个人空间FUYI;|a
  2  TABLESPACE SYSTEM PARTITION BY RANGE (ID)ITPUB个人空间h O3yD7KcN0sU
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
I`3Bq!y*].jQ,V0  4  PARTITION P2 VALUES LESS THAN (200) TABLESPACE YANGTK);

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;
k t;r(lz` Q0PURGE TABLE T_PARTITIONITPUB个人空间j6{Zei
*ITPUB个人空间.dC:d#n,`9^,ax
1行出现错误:ITPUB个人空间*W Cp"{5u
ORA-38307:
对象不在回收站中

ITPUB个人空间!l;sK:x w"}4r
SQL> CREATE TABLE T_PARTITION (ID NUMBER, NAME VARCHAR2(30))
W+C%J.~r1O1M0  2  TABLESPACE USERS PARTITION BY RANGE (ID)
%kLzfj6n"dI#Ff-B0  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
^B X2?Nev,{Dn0  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))
^R^NE5k J5`0  2  TABLESPACE SYSAUX PARTITION BY RANGE (ID)ITPUB个人空间)A)yZzH`.|&m0fM
  3  (PARTITION P1 VALUES LESS THAN (100) TABLESPACE YANGTK,
"[M J ? xu @yA7u0  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))
N%bDHr-e:Cz2}0  2  TABLESPACE YANGTK;

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;

表已清除。

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

表已创建。

SQL> DROP TABLE T_PARTITION;

表已删除。

SQL> PURGE TABLE T_PARTITION;ITPUB个人空间f o#r5BwU
PURGE TABLE T_PARTITION
2ZQm2fX0*
N[X"}h hs0
1行出现错误:ITPUB个人空间 M*k9R:aBm H#o
ORA-38307:
对象不在回收站中

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

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

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

 


TAG:

yangtingkun的个人空间 引用 删除 yangtingkun   /   2008-03-20 18:49:01
local management的表空间,所有的记录通过BIMAP来管理,删除的时候BITMAP并不释放,只是该一下数据字典中的状态就可以了。

DICTIONARY MANAGEMENT就不是这么简单了。

至于为什么SYSTEM表空间要做限制,猜测了为了兼容性,避免数据字典受到影响。
yxyup's footprint 引用 删除 yxyup   /   2008-03-20 15:10:03
老大,可以接着说明一下原因,
1.为什么要是local managentt tbs?
2.为什么system Tbs不去recyclebin ?
 

评分:0

我来说两句

显示全部

:loveliness: :handshake :victory: :funk: :time: :kiss: :call: :hug: :lol :'( :Q :L ;P :$ :P :o :@ :D :( :)

Open Toolbar