从oracle10g开始oracle实现了如windows回收站的功能,也就是说,在drop table的时候,没有直接被drop掉,而是改了个名字放在回收站中,改了名后的格式(BIN$globalUID$version),含义如下:
1)
准备环境(创建测试表t,索引idx_t,触发器trg_t)
SCOTT@ORA10G>create table t(x number(2),d date);
Table created.
SCOTT@ORA10G>create unique index idx_t on t(x);
Index created.
SCOTT@ORA10G>create or replace trigger trg_t
2 before insert on t
3 for each row
4 begin
5 if :new.d is null then
6 :new.d := sysdate;
7 end if;
8 end;
9 /
Trigger created.
SCOTT@ORA10G>
2)
删除测试表t,并检查已进入回收站
SCOTT@ORA10G>drop table t;
Table dropped.
SCOTT@ORA10G>
SCOTT@ORA10G>select tname,tabtype from tab;
TNAME TABTYPE
—————————— ——-
DEPT TABLE
EMP TABLE
BONUS TABLE
SALGRADE TABLE
FB_QUERY1 TABLE
FB_QUERY2 TABLE
FB_TABLE TABLE
SYS_TEMP_FBT TABLE
BIN$znWzWW0UmUvgQKjAIAESgg==$0 TABLE
9 rows selected.
SCOTT@ORA10G>
通过show recyclebin显示的为自己回收站中的表
SCOTT@ORA10G>show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
————– —————————— ———— ——————-
FB_DROP BIN$znWzWW0UmUvgQKjAIAESgg==$0 TABLE 2012-10-09:22:53:42
SCOTT@ORA10G>
通过字典表我们发现,与表t相关的对象都已进入回收站
SCOTT@ORA10G>SELECT original_name, object_name, type, ts_name, droptime FROM user_recyclebin;
ORIGINAL_NAME OBJECT_NAME TYPE TS_NAME DROPTIME
————- —————————— ——- ——- ——————-
IDX_T BIN$znWzWW0SmUvgQKjAIAESgg==$0 INDEX USERS 2012-10-09:23:17:35
TRG_T BIN$znWzWW0TmUvgQKjAIAESgg==$0 TRIGGER 2012-10-09:23:17:35
T BIN$znWzWW0UmUvgQKjAIAESgg==$0 TABLE USERS 2012-10-09:23:17:35
SCOTT@ORA10G>
注:有一定权限的话,也可以查看dba_recyclebin这个视图
3)
对删除的表进行闪回恢复
SCOTT@ORA10G>flashback table t to before drop;
Flashback complete.
SCOTT@ORA10G>
SCOTT@ORA10G>select tname,tabtype from tab;
TNAME TABTYPE
—————————— ——-
DEPT TABLE
EMP TABLE
BONUS TABLE
SALGRADE TABLE
FB_QUERY1 TABLE
FB_QUERY2 TABLE
FB_TABLE TABLE
SYS_TEMP_FBT TABLE
T TABLE
9 rows selected.
SCOTT@ORA10G>
SCOTT@ORA10G>show recyclebin
SCOTT@ORA10G>
SCOTT@ORA10G>SELECT original_name,object_name,type,ts_name,droptime FROM user_recyclebin;
no rows selected
SCOTT@ORA10G>
此时我们发现,与表t已不在回收站,相关的对象也已都不在回收站了
4)
查看对象状态,我们会发现,还有两个对象的名字以回收站的格式定义的,一个状态是有效的,一个是失效的,有效的为索引,无效的为触发器,也就是说,当做闪回删除的时候,表的相关对象也都跟着闪回回来,不过,名字确还是当初在回收站中的名字,并且,触发器的状态已变为失效
SCOTT@ORA10G>SELECT object_name,object_type,status FROM user_objects;
OBJECT_NAME OBJECT_TYPE STATUS
—————————— ——————- ——-
PK_DEPT INDEX VALID
DEPT TABLE VALID
EMP TABLE VALID
PK_EMP INDEX VALID
BONUS TABLE VALID
SALGRADE TABLE VALID
FB_QUERY1 TABLE VALID
FB_QUERY2 TABLE VALID
TRG_FB_TABLE TRIGGER VALID
SYS_TEMP_FBT TABLE VALID
T TABLE VALID
BIN$zn7Pezt2lLbgQKjAIAEKlA==$0 TRIGGER INVALID
FB_TABLE TABLE VALID
BIN$zn7Pezt1lLbgQKjAIAEKlA==$0 INDEX VALID
IDX_FB_TABLE INDEX VALID
15 rows selected.
SCOTT@ORA10G>
5)
重新编译触发器、重命名触发器
SCOTT@ORA10G>alter trigger “BIN$zn7Pezt2lLbgQKjAIAEKlA==$0″ compile;
Trigger altered.
SCOTT@ORA10G>SELECT object_name,object_type,status FROM user_objects;
OBJECT_NAME OBJECT_TYPE STATUS
—————————— ——————- ——-
PK_DEPT INDEX VALID
DEPT TABLE VALID
EMP TABLE VALID
PK_EMP INDEX VALID
BONUS TABLE VALID
SALGRADE TABLE VALID
FB_QUERY1 TABLE VALID
FB_QUERY2 TABLE VALID
TRG_FB_TABLE TRIGGER VALID
SYS_TEMP_FBT TABLE VALID
T TABLE VALID
BIN$zn7Pezt2lLbgQKjAIAEKlA==$0 TRIGGER VALID
FB_TABLE TABLE VALID
BIN$zn7Pezt1lLbgQKjAIAEKlA==$0 INDEX VALID
IDX_FB_TABLE INDEX VALID
15 rows selected.
SCOTT@ORA10G>
SCOTT@ORA10G>alter trigger “BIN$zn7Pezt2lLbgQKjAIAEKlA==$0″ rename to trg_t;
Trigger altered.
SCOTT@ORA10G>SELECT object_name,object_type,status FROM user_objects;
OBJECT_NAME OBJECT_TYPE STATUS
—————————— ——————- ——-
PK_DEPT INDEX VALID
DEPT TABLE VALID
EMP TABLE VALID
PK_EMP INDEX VALID
BONUS TABLE VALID
SALGRADE TABLE VALID
FB_QUERY1 TABLE VALID
FB_QUERY2 TABLE VALID
TRG_FB_TABLE TRIGGER VALID
SYS_TEMP_FBT TABLE VALID
T TABLE VALID
TRG_T TRIGGER VALID
FB_TABLE TABLE VALID
BIN$zn7Pezt1lLbgQKjAIAEKlA==$0 INDEX VALID
IDX_FB_TABLE INDEX VALID
15 rows selected.
SCOTT@ORA10G>
此时闪回已经完成,但要注意的是,索引虽然已经闪回,但是名字却没有改回来。
二、rename回收站中的表
我们知道回收站中的表是可以查询的,那么,我们是否可以将其rename了呢?
答案是肯定的,不过,它依然在回收站中。
SCOTT@ORA10G>create table ha as select 1 as x from dual;
Table created.
SCOTT@ORA10G>drop table ha;
Table dropped.
SCOTT@ORA10G>
SCOTT@ORA10G>SELECT original_name, object_name FROM user_recyclebin where original_name=’HA’;
ORIGINAL_NAME OBJECT_NAME
————————— ——————————
HA BIN$zn7Pezt7lLbgQKjAIAEKlA==$0
SCOTT@ORA10G>select * from “BIN$zn7Pezt7lLbgQKjAIAEKlA==$0″;
X
———-
1
SCOTT@ORA10G>rename “BIN$zn7Pezt7lLbgQKjAIAEKlA==$0″ to HA2;
Table renamed.
SCOTT@ORA10G>select * from ha2;
X
———-
1
SCOTT@ORA10G>delete ha2;
delete ha2
*
ERROR at line 1:
ORA-38301: can not perform. DDL/DML over objects in Recycle Bin
SCOTT@ORA10G>show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
—————- —————————— ———— ——————-
HA HA2 TABLE 2012-10-09:10:18:32
SCOTT@ORA10G>
通过这个测试我们知道,回收站中的表是不允许DDL/DML操作的。
三、后进先出
如回收站中存在两个相同的源表名,则闪回时总是闪回最近的版本,如果闪回特定的表,需要指定该表在回收站中的名称。如下
SCOTT@ORA10G>create table hehe(x1 int);
Table created.
SCOTT@ORA10G>drop table hehe;
Table dropped.
SCOTT@ORA10G>create table hehe(x1 int,x2 int);
Table created.
SCOTT@ORA10G>drop table hehe;
Table dropped.
SCOTT@ORA10G>create table hehe(x1 int,x2 int,x3 int);
Table created.
SCOTT@ORA10G>drop table hehe;
Table dropped.
SCOTT@ORA10G>
SCOTT@ORA10G>SELECT original_name, object_name FROM user_recyclebin where original_name=’HEHE’;
ORIGINAL_NAME OBJECT_NAME
————————— ——————————
HEHE BIN$zn7Pezt8lLbgQKjAIAEKlA==$0
HEHE BIN$zn7Pezt+lLbgQKjAIAEKlA==$0
HEHE BIN$zn7Pezt9lLbgQKjAIAEKlA==$0
SCOTT@ORA10G>
SCOTT@ORA10G>desc “BIN$zn7Pezt8lLbgQKjAIAEKlA==$0″
Name Null? Type
———————————- ——– —————————-
X1 NUMBER(38)
SCOTT@ORA10G>desc “BIN$zn7Pezt+lLbgQKjAIAEKlA==$0″
Name Null? Type
———————————- ——– —————————-
X1 NUMBER(38)
X2 NUMBER(38)
X3 NUMBER(38)
SCOTT@ORA10G>desc “BIN$zn7Pezt9lLbgQKjAIAEKlA==$0″
Name Null? Type
———————————- ——– —————————-
X1 NUMBER(38)
X2 NUMBER(38)
SCOTT@ORA10G>flashback table hehe to before drop;
Flashback complete.
–此时我们发现,闪回的表为最后删除的那个包含三个字段的表,即“后进先出”
SCOTT@ORA10G>desc hehe;
Name Null? Type
———————————- ——– —————————-
X1 NUMBER(38)
X2 NUMBER(38)
X3 NUMBER(38)
SCOTT@ORA10G>
SCOTT@ORA10G>flashback table “BIN$zn7Pezt8lLbgQKjAIAEKlA==$0″ to before drop rename to hehe1;
Flashback complete.
SCOTT@ORA10G>
SCOTT@ORA10G>desc hehe1
Name Null? Type
———————————– ——– —————————-
X1 NUMBER(38)
SCOTT@ORA10G>
四、清空回收站
1)将整个表空间的回收站内容全部清空:
PURGE TABLESPACE ts_name;
2)清空某个表空间上某个用户回收站中的对象:
PURGE TABLESPACE ts_name USER user_name;
3)清空当前用户下回收站:
PURGE RECYCLEBIN;
4)当以DBA身份登录时,可以清空所有表空间上回收站:
PURGE DBA_RECYCLEBIN;
五、回收站注意事项
1)闪回删除不适用于:
- 驻留在 SYSTEM 表空间中的表
- 使用细粒度级审计或虚拟专用数据库的表
- 驻留在字典管理表空间中的表
- 已清除的表,无论是手动清除的,还是在空间压力下自动清除的
2)以下相关对象不受保护:
- 位图联接索引
- 实体化视图日志
- 引用完整性约束条件
- 在删除表前删除的索引
注:位图连接索引不受保护,此处的位图连接索引非是位图索引。
以上列举的的操作都不适用于闪回删除,下面做一个系统表空间中的表不适用于闪回删除的测试:
SCOTT@ORA10G>create table ha tablespace system as select 1 as x from dual;
Table created.
SCOTT@ORA10G>drop table ha;
Table dropped.
SCOTT@ORA10G>show recyclebin;
SCOTT@ORA10G>
六、小结
闪回删除的功能非常实用,不过一定不要过于依赖回收站功能,因为,回收站的使用有好多注意事项(如:system表空间、表空间不足等情况),以免乐极生悲。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/23009281/viewspace-758019/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23009281/viewspace-758019/