Oracle 10G 新特性——閃回表

jolly10發表於2008-07-09
如果某個使用者不小心刪除了一個十分重要的表,後果將非常嚴重。在9i中提供的閃回特性只能恢復DML語句造成的影響,而無法恢復DDL語句的影響。DBA只能透過重建一張表,然後從備份資料中匯入。[@more@]刪除表的恢復

利用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;

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

相關文章