简易总结:

       1、如果删除了表可以考虑flashback drop (表不在system表空间)

       2、如果是一个表几条记录可以考虑flashback table(sys用户下的表不支持)

       3、如果涉及的表比较多,那么可以考虑flashback database,但要确认是否启用了闪回数据库,默认未打开

       4、如果修改过多次,那么可以考虑使用flashback transaction query确认,使用UNDO_SQL来恢复


一、闪回介绍  

       Flashback 技术是以Undo  segment中的内容为基础的, 因此受限于UNDO_RETENTON参数。要使用flashback 的特性,必须启用自动撤销管理表空间。(undo_management string  AUTO)

       在Oracle 10g中, Flash  back家族分为以下成员: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version  Query,Flashback Transaction Query三种)和Flashback Table。

       在Oracle 11g里又出了一个新特性:Oracle Flashback Data Archive. FDA通过将变化数据另外存储到创建的闪回归档区(Flashback Archive)中,以和undo区别开来,这样就可以为闪回归档区单独设置存储策略,使之可以闪回到指定时间之前的旧数据而不影响undo策略。


1、闪回的种类

       1)flashback drop 依赖回收站recyclebin   删除表了,闪回到DROP表之前

          有两种情况,表是不进回收站的:第一种原始表在SYSTEM表空间。第二种当前对象在DMT表空间中删除。

          删除表时,相关的索引,触发器也被删除,函数,存储过程则不会,所以函数或者存储过程等就需要使用Flashback Query来实现。

SQL> drop table ttt;
              Table dropped.
              SQL> select * from user_recyclebin;
               。。。。。。。
              SQL> flashback table ttt to before drop;如原表名已占用,只能重命名(flashback table ttt to before dorp rename to xx)
              Flashback complete.
              SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop; 这样也行。如果有重名的话
              SQL> select * from ttt;
              
              ---------- ----------

                    

                    

              Flashback Drop需要注意的地方:

1). 只能用于非系统表空间和本地管理的表空间

2). 对象的参考约束不会被恢复,指向该对象的外键约束需要重建。

3). 对象能否恢复成功,取决与对象空间是否被覆盖重用。

4). 当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop 时,也不能恢复依赖其的物化视图,需要dba手工介入重新创建。

5). 对于Recycle Bin中的对象,只支持查询.

 

       2)flashback table (sys用户下的表不支持)删除表中的数据后,闪回到删除数据之前。可以处理错误删除或修改数据

              依赖UNDO表空间,11G之后增加了,可以单独设置闪回表空间。设置保存多少时间。

        Flashback  table 命令支持同时操作多个表,如:flashback table a,b ,c要么都成功,要么都失败,同一事物中。

       例子:

SQL> delete t1 where id='1';
              1 row deleted.
              SQL> commit;
              SQL> flashback table t1 to scn 1946891;
              flashback table t1 to scn 1946891
                     
              ERROR at line 1:
              ORA-08189: cannot flashback the table because row movement is not enabled
              SQL> alter table t1 enable row movement;  因为闪回来的数据ROWID会变化,那么必须要启用ROW MOVEMENT,禁用DISABLE
              Table altered.
              SQL> flashback table t1 to scn 1946891;
              Flashback complete.
              SQL> select * from t1;
                     ID NAME
              ---------- ----------------------------------------
                     
                     
       查询是否启动了row movment
SQL> select row_movement from user_tables where table_name='C';
ROW_MOVE 
-------- 
ENABLED

      

       3)flashback query闪回查询可以处理行的删除. 

      Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据。依赖于UNDO,查询数据方式只需要在标准查询语句的表名后面跟上as of  timestamp(基于时间)或as of scn(基于scn)即可

         语法:select * from tablename as of timestamp|scn

例子: select * from t as of scn 696842   10G才支持,9I一般使用dbms_flashback这个包里的函数来实现
                 select * from test1 as of timestamp to_timestamp('12-01-13 16:59:29','YY-MM-DD hh24:mi:ss');

     

·    flashback query 对v$tables,x$tables等动态性能视图无效,不过对于dba_*,all_*,user_*等数据字典是有效的。

  该特性也完全支持访问远端数据库,比如select * from tbl@dblink as of scn 3600;的形式。

·    as of timestamp的确非常易用,但是在某些情况下,我们建议使用as of scn的方式执行flashback query,比如需要对多个相互有主外键约束的表进行恢复时,如果使用as of timestamp 的方式,可能会由于时间点不统一的缘故造成数据选择或插入失败,通过scn方式则能够确保记录的约束一致性。

          (SCN 与 timestamp关系见下面的补充)

      

       4)flashback vession query闪回版本查询。主要用来查询

      Flashback  Query 只能看到某一点的对象状态,  Oracle  10g引入的Flashback Version  Query可以看到过去某个时间段内,记录是如何发生变化的。版本查询是通过一个伪列来查询:ORA_ROWSCN(Oracle 10g新增的),暂且把它看作是记录最后一次被提交修改时的SCN。

例子:        
              04:32:17 SQL> insert into t1 values(5,6);
              1 row created.
              04:32:43 SQL> commit;
              Commit complete.
              04:32:47 SQL> insert into t1 values(7,8);
              1 row created.
              04:32:58 SQL> commit;
              Commit complete.
              04:33:01 SQL> insert into t1 values(9,10);
              1 row created.
              04:33:17 SQL> insert into t1 values(11,12);
              1 row created.
        当前表的版本查询:
              sql>select versions_xid,versions_operation,versions_startscn,versions_starttime,
                     versions_endscn,versions_endtime,id,name
                     from  test1.t1 versions between scn minvalue and maxvalue
       
              sql>update test1.t1 set id='111' where id='11' 
              
       select current_scn from v$database; 查询当前SCN
       SELECT ID,NAME,VERSIONS_STARTSCN STARTSCN,VERSIONS_ENDSCN ENDSCN,VERSIONS_OPERATION OPERATION,VERSIONS_XID XID
        FROM T1 VERSIONS BETWEEN SCN 2942841 AND 2942947;
--VERSIONS_STARTSCN:该条记录操作时的SCN,如果为空,表示该行记录是在查询范围外创建的
--VERSIONS_ENDSCN:该条记录失效时的SCN,如果为空,说明记录在这段时间无操作,或者已经被删数,配合VERSIONS_OPERATION
--VERSIONS_OPERATION:I表示insert、D表示delete、U表示update
--VERSIONS_XID:该操作的事务ID

 

       5)flash transaction query 闪回事务查询

      Flashback  Transaction  Query也是使用UNDO信息来实现。利用这个功能可以查看某个事务执行的所有变化,它需要访问flashback_transaction_query视图,这个视图的XID列代表事务ID,利用这个ID可以区分特定事务发生的所有数据变化。

              select * from flashback_transaction_query这个数据量来源于UNDO表空间,一般生产库数据量非常大

       例子:select * from flashback_transaction_query where xid='06001D0078030000'

              就可以查到UNDOSQL:update "TEST1"."T1" set "ID" = '11' where ROWID = 'AAANIhAAGAAAAAUAAD';这样执行这条UNDO sql就可以完全回退。

             

       查询XID示例:

SQL> insert into B values(3); 
已创建 1  行。
SQL> commit; 
提交完成。
SQL> select * from B; 
        ID 
       ---------- 
         1 
         2 
         3 
  
       查看视图,每个事务都对应相同的XID
SQL>Select  xid,operation,commit_scn,undo_sql  from  flashback_transaction_query
where  xid  in  (Select  versions_xid  from  B  versions  between  scn  minvalue  and maxvalue);
  
或者
SQL>select  xid,commit_scn,commit_timestamp,operation,undo_sql
from flashback_transaction_query q
where  q.xid  in(select  versions_xid  from  B  versions
between scn 413946 and 413959); 
  
XID                            OPERATION           COMMIT_SCN  UNDO_SQL
-----------------------------------------------------------------------------------------------------
03001C006A020000 DELETE                                  1100723
insert into "SYS"."B"("ID") values ('4');
03001C006A020000 DELETE                   
insert into "SYS"."B"("ID") values ('3');
03001C006A020000 DELETE                                  1100723
insert into "SYS"."B"("ID") values ('2');
       SQL> DESC FLASHBACK_TRANSACTION_QUERY --能获得这个事务执行时的很多信息,包括UNDO语句
 Name       
 ----------------- -------- ------------
 XID                RAW(8)    --事务ID,对应Versions Query中的VERSIONS_XID
 START_SCN          NUMBER       --事务开始时的SCN
 START_TIMESTAMP    DATE         --事务开始时间
 COMMIT_SCN         NUMBER    --事务提交时的SCN,该列为空的话,说明事务为活动事务
 COMMIT_TIMESTAMP   DATE     --事务提交时间
 LOGON_USER         VARCHAR2(30) --操作用户
 UNDO_CHANGE#       NUMBER    --UNDO SCN
 OPERATION          VARCHAR2(32) --执行操作,有几个值:Delete、Insert、Update、B、UNKNOWN
 TABLE_NAME         VARCHAR2(256)--DML操作对象的表名
 TABLE_OWNER        VARCHAR2(32) --表的属主
 ROW_ID             VARCHAR2(19) --DML操作记录的行地址
 UNDO_SQL           VARCHAR2(4000)--撤销该操作对应的SQL

补充:

1、回收站

初始化参数recyclebin 用于控制是否启用recyclebin功能,缺省是ON,可以使用OFF关闭

禁用及开启该功能:
SQL> alter system set recyclebin=off; 
SQL> alter system set recyclebin=on;
        查看回收站里的对象:
                 SQL> show recyclebin
              
ORIGINAL_NAME            OBJECT_NAME
-------------------------------- ------------------------------
A

                             

              查看recyblebin对象里的内容:

SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";

也可以手动的删除Recycle Bin占用的空间:

  1). Purge tablespace tablespace_name :用于清空表空间的Recycle Bin

  2).  Purge  tablespace  tablespace_name  user  user_name:清空指定表空间的Recycle Bin中指定用户的对象

  3). Purge recyclebin: 删除当前用户的Recycle Bin中的对象

  4).  Purge  dba_recyclebin: 删除所有用户的Recycle  Bin中的对象,该命令要sysdba权限

  5). Drop table table_name purge:  删除对象并且不放在Recycle Bin中,即永久的删除,不能用Flashback恢复。

  6).  Purge  index  recycle_bin_object_name:当想释放Recycle bin的空间,又想能恢复表时,可以通过释放该对象的index所占用的空间来缓解空间压力。因为索引是可以重建的。