[轉]Oracle 10G 新特性——閃回表

如果某個用戶不小心刪除了一個十分重要的表,後果將非常嚴重。在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;

一個例外就是位圖索引被刪除後是不會被保存在回收站中的,也無法從上述視圖中查到,需要用其他方式來恢復。

閃回表的其他用途

閃回表功能並不僅僅用於恢復被刪除的表。像閃回語句那樣,閃回表可以閃回表在某一時間點的狀態來完全取代現在的這張表。如下面語句將表閃回到SCN2202666520的狀態下:

SQL> FLASHBACK TABLE RECYCLETEST TO SCN 2202666520;

 

 

 

轉自:http://jolly10.itpub.net/post/7268/466130

 

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