Oracle中recyclebin的保留策略

我們知道,Oracle 10g引入了recyclebin的概念,當我們刪除一個表的時候,若不指定purge,系統只是將這個表重命名爲BIN$開頭的名稱,並在數據字典中修改相關的數據。
       Administrator's Guide中是這麼描述recyclebin的:recycle bin實際上是一個包含了刪除的對象的相關信息的數據字典表。被刪除的表以及相關的對象(比如索引、約束、嵌套表等等)並沒有被移除,並且依然佔用着空間。它們會繼續使用用戶的空間配額,直到明確將它們從回收站中清除,或者是另一種很少見的情況:由於表空間的空間限制,數據庫必須將它們清除。
       由此我們可以知道,在Oracle 10g以後,若啓用了recyclebin功能,當你drop一個表的時候,它會仍然佔用着原來的空間。
       我們可以使用user_recyclebin或dba_recyclebin來查看回收站中的對象信息,或者使用recyclebin,它是user_recyclebin的公共同義詞。
       文檔中提到了,除了手動purge,這些回收站中的對象只有在表空間出現空間不足情況時纔會被清除。我們可以做個測試(測試環境爲RAC10.2.0.1+ASM)

       新建一個表空間,給它20m的容量
 
SQL> create tablespace test1 datafile size 20m; 
 
 
Tablespace created. 


然後我們在這個表空間上創建一個測試表a
 
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> 

一張表佔用6M空間,我們再創建2張一樣的測試表
 
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 


此時表空間已經使用了18M。這時我們把這三張表都刪除
 
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 

 
W1 BIN$r6HZooW+xpzgQKjAb01Spw==$0 

 
W1 BIN$r6HZooXAxpzgQKjAb01Spw==$0 

 
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> 

可以看到,3張表到了回收站中,空間也沒有釋放。
此時20m的表空間還剩餘2m可用,如果我再創建一張同樣的表呢
 
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

然後釋放掉所佔用的空間


如果想關閉recyclebin

>alter system set  recyclebin=OFF scope=both;即可

摘自:狂浪 的旮旯天地

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章