[Oracle 10g] About Recycle bin

关于Oracle 10g 中的Recylebin,有两篇文章说得很详细,

(1) Flashback Table by Arup Nanda

(2) Using Oracle's recycle bin  by Natalka Roshak

本篇blog只是简单介绍如何去追溯recyclebin的本质。

Recyclebin是Oracle 10g中新加入的一个feature, 就像Windows操作系统提供的回收站一样,删除的东西(如果不是直接删除)都会先放到回收站里,之后我们可以把recycle bin中的东西restore出来。

这有助于解决有时候我们错误把一个表删除的问题,只要该表还存在recyclebin中,我们就可以很容易把它恢复出来,而不需要做很多的工作。这就是之前提到的Oracle 10g 增加的Flashback Table / Flashback Drop。

先看一个测试用例,创建一个表test_for_recyclebin, 插入一条记录,然后commit, 接下来drop该表,

 
scott@ORCL> create table test_for_recyclebin(version varchar2(20));
 
Table created.
 
scott@ORCL> insert into test_for_recyclebin values('Version 1');
 
1 row created.
 
scott@ORCL> commit;
 
Commit complete.
 
scott@ORCL> drop table test_for_recyclebin;
 
Table dropped.
 
scott@ORCL> select * from test_for_recyclebin;
select * from test_for_recyclebin
              *
ERROR at line 1:
ORA-00942: table or view does not exist
 
 
scott@ORCL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST_FOR_RECYCLE BIN$AjbtchOeRHiyRuwIoMqixA==$0 TABLE        2010-01-07:21:13:53
BIN
scott@ORCL> select * from "BIN$AjbtchOeRHiyRuwIoMqixA==$0";
 
VERSION
--------------------
Version 1
 
scott@ORCL> flashback table test_for_recyclebin to before drop;
 
Flashback complete.
 
scott@ORCL> select * from test_for_recyclebin;
 
VERSION
--------------------
Version 1

从上面测试用例可以看出,当把表test_for_recyclebin删除之后,该表被放到了recyclebin里(通过 show recyclebin 查看),但是表的名字被改成了以BIN$打头的样子 -- BIN$AjbtchOeRHiyRuwIoMqixA==$0

 

这里有个很重要的一点要注意的就是,把表drop之后,该表并没有从数据库中删除,(没有从该表所在的tablespace删除掉),只是被改了名字而已。

这可以从上面的测试用例看出,SELECT语句作用于改了名字的表上,得到的结果就是表test_for_recyclebin中的数据。然后通过Flashback table test_for_recyclebin to before drop可以"把表从recyclebin 中 restore出来”。(归根到底,都是对一些数据字典的更改操作)

那么究竟什么recyclebin呢, 其实recycle bin只是形象上的一种叫法,可以看作是逻辑上把被drop的表放到了一个”容器“里。

recyclebin 本质上是个视图,一共用两个recyclebin的视图:DBA_RECYCLEBIN 和 USER_RECYCLEBIN。 除了拥有DBA role的 user 可以访问dba_recyclebin, 看到所有schema对应的recyclebin, 每个普通user都只能访问到自己的recyclebin, 跟其他DBA_XXX / USER_XXX等视图一样。

为什么我们可以直接通过recyclebin来查询USER_RECYCLEBIN呢,很容易可以猜到RECYCLEBIN是个synonym, 下面来证明一下,

 
SQL> sho user
USER is "SYS"
SQL> select owner, object_id, object_type, temporary
  2  from all_objects where object_name='RECYCLEBIN';
 
OWNER                 OBJECT_ID OBJECT_TYPE         T
-------------------- ---------- ------------------- -
PUBLIC                     3877 SYNONYM             N
 
SQL> select * from all_synonyms where synonym_name = 'RECYCLEBIN';
 
OWNER                SYNONYM_NAME                   TABLE_OWNER                    TABLE_NAME
-------------------- ------------------------------ ------------------------------ -----------------
PUBLIC               RECYCLEBIN                     SYS                            USER_RECYCLEBIN
 
SQL> select owner, object_name, object_type from all_objects where object_name = 'USER_RECYCLEBIN';
 
OWNER                OBJECT_NAM OBJECT_TYPE
-------------------- ---------- -------------------
SYS                  USER_RECYC VIEW
                     LEBIN
 
PUBLIC               USER_RECYC SYNONYM
                     LEBIN
 
 
SQL>

可以看出不光RECYCLEBIN是个Synonym, USER_RECYCLEBIN也是个Synonym, 也就是我们在非SYS用户下访问RECYCLEBIN和USER_RECYCLEBIN用的都是Synonym, 他们都是视图USER_RECYCLEBIN的同义词。

scott@ORCL> select * from recyclebin;
 
no rows selected
 
scott@ORCL> select * from user_recyclebin;
 
no rows selected
 
scott@ORCL> desc recyclebin;
 Name
                                                                       Null?    Type
 ------------------------------------------------------------------------------------------------
 OBJECT_NAME
                                                                       NOT NULL VARCHAR2(30)
 ORIGINAL_NAME
                                                                                VARCHAR2(32)
 OPERATION
                                                                                VARCHAR2(9)
 TYPE
                                                                                VARCHAR2(25)
 TS_NAME
                                                                                VARCHAR2(30)
 CREATETIME
                                                                                VARCHAR2(19)
 DROPTIME
                                                                                VARCHAR2(19)
 DROPSCN
                                                                                NUMBER
 PARTITION_NAME
                                                                                VARCHAR2(32)
 CAN_UNDROP
                                                                                VARCHAR2(3)
 CAN_PURGE
                                                                                VARCHAR2(3)
 RELATED
                                                                       NOT NULL NUMBER
 BASE_OBJECT
                                                                       NOT NULL NUMBER
 PURGE_OBJECT
                                                                       NOT NULL NUMBER
 SPACE
                                                                                NUMBER
 
scott@ORCL>

可以调用DBMS_METADATA.GET_DLL来获取USER_RECYCLEBIN的定义,

select dbms_metadata.get_ddl('VIEW', 'USER_RECYCLEBIN', 'SYS') from dual;

 

结果如下,

CREATE OR REPLACE FORCE VIEW "SYS"."USER_RECYCLEBIN" ("OBJECT_NAME", "ORIGINAL_NAME", "OPERATION", "TYPE", "TS_NAME", "CREATETIME", "DROPTIME", "DROPSCN", "PARTITION_NAME", "CAN_UNDROP", "CAN_PURGE", "RELATED", "BASE_OBJECT", "PURGE_OBJECT", "SPACE") AS 
select o.name, r.original_name,
     decode(r.operation, 0, 'DROP', 1, 'TRUNCATE', 'UNDEFINED'),
     decode(r.type#, 1, 'TABLE', 2, 'INDEX', 3, 'INDEX',
                     4, 'NESTED TABLE', 5, 'LOB', 6, 'LOB INDEX',
                     7, 'DOMAIN INDEX', 8, 'IOT TOP INDEX',
                     9, 'IOT OVERFLOW SEGMENT', 10, 'IOT MAPPING TABLE',
                     11, 'TRIGGER', 12, 'CONSTRAINT', 13, 'Table Partition',
                     14, 'Table Composite Partition', 15, 'Index Partition',
                     16, 'Index Composite Partition', 17, 'LOB Partition',
                     18, 'LOB Composite Partition',
                     'UNDEFINED'),
     t.name,
     to_char(o.ctime, 'YYYY-MM-DD:HH24:MI:SS'),
     to_char(r.droptime, 'YYYY-MM-DD:HH24:MI:SS'),
     r.dropscn, r.partition_name,
     decode(bitand(r.flags, 4), 0, 'NO', 4, 'YES', 'NO'),
     decode(bitand(r.flags, 2), 0, 'NO', 2, 'YES', 'NO'),
     r.related, r.bo, r.purgeobj, r.space
om sys.obj$ o, sys.recyclebin$ r, sys.ts$ t
ere r.owner# = userenv('SCHEMAID')
and o.obj# = r.obj#
and r.ts# = t.ts#(+);

可以看到这个视图基于三张数据字典表sys.obj$, sys.recyclebin$, sys.ts$,  USER_RECYCLEBIN只是在视图中多了如下限制条件,

sys.recyclebin$.owner# = userenv(‘SCHEMAID’)

不难推测,sys.recyclebin$就是最终的根了,每次drop / restore 表这个数据字典都会有所记录。

原文地址:https://www.cnblogs.com/fangwenyu/p/1641632.html