Oracle閃回刪除

llnnmc發表於2017-05-19

閃回刪除是透過將DROP命令對映到RENAME命令實現的,因而不是真正將表刪除,而是將表重新命名為一個系統生成的名稱,以後當活動物件需要儲存空間時才可能真正刪除它。如果儲存空間沒有被重用,那麼可以將物件重新命名回原來的名字而還原。如果沒有提供此功能,在刪除一個表後還原它的唯一方法就是執行不完整恢復,恢復到刪除之前的時間點。這樣做通常很耗時,並意味著會丟失其後完成的工作。

 

閃回刪除將一個表(連同它的索引和許可權)恢復到刪除前的狀態,而不會丟失任何使用者需要的資料。此操作不需要配置,也不需要任何備份,它始終是可以使用的,除非特意禁用。操作中資料庫保持當前狀態,不會給使用者帶來任何停機時間。

 

閃回刪除是DROP命令特有的,不能用於被TRUNCATE命令截斷的表。

 

閃回刪除(Flashback Drop)允許您將之前刪除的表(但不是截斷Truncate)恢復到剛好刪除它之前的狀態。同時還會自動恢復所有相關的索引、觸發器、許可權和不包括外來鍵約束的其它約束。

 

1、閃回刪除的實現

 

直到Oracle 9i版本為止,當刪除一個表時,到該表的所有引用都會從資料字典中刪除。儘管表的資料塊仍存在,但是無法找到它們,因為資料字典沒有記錄哪些塊屬於刪除的表。因而恢復刪除的表的唯一方法就是執行時間點恢復。

 

Oracle 10g版本開始,Drop table命令的實現方式完全不一樣。資料庫中根本沒有刪除表,而只是重新命名。Oracle在內部將Drop table命令對映到Rename命令,它將作用於表及其所有相關的索引、觸發器和約束,但不包括外來鍵約束,外來鍵約束將被刪除。可以想象,如果未刪除的父表上的DML受已刪除的表的內容約束,這將很荒誕。對於表的許可權,由於Rename操作並沒有改變物件號,因此授權仍是有效的。

 

既然Drop實際上是Rename,刪除就有可能透過重新命名回原來的名字而撤銷。但是,並不能保證這樣做總能成功。因為刪除的表佔用的空間有可能被重用。並且還會出現更復雜的情況,如在此期間建立了另一個表,並且重用了與刪除的表相同的名稱。

 

透過檢視回收站可以查詢刪除的物件及其更改後的新名稱。每個使用者都有一個回收站,可以在資料字典檢視user_recyclebin中查詢。也可以查詢全域性檢視dba_recyclebin。當表空間容量不足時,系統會自動重用回收站物件佔用的空間,此後物件將不能恢復。

 

閃回刪除不適用於儲存在system表空間中的表,它們是被直接刪除的。

 

2、使用閃回刪除

 

Drop命令將表重新命名為系統生成的名稱

drop table <table_name> [purge];

 

Purge關鍵字指示Oracle恢復Drop的原始含義,刪除該表及其所有引用,並且無法恢復。

 

閃回表並可重新命名

flashback table <table_name> to before drop [rename to <new_name>];

 

重新命名是必要的,防止已有同名物件被建立而無法閃回。

 

和表一同閃回的索引、觸發器和約束都保持了它們在回收站中的名稱。如果希望恢復它們原先的名稱,可以在閃回操作後手動重新命名。

 

強調兩點:第一,閃回刪除只適用於執行Drop命令後的恢復,而不能恢復用Truncate命令截斷的表;第二,如果刪除了一個使用者,如使用drop user scott cascade命令級聯刪除了使用者及其所有表,那麼使用閃回將無法恢復任何該使用者的物件,因為根本沒有可供物件連線的使用者。

 

使用SQL*Plus命令show recyclebin可以檢視有關刪除物件的資訊

show recyclebin;

 

ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME

---------------- ------------------------------ ------------ -------------------

T1               BIN$nQhcJiWqRIG1ykFeF+LD3g==$0 TABLE        2016-03-13:22:59:23

 

如果刪除了表,然後建立了具有相同名稱的另一個表,並且隨後也刪除了它,那麼在回收站中將有兩個原名相同的表,但具有不同的回收站名稱。預設情況下,閃回刪除命令總是恢復最新版本的表。但如果需要,也可以指定希望恢復的版本的回收站名稱,而不是指定原先的名稱

flashback table "BIN$nQhcJiWqRIG1ykFeF+LD3g==$0" to before drop;

 

以下例子實驗閃回刪除的使用。

 

1)作為使用者system使用SQL*Plus連線資料庫

sqlplus system/mesHz2@mes

 

2)建立使用者、表、索引和約束,插入資料

create user dropper identified by dropper account unlock;

grant connect, resource to dropper;

conn dropper/dropper

create table names(name varchar2(10));

create index idx_name on names(name);

alter table names add constraint name_u unique(name);

insert into names values('Liuluning');

commit;

 

3)確認模式的內容

col object_name for a30

select object_name, object_type from user_objects;

 

OBJECT_NAME                    OBJECT_TYPE

------------------------------ -------------------

NAMES                          TABLE

IDX_NAME                       INDEX

 

select constraint_name, constraint_type, table_name from user_constraints;

 

CONSTRAINT_NAME                C TABLE_NAME

------------------------------ - ------------------------------

NAME_U                         U NAMES

 

4)刪除該表

drop table names;

 

5)重新執行步驟3的查詢,確認已從user_objects中刪除了物件,但是仍存在系統生成的名稱的約束

select object_name, object_type from user_objects;

 

未選定行

 

select constraint_name, constraint_type, table_name from user_constraints;

 

CONSTRAINT_NAME                C TABLE_NAME

------------------------------ - ------------------------------

BIN$7vEz1hktQe2IdYDzs0QoKA==$0 U BIN$gOlcZp57RpCDWmuorgRRgA==$0

 

6)查詢回收站以檢視原始名稱到回收站名稱的對映

col original_name for a20

col type for a10

col ts_name for a20

select object_name, original_name, operation, type, ts_name, createtime, droptime from user_recyclebin;

 

OBJECT_NAME                    ORIGINAL_NAME        OPERATION TYPE       TS_NAME              CREATETIME          DROPTIME

------------------------------ -------------------- --------- ---------- -------------------- ------------------- -------------------

BIN$gOlcZp57RpCDWmuorgRRgA==$0 NAMES                DROP      TABLE      USERS                2018-04-15:22:38:15 2018-04-15:22:43:20

BIN$o++vBTFJR1yYnhE9VmJNaQ==$0 IDX_NAME             DROP      INDEX      USERS                2018-04-15:22:39:02 2018-04-15:22:43:20

 

可以看到,該檢視中沒有約束,約束只是被換了名稱。

 

可以查詢回收站中的表,但不能進行DML操作,查詢時表名稱應加上雙引號,以便SQL*Plus能夠正確的解析非標準的字元

select * from "BIN$gOlcZp57RpCDWmuorgRRgA==$0";

 

NAME

----------

Liuluning

 

7)閃回表

flashback table names to before drop;

 

8)重新執行步驟36中的查詢。可以看到,表已恢復,索引和約束仍保留了刪除後的名稱

select object_name, object_type from user_objects;

 

OBJECT_NAME                    OBJECT_TYPE

------------------------------ -------------------

BIN$o++vBTFJR1yYnhE9VmJNaQ==$0 INDEX

NAMES                          TABLE

 

select constraint_name, constraint_type, table_name from user_constraints;

 

CONSTRAINT_NAME                C TABLE_NAME

------------------------------ - ------------------------------

BIN$7vEz1hktQe2IdYDzs0QoKA==$0 U NAMES

 

select object_name, original_name, operation, type, ts_name, createtime, droptime from user_recyclebin;

 

未選定行

 

9)將索引和約束重新命名回原先的名稱

alter index "BIN$o++vBTFJR1yYnhE9VmJNaQ==$0" rename to idx_name;

alter table names rename constraint "BIN$7vEz1hktQe2IdYDzs0QoKA==$0" to name_u;

 

10)透過重新執行步驟3中的查詢確認物件名稱已改回

select object_name, object_type from user_objects;

 

OBJECT_NAME                    OBJECT_TYPE

------------------------------ -------------------

IDX_NAME                       INDEX

NAMES                          TABLE

 

select constraint_name, constraint_type, table_name from user_constraints;

 

CONSTRAINT_NAME                C TABLE_NAME

------------------------------ - ------------------------------

NAME_U                         U NAMES

 

11)實驗完畢,以使用者system連線資料庫,刪除dropper模式

conn system/mesHz2

drop user dropper cascade;

 

3、管理回收站

 

可以使用例項引數recyclebin禁用回收站,預設值是on,意味著所有模式都有一個回收站。該引數是動態的,可以為某個會話或整個系統將其設定為off

show parameter recyclebin;

 

NAME                                 TYPE       VALUE

------------------------------------ ---------- ------------------------------

recyclebin                           string     on

 

每個使用者可以使用SQL*Plus命令show recyclebin檢視回收站資訊。若要了解更詳細的資訊,可以查詢檢視user_recyclebindba_recyclebin,前面已經有過說明。

 

當表空間容量不足而回收站中有許多刪除物件時,Oracle將會首先重寫在回收站中留存時間最長的物件。這種先進先出(FIFO)演算法假定最近刪除的物件最有可能被閃回。

 

可以使用多種形式的purge命令永久性的刪除物件。

 

刪除表並且不進入回收站

drop table <table_name> purge;

 

從回收站中清除表,如果存在多個相同原始名稱的物件,那麼將清除存在時間最久的物件,也可以透過指定回收站中的名稱來避免混淆

purge table <table_name>;

purge table "BIN$gOlcZp57RpCDWmuorgRRgA==$0";

 

從回收站中清除索引,可以指定原始名稱或回收站中名稱

purge index <index_name>;

purge index "BIN$o++vBTFJR1yYnhE9VmJNaQ==$0";

 

從回收站中清除歸屬某個表空間的所有物件

purge tablespace <tablespace_name>;

 

從回收站中清除屬於某個表空間的某個使用者的所有物件

purge tablespace <tablespace_name> user <user_name>;

 

清除該使用者刪除的所有物件

purge user_recyclebin;

 

清除所有刪除的物件

purge dba_recyclebin;

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

相關文章