如果某個用戶不小心刪除了一個十分重要的表,後果將非常嚴重。在9i中提供的閃回特性只能恢復DML語句造成的影響,而無法恢復DDL語句的影響。DBA只能通過重建一張表,然後從備份數據中導入。
刪除表的恢復
利用Oracle 10G中的閃回表的特性,DBA可以輕鬆完成這項工作,並將影響降到最小。下面就舉一個例子說明:
- 創建表:
SQL> create table abc (f number(9));
表已創建。
SQL> create index idx_test on abc(f);
索引已創建。
SQL> insert into abc values(1);
已創建 1 行。
SQL> insert into abc values(2);
已創建 1 行。
SQL> insert into abc values(3);
已創建 1 行。
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------ -------------- ----------
ABC TABLE
SQL> select index_name, index_type, table_name from ind;
INDEX_NAME INDEX_TYPE TABLE_NAME
------------------- ------------------- ----------------------
IDX_TEST NORMAL ABC
- 刪除表:
SQL> drop table abc;
表已刪除。
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------ -------------- ----------
BIN$XXUGsbYvSqa8Mrd6GstP+g==$0 TABLE
請注意,在原表abc被刪除後,abc沒有了,卻出現了一張新表BIN$XXUGsbYvSqa8Mrd6GstP+g==$0。這就是Oracle 10G中對刪除表的處理,原表實際上並沒有完全刪除掉,而是被系統重新命名成了一個系統定的新表。它還存在於原先的表空間,並且保持了原有的結構。
依賴於原表的存儲過程都失效了。而建在表上的索引和觸發器也會被重新命名。
SQL> select index_name, index_type, table_name from ind;
INDEX_NAME INDEX_TYPE TABLE_NAME
------------------- ------------------- ----------------------
BIN$1++ilvsQQ7mfPh2pvont5A==$0 NORMAL BIN$XXUGsbYvSqa8Mrd6GstP+g==$0
被刪除的表及其相關對象都會被放置在一個稱爲recyclebin的邏輯容器中:
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ---------------------------- ------------ ---------------
ABC BIN$XXUGsbYvSqa8Mrd6GstP+g==$0 TABLE 2005-08-29:18:03:10
顯示了被刪除對象的原有名字,刪除後的名字,對象類型以及刪除時間。
通過使用flashback table語句就可以恢復表!
SQL> flashback table abc to before drop;
閃回完成。
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------ -------------- ----------
ABC TABLE
這樣就輕鬆的將對象恢復了!
注意,對象被恢復後,它在recyclebin中佔用的空間並不會被釋放。必須使用PURGERECYCLEBIN來清空佔用的空間。
SQL> PURGE RECYCLEBIN;
回收站已清空。
當然,如果想要徹底刪除一個對象,讓它不佔用回收站的空間,可以用以下語句實現:
SQL> DROP TABLE ABC PURGE;
管理回收站
一旦哪些沒有被真正刪除的對象佔滿了表空間將會怎樣呢?其實答案很簡單:如果表空間被回收站中的數據佔滿了,並且數據文件也無法再擴展了(即產生了表空間壓力)。那麼回收站中的對象將會以“先入先出”(FIFO)的原則被自動清除掉。並且,依賴表的對象(如索引)將會比表對象先清除。
同樣的,當存在用戶配額時也會發生表空間壓力的情況。當一個用戶的配額空間被佔滿了,儘管此時表空間還可能有足夠的空間,系統也會以FIFO的原子釋放回收站中屬於這個用戶的對象。
另外,還有多種途徑來手工控制回收站。比如可以用對象的原有名字從回收站中清除指定對象:
PURGE TABLE ABC
或者用對象被刪除後系統自動重命名的名字來指定清除它:
PURGE TABLE “BIN$XXUGsbYvSqa8Mrd6GstP+g==$0”
清除表時,同時也會清除依賴這張表的約束,如索引。可以指定只清除表相應的約束,如:
PURGE INDEX IDX_TEST
此外,還可以將整個表空間的回收站內容全部清除:
PURGE TABLESPACE RING
也可以清除某個表空間上的回收站中某個用戶的對象:
PURGE TABLESPACE RING USER TEST
當用某個普通用戶登錄時,只會清除它自己的對象。
PURGE RECYCLEBIN
當以DBA身份登錄時,可以清除所有表空間上回收站
PURGE DBA_RECYCLEBIN
表的版本和閃回
一旦一張表被多次刪除又重建,該如何恢復呢?
SQL> CREATE TABLE TEST (COL1 NUMBER);
表已創建。
SQL> INSERT INTO TEST VALUES (1);
已創建 1 行。
SQL> COMMIT;
提交完成。
SQL> DROP TABLE TEST;
表已刪除。
SQL> CREATE TABLE TEST (COL1 NUMBER);
表已創建。
SQL> INSERT INTO TEST VALUES (2);
已創建 1 行。
SQL> COMMIT;
提交完成。
SQL> DROP TABLE TEST;
表已刪除。
SQL> CREATE TABLE TEST (COL1 NUMBER);
表已創建。
SQL> INSERT INTO TEST VALUES (3);
已創建 1 行。
SQL> COMMIT;
提交完成。
SQL> DROP TABLE TEST;
表已刪除。
這時,系統在每一次刪除時都會在回收站中爲這張表重命名一張表:
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------ -------------- ----------
BIN$IE1x0mwfSe6p6yhLn8/mBw==$0 TABLE
BIN$SUj0n3ghTaSQu0AFGheUYA==$0 TABLE
BIN$khjCqP4fRqeOrE/Eg/XUWQ==$0 TABLE
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ---------------------------- ------------ ---------------
TEST BIN$IE1x0mwfSe6p6yhLn8/mBw==$0 TABLE 2005-08-29:20:44:47
TEST BIN$khjCqP4fRqeOrE/Eg/XUWQ==$0 TABLE 2005-08-29:20:44:47
TEST BIN$SUj0n3ghTaSQu0AFGheUYA==$0 TABLE 2005-08-29:20:44:46
這時,如果使用flashback table test to before drop就只會最後一次刪除的表的狀態,即字段col1的內容爲3。可以使用以下方式將表閃回並重命名:
SQL> flashback table test to before drop rename to test2;
閃回完成。
SQL> flashback table test to before drop rename to test3;
閃回完成。
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------ -------------- ----------
TEST TABLE
TEST2 TABLE
TEST3 TABLE
這時的閃回是以刪除的相反順序閃回的。
所以可以直接指定某一次被刪除的表:
SQL> flashback table “BIN$khjCqP4fRqeOrE/Eg/XUWQ==$0” to before drop rename to test2;
閃回完成。
SQL> flashback table “BIN$SUj0n3ghTaSQu0AFGheUYA==$0” to before drop rename to test3;
閃回完成。
需要注意的
表上的對象如索引、觸發器在表被閃回後是不會被同時閃回的,而是保持了在回收站中名字。一些依賴這張表的代碼對象如視圖、存儲過程在表被刪除後會失效,在表被閃回後不會被自動重新編譯,而要手工重新編譯他們。
相關的信息被保存在視圖USER_RECYCLE中。可以用以下語句來獲得這些索引、觸發器對象的原有名稱:
SQL> SELECT OBJECT_NAME, ORIGINAL_NAME, TYPE
2 FROM USER_RECYCLEBIN
3 WHERE BASE_OBJECT = (SELECT BASE_OBJECT FROM USER_RECYCLEBIN
4 WHERE ORIGINAL_NAME = 'ABC')
5 AND ORIGINAL_NAME != 'ABC';
OBJECT_NAME ORIGINAL_N TYPE
------------------------------ ---------- --------
BIN$1++ilvsQQ7mfPh2pvont5A==$0 IDX_TEST INDEX
可以用以下方式來恢復索引:
SQL> ALTER INDEX " BIN$1++ilvsQQ7mfPh2pvont5A==$0" RENAME TO IDX_TEST;
一個例外就是位圖索引被刪除後是不會被保存在回收站中的,也無法從上述視圖中查到,需要用其他方式來恢復。
閃回表的其他用途
閃回表功能並不僅僅用於恢復被刪除的表。像閃回語句那樣,閃回表可以閃回表在某一時間點的狀態來完全取代現在的這張表。如下面語句將表閃回到SCN爲2202666520的狀態下:
SQL> FLASHBACK TABLE RECYCLETEST TO SCN 2202666520;
轉自:http://jolly10.itpub.net/post/7268/466130