OBJECT_ID、DATA_OBJECT_ID與truncate的本質

xiaokadba發表於2011-09-13

OBJECT_ID和DATA_OBJECT_ID可以這樣區別:OBJECT_ID可以看做是物件的一個邏輯ID,在物件建立時分配,一經分配即不再改變;而DATA_OBJECT_ID則是一個物理ID,在物件儲存發生變化時可能會發生改變。在sql.bsq檔案中,我們可以看到一段註釋說明(OBJ是DBA_OBJECTS的底層資料表),OBJ$表的DATAOBJ#為DateLayer的物件號,ORACLE提示不要在該欄位上建立索引,因為該標識會在truncate時發生改變。

這個註釋道出了truncate操作的本質,我們知道truncate操作可以很快速地清除表資料,也可以降低hwm並釋放儲存空間,同事也知道這是一個極其危險的操作,如果發生誤操作一般要透過備份來恢復,如果沒有備份,恢復將變得相當困難。

truncate的本質實質上就是透過為物件重新對映一段儲存空間,修改物件的DATAOB指向,從而完成了快速的資料清除,而在根本上,資料庫僅僅是將資料檔案上的空間標記為可用,並未真正清除資料,不過如果未來釋放的空間被其他物件使用,則資料將被真正覆蓋。所以如果真的發生了誤操作truncate了資料表,並且沒有備份,那麼最好的辦法就是儘快將相關檔案備份出來,熱按後透過各種方法和工具,將檔案上的資料抽取出來,完成資料恢復。

一下我們可以透過簡單的測試來驗證一下truncate操作的實現,首先建立一個測試表,可以看到初始的OBJECT_ID和DATA_OBJECT_ID是相同的:

1、新建表

create table test as select * from dba_users;

2、檢視OBJECT_ID、DATA_OBJECT_ID號(結果為74840,74840)

select object_name,object_id,data_object_id from dba_objects where object_name='TEST';

3、清空表

truncate table test;

4、檢視OBJECT_ID、DATA_OBJECT_ID號(結果為74840,74841)

select object_name,object_id,data_object_id from dba_objects where object_name='TEST';

根據上面的操作可以發現檢視OBJECT_ID沒有發生變化,而DATA_OBJECT_ID發生了變化。

[@more@]

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26274656/viewspace-1055009/,如需轉載,請註明出處,否則將追究法律責任。

相關文章