Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN)

系统 1829 0

--==============================================

-- Oracle 闪回特性 (FLASHBACK DROP & RECYCLEBIN)

--==============================================

 

    FLASHBACK DROP 特性允许在不丢失任何数据库的情况下将指定的表恢复至其被删除的时间点,并保持数据库为当前状态。闪回删除并不是

真正的删除表,而是把该表重命名并放入回收站,类似于 Windows 的回收站一样。当某个活动对象需要使用该表所占用的空间时,该表才会被真

正删除。只要空间未被复用,该表即可恢复。本文主要讲述了 FLASHBACK DROP 特性以及闪回特性中回收站 (RECYCLEBIN) 的管理。

 

一、 FLASHBACK DROP 的功能

    将先前删除的表恢复到删除之前的状态

    恢复该表的索引以及触发器,授权

    恢复该表的约束,包括唯一约束、主键约束、非空约束。外键约束不可恢复

    可以实现基于系统和基于会话的 flash drop 操作

        alter system set recyclebin = on | off ;

        alter session set recyclebin = on | off ;

   

    drop table ( oracle 10g ) 命令并不真正删除表 , 在内部被映射为 rename 命令 , 即是将其重命名之后放入回收站。    

 

二、理解表重名的过程

    scott@ORCL > create table tb_emp as select * from emp ;       -- 基于 emp 表来创建表 tb_emp

 

    scott@ORCL > alter table tb_emp add constraint empno_pk      -- 添加主键约束 , 将产生主键索引

      2   primary key ( empno );

     

    scott@ORCL > alter table tb_emp add constraint ename_uk      -- 添加唯一约束 , 将产生唯一索引

      2   unique ( ename );

     

    scott@ORCL > alter table tb_emp add constraint sal_ck check ( sal > 0 );      -- 添加 check 约束

 

    scott@ORCL > alter table tb_emp modify job constraint job_nn not null;   -- 添加非空约束

 

    scott@ORCL > alter table tb_emp add constraint dept_fk                   -- 添加外键约束

      2   foreign key ( deptno ) references dept ( deptno ) on delete cascade ;

 

    scott@ORCL > select constraint_name , constraint_type            -- 查看 tb_emp 表上的所有约束

      2   from user_constraints where table_name = 'TB_EMP' ;

 

    CONSTRAINT_NAME C

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

    EMPNO_PK         P

    ENAME_UK         U

    SAL_CK           C

    JOB_NN           C

    DEPT_FK          R       

   

    -- 下面查看表 tb_emp 所在文件的 id, 块的起始 id, 大小 , 以及该对象的对象 id

    sys@ORCL > select file_id , block_id , bytes from dba_extents where segment_name = 'TB_EMP' ;

 

       FILE_ID    BLOCK_ID       BYTES

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

              4         393       65536

             

    sys@ORCL > select object_name , object_id from dba_objects   -- 查看表 tb_emp 的对象 ID

      2   where object_name = 'TB_EMP' ;

 

    OBJECT_NAME            OBJECT_ID

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

    TB_EMP                     54493     

   

    -- 对表进行重命名

    scott@ORCL > alter table tb_emp rename to tb_employees ;

 

    sys@ORCL > select file_id , block_id , bytes from dba_extents   -- 重命名后所在文件的 id, 块的起始 id, 大小没有发生变化

      2   where segment_name = 'TB_EMPLOYEES' ;

 

       FILE_ID    BLOCK_ID       BYTES

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

              4         393       65536

         

    sys@ORCL > select object_name , object_id from dba_objects   -- 重命名后对象 ID 没有发生变化

      2   where object_name = 'TB_EMPLOYEES' ;

 

    OBJECT_NAME            OBJECT_ID

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

    TB_EMPLOYEES               54493

 

    scott@ORCL > select index_name , index_type               -- 重命名后索引和约束也没有发生变化

        2   from user_indexes where table_name = 'TB_EMPLOYEES'

      3   union all

      4   select constraint_name , constraint_type

      5   from user_constraints where table_name = 'TB_EMPLOYEES' ;

 

    INDEX_NAME                      INDEX_TYPE

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

    EMPNO_PK                        NORMAL

    ENAME_UK                        NORMAL

    EMPNO_PK                        P

    ENAME_UK                        U

    SAL_CK                          C

    JOB_NN                          C

    DEPT_FK                          R

   

    从上面的演示可以看出对于表的重命名仅仅是修改了表名,而对于表对象的 ID ,以及表存放的位置,块的起始,大小等并未发生实质

    性的变化。

   

三、删除表并实施闪回

    1. 删除表 tb_employees 并查看回收站的信息

        scott@ORCL > drop table tb_employees ;

 

        scott@ORCL > select object_name , original_name , can_undrop ,

          2   base_object from user_recyclebin ;

 

        OBJECT_NAME                     ORIGINAL_NAME                     CAN BASE_OBJECT

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

        BIN$k1zC3yEiwZvgQAB / AQBRVw == $0 TB_EMPLOYEES                      YES 54493

        BIN$k1zC3yEhwZvgQAB / AQBRVw == $0 ENAME_UK                          NO   54493

        BIN$k1zC3yEgwZvgQAB / AQBRVw == $0 EMPNO_PK                          NO   54493

 

        scott@ORCL > select count ( 1 ) from "BIN$k1zC3yEiwZvgQAB/AQBRVw==$0" ;   -- 可以使用回收站名来访问对象,但要对对象加双引号

 

          COUNT ( 1 )

        ----------

                13

   

    2. 实施闪回并查看闪回后的情况

        scott@ORCL > flashback table tb_employees to before drop ;    -- 进行闪回

 

        Flashback complete .

 

        scott@ORCL > select count ( 1 ) from tb_employees ;              -- 闪回后表存在并且可以访问

 

          COUNT ( 1 )

        ----------

                13

 

        scott@ORCL > select index_name , index_type                    -- 查看闪回后索引,约束的情况,发现其名称仍然为 BIN$ 名称

          2   from user_indexes where table_name = 'TB_EMPLOYEES'

          3   union all

          4   select constraint_name , constraint_type

          5   from user_constraints where table_name = 'TB_EMPLOYEES' ;

 

        INDEX_NAME                      INDEX_TYPE

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

        BIN$k1zC3yEgwZvgQAB / AQBRVw == $0 NORMAL

        BIN$k1zC3yEhwZvgQAB / AQBRVw == $0 NORMAL

        BIN$k1zC3yEcwZvgQAB / AQBRVw == $0 P

        BIN$k1zC3yEdwZvgQAB / AQBRVw == $0 U

        BIN$k1zC3yEewZvgQAB / AQBRVw == $0 C

        BIN$k1zC3yEfwZvgQAB / AQBRVw == $0 C        

       

        从上面的查询可以看出闪回之后索引约束的名字还是使用了以 BIN 开头,由系统生成的名字,可以将其改回,但外键约束已经不存在了。

   

    3. 尝试对表 DML 操作

        scott@ORCL > insert into tb_employees ( empno , ename , job , sal , deptno )

          2   select 9999 , 'Robinson' , 'DBA' , 3000 , 50 from dual ;

 

        1 row created .       -- 可以成功插入, deptno 列的外键约束已经被删除,故 deptno 为号成功插入

 

        scott@ORCL > alter index "BIN$k1zC3yEgwZvgQAB/AQBRVw==$0" rename to EMPNO_PK ;

 

        Index altered .       -- BIN 开头的索引改回原来的名字,其余的约束名修改在此省略

       

    4. 下面演示表空间不足时无法闪回表删除的问题  

        sys@ORCL > select tablespace_name , sum ( bytes / 1024 / 1024 ) || ' M'

          2   from dba_free_space where tablespace_name = 'TBS1'

          3   group by tablespace_name ;      -- 表空间 tbs1 的可用空间为 M

 

        TABLESPACE_NAME                 SUM ( BYTES / 1024 / 1024 )|| 'M'

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

        TBS1                            .9375 M  

 

        flasher@ORCL > create table tb1 tablespace tbs1 as select * from dba_objects

          2   where rownum < 6000 ;

 

        sys@ORCL > select tablespace_name , sum ( bytes / 1024 / 1024 ) || ' M'

          2   from dba_free_space where tablespace_name = 'TBS1'

          3   group by tablespace_name ;   -- 在该表空间创建表 tb1 之后,可用空间为 .25M

 

        TABLESPACE_NAME                 SUM ( BYTES / 1024 / 1024 )|| 'M'

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

        TBS1                            .25 M

       

        flasher@ORCL > drop table tb1 ;    -- 将表 tb1 删除

 

        flasher@ORCL > show recyclebin ;   -- 删除后的对象位于回收站中

        ORIGINAL NAME     RECYCLEBIN NAME                 OBJECT TYPE   DROP TIME

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

        TB1               BIN$k2oZsEiaG7LgQAB / AQAZMA == $0 TABLE         2010 - 10 - 25 : 12 : 05 : 18    

 

        flasher@ORCL > select object_name , original_name , can_undrop ,

          2   base_object from user_recyclebin ;

 

        OBJECT_NAME                     ORIGINAL_N CAN BASE_OBJECT

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

        BIN$k2oZsEiaG7LgQAB / AQAZMA == $0 TB1         YES        54531

       

        sys@ORCL > select tablespace_name , sum ( bytes / 1024 / 1024 ) || ' M'

          2    from dba_free_space where tablespace_name = 'TBS1'

          3    group by tablespace_name ;    -- 表空间 tbs1 显示的可用空间已返还为 1M

                                          -- 但并不是真正为 M, 在需要表空间时 , 将自动清除回收站最老的对象 , 以满足当前空间需求

        TABLESPACE_NAME                 SUM ( BYTES / 1024 / 1024 )|| 'M'

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

        TBS1                            .9375 M

       

        sys@ORCL > select tablespace_name , autoextensible    -- 这个查询可以看出表空间 tbs1 不能自动扩展

          2   from dba_data_files where tablespace_name = 'TBS1' ;

 

        TABLESPACE_NAME AUT

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

        TBS1             NO

 

        flasher@ORCL > create table tb2 tablespace tbs1 as select * from dba_objects   -- 再次在表空间创建新表 tb2

          2   where rownum < 6000 ;   

 

        flasher@ORCL > show recyclebin ;   -- 此时回收站中原来的表 tb1 记录被自动清除

       

        flasher@ORCL > select object_name , original_name , can_undrop ,

          2   base_object from user_recyclebin ;

 

        no rows selected

 

        flasher@ORCL > flashback table tb1 to before drop ;   -- 此时表 tb1 不能被闪回

        flashback table tb1 to before drop

        *

        ERROR at line 1 :

        ORA - 38305 : object not in RECYCLE BIN

       

四、回收站的管理

    每个用户都拥有自己的回收站,且可以查看在自己模式中删除的表

    使用 purge 命令可以永久删除对象,回收空间

    purge 命令的几种常用形式

        drop table tbname purge     -- 直接删除表,而不置于回收站

        purge table tbname          -- 清除回收站中的 tbname

        purge index idx_name        -- 清除回收站中的索引 idx_name

        purge tablespace tablespace_name    -- 清除该表空间中所有已删除的对象

        purge tablespace tablespace_name user user_name   -- 清除表空间中指定用户删除的对象

        purge user_recyclebin       -- 清除指定用户已删除的所有对象

        purge dba_recyclebin        -- 清除所有已删除的对象

 

五、总结

    通过对上述表的删除及空间分配情况,总结如下:

    1. 表的删除被映射为将表的重命名,然后将其置于回收站

    2. 表的索引 , 触发器 , 授权闪回后将不受到影响 . 索引 , 触发器名字可以根据需要进行更改回原来名称

    3. 对于约束,如果是外键约束,表删除之后将不可恢复,其余的约束不受影响

    4. 如果要查询回收站中的对象,建议将对象名使用双引号括起来

    5. 闪回的实质并不能撤销已提交的事务,而是构造倒退原有事务影响的另一个事务

    6. 对于已经删除的表如果在所在的表空间新增对象由于空间不足的压力而被重用将导致闪回失败

    7. 对于表空间不足时,系统会自动清除回收站中最老的对象,以满足当前需求,即采用 FIFO 原则

    8. 闪回表的常用方法

        flashback table tbname to before drop ;

        flashback table tbname to before drop rename to newtbname;

        第二条语句用于被删除的表名已经被再次重用 , 故闪回之前必须将其改名为新表名 ,schema 不变化

    9. 如回收站中存在两个相同的原表名,则闪回时总是闪回最近的版本,如果闪回特定的表,需要指定

        该表在回收站中的名称。如

        flashback table "BIN$k1zC3yEiwZvgQAB/AQBRVw==$0" to before drop;

    10.flashback drop 不能闪回 truncate 命令截断的表,而是只能恢复 drop 之后的表

    11.flashback drop 不能闪回 drop user scott cascade 删除方案的操作 , 此只能用 flashback database

    12. system 表空间中存储的表无法启用 flashback drop ,且这些表会被立即删除

 

    与回收站相关两个重要的视图

        dba_recyclebin

        user_recyclebin     

 

六、 更多参考    

有关基于用户管理的备份和备份恢复的概念请参考:

        Oracle 冷备份

        Oracle 热备份

        Oracle 备份恢复概念

        Oracle 实例恢复

        Oracle 基于用户管理恢复的处理 ( 详细描述了介质恢复及其处理 )

       

    有关 RMAN 的恢复与管理请参考:

        RMAN 概述及其体系结

        RMAN 配置、监控与管理

        RMAN 备份详解

        RMAN 还原与恢复

       

    有关 Oracle 体系结构请参考:

        Oracle 实例和Oracle 数据库(Oracle 体系结构)

        Oracle 表空间与数据文件

        Oracle 密码文件

        Oracle 参数文件

Oracle 数据库实例启动关闭过程

        Oracle 联机重做日志文件(ONLINE LOG FILE)

        Oracle 控制文件(CONTROLFILE)

        Oracle 归档日志

 

Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论