Flashback Drop的應用與限制

atlantisholic發表於2011-09-07
一、Flashback drop功能
    flashback drop特性從Oracle10g開始才有的,這個新特性,允許你從當前資料庫中恢復一個被drop了的物件。在執行drop操作時,現在Oracle不是真正刪除它,而是將該物件的相關資訊自動放入回收站(recycle bin)。recycle bin是一個儲存被刪除物件資訊的邏輯容器,實際上當某個物件被刪除,它在所屬表空間所佔的空間被不會被釋放,同時它的相關資訊被記錄到recycle bin中,在recycle bin中,每一個被刪除的物件都有一個唯一的名字。當某個物件需要分配新的空間,而此時表空間不足時,那麼ORACLE會以FIFO方式釋放recycle bin中的物件所佔用的空間,然後把這些空間分配給需要空間的物件使用。
    在oracle10g中,flashback drop的這個功能是預設啟動的。對於想進行FLASHABACK DROP操作的使用者,必須授予FLASHBACK許可權。
不過flashback drop也有一些限制:
1) 對於非SYSTEM表空間,同時也是本地管理的表空間才能使用flashback drop功能。不過如果一個表屬於非SYSTEM的本地管理表空間,其依賴的物件位於字典管理的表空間,這些物件也能夠能到RECYCLE BIN的保護。
2) 一個物件儲存在Recycle Bin的時間是沒有保證的。這個時間會由影響空間的系統活動決定。
3) Recycle bin中的物件不允許進行DML和DDL操作。
4) 由於安全原因,定義的VPD和FGA表策略不會被保護(但是,使用標準資料庫審計還是能夠監控回收站中表的操作)。
5) 索引組織表不受保護

 

 


下面具體演示一下flashback drop的功能:
SQL> conn / as sysdba;
已連線。
SQL> show parameter recyclebin
NAME                                 TYPE        VALUE
------------------------------------ ----------- ---------
recyclebin                           string      on
--關閉recycle bin,也就是關閉flashback drop功能
SQL> alter system set recyclebin=off;
系統已更改。
SQL> show parameter recyclebin
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------
recyclebin                           string      OFF
SQL> alter system set recyclebin=on;
系統已更改。
SQL> show parameter recyclebin
NAME                                 TYPE        VALUE
------------------------------------ ----------- -------------
recyclebin                           string      ON
SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order b
y droptime;
未選定行
SQL> create table dept_test as select * from scott.dept;
表已建立。
SQL> drop table dept_test;
表已刪除。
SQL> show recyclebin
SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order b
y droptime;
未選定行
此時刪除的表並沒有放到recycle bin之中,因為我們是用SYS使用者建立dept_test表的,其預設的儲存位置就是SYSTEM表空間。
SQL> create table dept_test tablespace test as select * from scott.dept;
表已建立。
SQL> drop table dept_test;
表已刪除。
SQL> show recyclebin
ORIGINAL NAME  RECYCLEBIN NAME                 OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT_TEST      BIN$1/cPW58fSmO0AKuCRetDGQ==$0  TABLE        2007-05-14:23:08:33
也可以查詢dba_recyclebin檢視獲得物件資訊
SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order b
y droptime;
OWNER                          OBJECT_NAME
------------------------------ ------------------------------
ORIGINAL_NAME                    DROPTIME
-------------------------------- -------------------
SYS                            BIN$1/cPW58fSmO0AKuCRetDGQ==$0
DEPT_TEST                        2007-05-14:23:08:33
SQL> create table dept_test tablespace test as select * from scott.dept;
表已建立。
SQL> drop table dept_test;
表已刪除。
SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME               OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT_TEST       BIN$kY10xbDpSu+M9fzXXLXNgQ==$0 TABLE        2007-05-14:23:10:28
DEPT_TEST       BIN$1/cPW58fSmO0AKuCRetDGQ==$0 TABLE        2007-05-14:23:08:33
可以見到,每一個物件在被刪除後放入recycle bin中都會有一個唯一的名字。這時我們可以查詢recycle bin中被刪除的表的資料:
SQL> select count(*) from "BIN$kY10xbDpSu+M9fzXXLXNgQ==$0";
  COUNT(*)
----------
         4
恢復recycle bin中被刪除的表,如果相同的一個表被刪除多次,那麼恢復的時候預設將恢復最近刪除的表
SQL> flashback table dept_test to before drop;
閃回完成。
SQL> select count(*) from dept_test;
  COUNT(*)
----------
         4
SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT_TEST       BIN$1/cPW58fSmO0AKuCRetDGQ==$0 TABLE        2007-05-14:23:08:33
可以見到2007-05-14:23:10:28刪除的那個表首先被恢復了。
--也可以指定recycle bin中的表名進行恢復
SQL> flashback table "BIN$1/cPW58fSmO0AKuCRetDGQ==$0" to before drop;
flashback table "BIN$1/cPW58fSmO0AKuCRetDGQ==$0" to before drop
*
第 1 行出現錯誤:
ORA-38312: 原始名稱已被現有物件使用
此時被恢復的表名稱仍然採用以前的名字,我們之前已經恢復一次DEPT_TEST,所以現在恢復就出現了重名,不過可以為其指定新的名字。
SQL> flashback table "BIN$1/cPW58fSmO0AKuCRetDGQ==$0" to before drop rename to d
ept_test2;
閃回完成。
SQL> select count(*) from dept_test2;
  COUNT(*)
----------
         4
當我們想刪除回收站裡的物件時,是不能使用DROP命令進行刪除,必須使用PURGE命令,在使用PURGE命令刪除表之後,這個表就不能被恢復了,因為它被徹底從recycle bin中刪除了,並將釋放出空間:
SQL> drop table dept_test;
表已刪除。
SQL> drop table dept_test2;
表已刪除。
SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT_TEST       BIN$Ohxs0m6ES1e2vur+U3mgsw==$0 TABLE        2007-05-14:23:16:42
DEPT_TEST2      BIN$ANVQ1MdeQkyWRvZVZu8Bww==$0 TABLE        2007-05-14:23:16:44
SQL> drop table "BIN$Ohxs0m6ES1e2vur+U3mgsw==$0";
drop table "BIN$Ohxs0m6ES1e2vur+U3mgsw==$0"
           *
第 1 行出現錯誤:
ORA-38301: 無法對回收站中的物件執行 DDL/DML
SQL> purge table "BIN$Ohxs0m6ES1e2vur+U3mgsw==$0";
表已清除。
SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
DEPT_TEST2      BIN$ANVQ1MdeQkyWRvZVZu8Bww==$0 TABLE        2007-05-14:23:16:44
我們也可以通過表空間一級進行清除
SQL> purge tablespace test;
表空間已清除。
這樣將清空在這個表空間上所有被刪除的物件並釋放這些物件所點用的空間,同時在purge tablespace也可以指定user,這樣將清空所屬使用者在這個表空間上被刪除的物件所佔用的空間。
SQL> purge tablespace test user scott;
表空間已清除。
--刪除當前使用者整個回收站裡的物件
SQL> purge recyclebin;
DBA 回收站已清空。
--刪除所有使用者的回收站裡的物件
SQL> purge dba_recyclebin;
DBA 回收站已清空。
下面測試一下當刪除表的時候,其所屬的物件,比如索引會不會也被放到recycel bin中:
SQL> create user test identified by test
  2  default tablespace test
  3  temporary tablespace temp;
使用者已建立。
SQL> alter user test quota unlimited  on test;
使用者已更改。
SQL> grant resource,connect to test;
授權成功。
SQL> conn test/test@ora10g;
已連線。
SQL> create table aa(a int);
表已建立。
SQL> insert into aa values(1);
已建立 1 行。
SQL> commit;
提交完成。
SQL> create index aa_inx on aa(a);
索引已建立。
SQL> drop table aa;
表已刪除。
SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
AA              BIN$KmzWs8qoSg6LZdlc0mePjw==$0 TABLE        2007-05-14:23:33:16
SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order b
y droptime;
OWNER                          OBJECT_NAME
------------------------------ ------------------------------
ORIGINAL_NAME                    DROPTIME
-------------------------------- -------------------
TEST                           BIN$Kwbc5qHKT2GwaXv1Tzmjqw==$0
AA_INX                           2007-05-14:23:33:16

TEST                           BIN$KmzWs8qoSg6LZdlc0mePjw==$0
AA                               2007-05-14:23:33:16
在這裡多了一個INDEX的資訊。
SQL> flashback table test."BIN$KmzWs8qoSg6LZdlc0mePjw==$0" to before drop;
閃回完成。
SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order b
y droptime;
未選定行
SQL> select * from aa;
         A
----------
         1
SQL> select index_name from user_indexes;
INDEX_NAME
------------------------------
BIN$Kwbc5qHKT2GwaXv1Tzmjqw==$0
我們可以看到,相關的索引被回收了,但它的名稱並沒有恢復到之前的名稱,而是保留著recycle bin中的名稱。
當通過drop user xx cascade刪除使用者資訊的時候,使用者所屬的物件不能放到recycle bin中。
SQL> drop user test cascade;
使用者已刪除。
SQL> select owner,object_name,original_name,DROPTIME from dba_recyclebin order b
y droptime;
未選定行

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

相關文章