SQL> create tablespace test1 datafile size 20m; Tablespace created.
SQL> create table w1.a tablespace test1 as select * from dba_objects; Table created. SQL> select owner,segment_name,round(bytes/1024/1024,2)||' MB' m from dba_segments where tablespace_name='TEST1'; OWNER SEGMENT_NAME M ------------ --------------------------------------------------------------------------------------- W1 A 6 MB SQL>
SQL> create table w1.b tablespace test1 as select * from dba_objects; Table created. SQL> create table w1.c tablespace test1 as select * from dba_objects; Table created. SQL> select round(sum(bytes)/1024/1024,2)||' MB' from dba_segments where tablespace_name='TEST1'; ROUND(SUM(BYTES)/1024/1024,2)||'MB' ------------------------------------------- 18 MB
SQL> drop table w1.a; Table dropped. SQL> drop table w1.b; Table dropped. SQL> drop table w1.c; Table dropped. SQL> select owner,object_name,original_name from dba_recyclebin where ts_name='TEST1'; OWNER OBJECT_NAME ------------------------------ ------------------------------ ORIGINAL_NAME -------------------------------- W1 BIN$r6HZooW/xpzgQKjAb01Spw==$0 B W1 BIN$r6HZooW+xpzgQKjAb01Spw==$0 A W1 BIN$r6HZooXAxpzgQKjAb01Spw==$0 C SQL> col owner format a4 SQL> col segment_name format a35 SQL> col m format a10 SQL> select owner,segment_name,round(bytes/1024/1024,2)||' MB' m from dba_segments where tablespace_name='TEST1'; OWNE SEGMENT_NAME M ---- ----------------------------------- ---------- W1 BIN$r6HZooXAxpzgQKjAb01Spw==$0 6 MB W1 BIN$r6HZooW+xpzgQKjAb01Spw==$0 6 MB W1 BIN$r6HZooW/xpzgQKjAb01Spw==$0 6 MB SQL>
SQL> alter session set tracefile_identifier='rctest'; Session altered. SQL> alter session set sql_trace=true; Session altered. SQL> create table w1.d tablespace test1 as select * from dba_objects; Table created. SQL> alter session set sql_trace=false; Session altered. SQL> select owner,object_name,original_name from dba_recyclebin where ts_name='TEST1'; OWNE OBJECT_NAME ORIGINAL_NAME ---- ------------------------------ -------------------------------- W1 BIN$r6HZooW/xpzgQKjAb01Spw==$0 B W1 BIN$r6HZooXAxpzgQKjAb01Spw==$0 C
可以看到,A表被干掉了。我们看看从trace文件里能找到些什么
执行create table前,系统先查询test1表空间是否online。执行create table时,先检查相同的命名空间中是否已经存在相同的名称。接下来开始更新相关的数据字典,准备插入数据。此时发现空间不够,怎么办?注意下面的信息:
select obj#, type#, flags, related, bo, purgeobj, con#
from
RecycleBin$ where ts#=:1 and to_number(bitand(flags, 16)) = 16 order
by dropscn
注意这个排序:order by dropscn
接下来Oracle做了什么呢:
drop table "W1"."BIN$r6HZooW+xpzgQKjAb01Spw==$0" purge
删除了这个表以后,更新相关的数据字典,并插入新的数据
我们可以得出这样的结论:当删除表的时候,若不指定purge,会将表放入到回收站中。在创建新的段时,若表空间中没有足够的剩余空间,Oracle会按dropscn顺序从回收站中删除一些对象。如果数据文件指定了autoextend,那么这个优先级次序是:先删除回收站中的对象,再扩展数据文件
在删除用户的时候,系统首先从回收站中purge相关的表,然后对用户下的表采用如下的删除命令
drop table "W1"."D" cascade constraints purge force
然后释放掉所占用的空间