前幾天有同事告訴我,有台伺服器上的資料表空間無法刪除,讓我看看。登入到伺服器,刪除資料表空間,資料庫同時報ora-00604和ora-38301錯誤。起初以為是有資料庫物件被鎖定,重啟資料庫後,發現還是報同樣的錯誤。Google後發現可能與10g的一個新特性資源回收筒有關,清空資源回收筒purge recyclebin後,進行刪除還是報同樣的錯誤。將資料表空間offline後進行刪除也不行,想可能是還有什麼關聯對象沒有被清空或依舊被佔用。想起以前未刪除資料表空間前刪除使用者時,提示是否刪除關聯的對象。先刪除使用者,選擇刪除使用者時同時刪除關聯的級聯對象,再刪除資料表空間時,成功刪除。同時也知道了oracle10g的一個新特性。 Oracle10g提供了類似作業系統中的資源回收筒功能。資源回收筒,從原理上來說就是一個資料字典表,放置使用者Drop掉的資料庫物件資訊。當drop table的時候,實際上只是將其重新命名,並將table以及相關聯的對象如index,constraint等放到資源回收筒(RecycleBin)中,後續如果發現drop錯了table,可以使用flashback table命名將資源回收筒中的table還原,這就是Oracle10g的Flashback Drop功能。 1. 啟用/禁用RecycleBin: 通過設定初始化參數recyclebin,可以控制是否啟用資源回收筒功能,預設是開啟的。 ;`:v | } h;w2?)L r B0SQL> alter system set recyclebin=off; 系統已更改。 SQL> alter system set recyclebin=on; 系統已更改。 SQL> alter session set recyclebin=off; 會話已更改。 SQL> alter session set recyclebin=on; 會話已更改。 2. 查看資源回收筒: SQL> SHOW recyclebin; 或者 SQL>select * from recyclebin; 除非擁有sysdba許可權,否則每個使用者只能看到屬於自己的對象。所以,對於使用者來說,好像每個人都擁有自己的資源回收筒。即使使用者有刪除其他schema對象的許可權,也只能在recyclebin中看到屬於自己的對象。 3. 資源回收筒對象的操作: 當一個表被刪除並移動到"資源回收筒"中,它的名字要進行一些轉換。這樣的目的是為了避免同類對象名稱的重複。(這一點和Windows作業系統的資源回收筒不同,Windows中的資源回收筒經過了特殊的處理,作業系統檔案可以重名。)轉換後的名字格式如下: BIN$unique_id$version其中BIN代表RecycleBin,unique_id是資料庫中該對象的唯一標誌,26個字元長度version表示該對象的版本號碼。 注意,以下幾種drop不會將相關對象放進RecycleBin: drop tablespace:會將RecycleBin中所有屬於該tablespace的對象清除 drop user:會將RecycleBin中所有屬於該使用者的對象清除 drop cluster:會將RecycleBin中所有屬於該cluster的成員對象清除 drop type:會將RecycleBin中所有依賴該type的對象清除 l 已經放到資源回收筒裡的表是不能用drop命令刪除的(注意對象名字上的雙引號): SQL> DROP table "BIN$V3f/oYUITrCEF2cotS5JaA==$0" ; DROP table "BIN$V3f/oYUITrCEF2cotS5JaA==$0" * ERROR at line 1: ORA-38301: can not perform. DDL/DML over objects in Recycle Bin 如果要清掉該對象,使用purge命令: SQL> PURGE table "BIN$V3f/oYUITrCEF2cotS5JaA==$0" ; Table purged. l 如果直接清空所有的Recycle Bin中的對象: SQL> PURGE RECYCLEBIN; Recyclebin purged. Purge recyclebin可以清除執行該命令的使用者所能看到的所有recyclebin對象。也就是普通使用者能清除屬於自己的對象,而sysdba使用者則能清除所有recyclebin中的對象。 l 恢複表,用回閃表的功能: SQL> FLASHBACK TABLE table_name TO BEFORE DROP; Flashback complete. 預設的恢複是第一個被刪除的表。如果要恢複指定的表,可以在FLASHBACK TABLE後面加上指定的RECYCLEBIN參數指定其他的名字: 語句FLASHBACK TABLE [已刪除TABLE名|"RECYCLEBIN中的名字"] TO BEFORE DROP; 但當你在RECYCLEBIN內有2張相同名字的表時候,只有通過"RECYCLEBIN中的名字"來閃回指定的表,用上面方法只閃回第一個被刪除的同名表。 l Purge tablespace tablespace_name可以清除RecycleBin屬於指定tablespace的所有對象。ITPUB個人空間0? M }0~+P x4A J SQL> purge tablespace users; 資料表空間已清除。 Purge tablespace tablespace_name user user_name則可以清除Recycle中屬於指定tablespace和指定user的所有對象。ITPUB個人空間3Q+S Q E Z SQL> purge tablespace users user ning; 資料表空間已清除。 l 清除表時,同時也會清除依賴這張表的約束,如索引。可以指定只清除表相應的約束,如:PURGE INDEX IDX_TEST。 表上的對象如索引、觸發器在表被閃回後是不會被同時閃回的,而是保持了在資源回收筒中名字。一些依賴這張表的代碼對象如視圖、預存程序在表被刪除後會失效,在表被閃回後不會被自動重新編譯,而要手工重新編譯他們。相關的資訊被儲存在視圖USER_RECYCLE中。可以用以下語句來獲得這些索引、觸發器對象的原有名稱: 1 SQL> SELECT OBJECT_NAME, ORIGINAL_NAME, TYPE 2 FROM USER_RECYCLEBIN A4})a R'd+C$l e.F0 3 WHERE BASE_OBJECT = (SELECT BASE_OBJECT FROM USER_RECYCLEBIN _)Z7R(? Z0 4 WHERE ORIGINAL_NAME = 'ABC') m m4x Z#b;O j0 5 AND ORIGINAL_NAME != 'ABC'; 8~:_ ]$G s S0 OBJECT_NAME ORIGINAL_N TYPE 3T U0D;r4C"q0]$L0 ------------------------------ ---------- -------- $U Q p C,l;y4l+k(u)`0 BIN$1++ilvsQQ7mfPh2pvont5A==$0 IDX_TEST INDEX 可以用以下方式來恢複索引: SQL> ALTER INDEX " BIN$1++ilvsQQ7mfPh2pvont5A==$0" RENAME TO IDX_TEST; 一個例外就是位元影像索引被刪除後是不會被儲存在資源回收筒中的,也無法從上述視圖中查到,需要用其他方式來恢複。 |