Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN)

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

-- 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

限时福利1:原价 129 元,最后2天仅需 69 元!后天涨价至98元 限时福利2:购课进答疑群专享柳峰(刘运强)老师答疑服务 限时福利3:购课添加助教领取价值 800 元的编程大礼包 为什么需要掌握高性能的MySQL实战? 由于互联网产品用户量大、高并发请求场景多,因此对MySQL的性能、可用性、扩展性都提出了很高的要求。使用MySQL解决大量数据以及高并发请求已经是程序员的必备技能,也是衡量一个程序员能力和薪资的标准之一。 为了让大家快速系统了解高性能MySQL核心知识全貌,我为你总结了「高性能 MySQL 知识框架图」,帮你梳理学习重点,建议收藏! 【课程设计】 课程分为四大篇章,将为你建立完整的 MySQL 知识体系,同时将重点讲解 MySQL 底层运行原理、数据库的性能调优、高并发、海量业务处理、面试解析等。 一、性能优化篇: 主要包括经典 MySQL 问题剖析、索引底层原理和事务与锁机制。通过深入理解 MySQL 的索引结构 B+Tree ,学员能够从根本上弄懂为什么有些 SQL 走索引、有些不走索引,从而彻底掌握索引的使用和优化技巧,能够避开很多实战中遇到的“坑”。 二、MySQL 8.0新特性篇: 主要包括窗口函数和通用表表达式。企业中的许多报表统计需求,如果不采用窗口函数,用普通的 SQL 语句是很难实现的。 三、高性能架构篇: 主要包括主从复制和读写分离。在企业的生产环境中,很少采用单台MySQL节点的情况,因为一旦单个节点发生故障,整个系统都不可用,后果往往不堪设想,因此掌握高可用架构的实现是非常有必要的。 四、面试篇: 程序员获得工作的第一步,就是高效的准备面试,面试篇主要从知识点回顾总结的角度出发,结合程序员面试高频MySQL问题精讲精练,帮助程序员吊打面试官,获得心仪的工作机会。
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页