一、闪回查询(Flashback Query)
1、闪回查询技术
1.1 闪回查询机制
    闪回查询是指利用数据库回滚段存放的信息查看指定表中过去某个时间点的数据信息,或过去某个时间段数据的变化情况,或某个事务对该表
的操作信息等。为了使用闪回查询功能,需要启动数据库撤销表空间来管理回滚信息。

1.2 撤销段(UNDO SEGMENT)简介
    大部分闪回技术都需要依赖撤销段中的撤销数据。撤销数据是反转DML语句结果所需的信息,只要某个事务修改了数据,那么更新前的原有数据
就会被写入一个撤销段。事务启动时,Oracle 会为其分配一个撤销段,事务和撤销段存在多对一的关系,即一个事务只能对应一个撤销段,多个事
务可以共享一个撤销段。

1.3 与撤销表空间相关的参数包括:
UNDO_MANAGEMENT:指定回滚段的管理方式,如果设置为AUTO,则采用撤销表空间自动管理回滚信息;
UNDO_TABLESPACE:指定用于回滚信息自动管理的撤销表空间名;
UNDO_RETENTIOIN:指定回滚信息的最长保留时间。

在不繁忙的数据库可以开启guarantee
SQL> alter tablespace undotbs1 retention guarantee;

2、闪回事务查询
2.1 闪回事务查询提供了一种查看事务级数据库变化的方法。
可以从FLASHBACK_TRANSATION_QUERY中查看回滚段中存储的事务信息。
例如:
SELECT operation,table_name,undo_sql FROM FLASHBACK_TRANSACTION_QUERY WHERE xid=HEXTORAW('01001B00A0050000');

2.2 通常将闪回事务查询与闪回版本查询相结合,先利用闪回版本查询获取事务ID及事务操作结果,然后利用事务ID查询事务的详细操作信息。
SELECT versions_xid,sal FROM scott.emp ERSIONS BETWEEN SCN MINVALUE AND MAXVALUE WHERE empno=7844;
SELECT operation,undo_sql FROM FLASHBACK_TRANSACTION_QUERY WHERE xid=HEXTORAW('01001B00A0050000');

3、闪回操作
3.1 启用表闪回首先要在表上支持行移动(在数据字典中设置标识来标识该操作可能会改变行ID,即同一条数据闪回成功后主键都一样,但行ID其实
    已经发生变化了)   
SQL> alter table emp enable row movement;

3.2 闪回表操作      
SQL> flashback table dept to timestamp to_timestamp('2016-09-10 11:00:00','yyyy-mm-dd hh24:mi:ss');

二、闪回数据库(Flashback Data)
1、闪回数据库的特性
Flashback Database 功能非常类似与RMAN的不完全恢复,它可以把整个数据库回退到过去的某个时点的状态,这个功能依赖于Flashback log 日志,
而且比RMAN更快速、高效。因此Flashback Database 可以看作是不完全恢复的替代技术。但它也有某些限制:
1.1 Flashback Database 不能解决Media Failure, 这种错误RMAN恢复仍是唯一选择
1.2 如果删除了数据文件或者利用Shrink技术缩小数据文件大小,这时不能用Flashback Database技术回退到改变之前的状态,这时候就必须
    先利用RMAN把删除之前或者缩小之前的文件备份restore 出来,然后利用Flashback Database 执行剩下的Flashback Datbase。
1.3 如果控制文件是从备份中恢复出来的,或者是重建的控制文件,也不能使用Flashback Database。
1.4 使用Flashback Database锁能恢复到的最早的SCN, 取决与Flashback Log中记录的最早SCN。

2、闪回数据库的工作原理
    Flashback Database 整个架构包括一个进程Recover Writer(RVWR)后台进程、Flashback Database Log日志、Flashback Buffer和闪回的数据文件。
一旦启用了闪回数据库,修改的块的前映像(before image)会不时地从数据库缓冲区的缓存中复制到SGA内的一个新的存储区域中,即闪回缓冲区
(Flashback Buffer)。通过一个新的后台进程——恢复写入器(RVWR)将这些数据刷新到Flash Recovery Area中的闪回日志(Flashback Database Log)文件。
闪回的过程,则是一个提取闪回日志-->将块映像复制回数据文件 的过程。
    这没有改变向日志缓冲区写入更改的常规程序,LGWR(日志写入器)然后将日志缓冲区刷新到日志文件;闪回日志记录是此操作的附属物。闪回日志不
是循环使用的,联机重做日志是循环使用的。当事务修改了buffer cache中的数据块时,会将改变前的值和改变后的值以重做记录的形式保存在log buffer
中,然后通过LGWR将重做记录写入联机重做日志中。但是在记录闪回日志时,只会将改变前的值保存在flashback buffer中,再由RVWR写入闪回日志中。
闪回时,从闪回日志的尾部向头部方向,依次取出闪回日志中的记录并应用在数据库上。而应用重做日志在进行实例恢复时,从闪回日志的头部向尾部方
向依次取出重做记录并应用到数据库上。

3、功能描述
    闪回数据库可将整个数据库回退到过去某个时间点,闪回表是某张表的时空穿梭,闪回数据库则是整个数据库的时空穿梭。当然,闪回点之后的所有
工作就丢失了,其实就相当于数据库的不完整恢复,所以只能以resetlogs模式打开数据库。闪回数据库会造成停机时间,当然相比于传统备份恢复机制,
恢复过程会快很多。

4、配置闪回数据库(RAC的闪回恢复区必须位于共享磁盘上,能被所有实例访问。)
SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /u01/app/archivelog
Oldest online log sequence     69
Next log sequence to archive   71
Current log sequence           71

SQL> show parameter db_recovery_file_dest
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      /u01/app/oracle/fast_recovery_
                                                 area
db_recovery_file_dest_size           big integer 4182M
SQL> show parameter db_flashback_retention_target
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     1440

SQL> alter system set db_recovery_file_dest_size = 10240M scope=both;
System altered.

SQL> alter database flashback on;
Database altered.

SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES

SQL> alter system archive log current;
System altered.
SQL> show parameter DB_RECOVERY_FILE_DEST
NAME                                 TYPE        VALUE
------------------------------------ ----------- ----------------------------------
db_recovery_file_dest                string      /u01/app/oracle/fast_recovery_area
db_recovery_file_dest_size           big integer 10G

SQL> show parameter DB_FLASHBACK_RETENTION_TARGET
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target        integer     1440

5、闪回数据库相关的几个视图
5.1 v$flashback_database_log
Flashback Database 所能回退到的最早时间,取决与保留的Flashback Database Log 的多少,该视图就可以查看许多有用的信息。
Oldest_flashback_scn / Oldest_flashback_time : 这两列用来记录可以恢复到最早的时点
Fashback_size: 记录了当前使用的Flash Recovery Area 空间的大小
Retention_target: 目标保存的实际(分钟)
Estimated_flashback_size: 根据策略对需要的空间大小的估计值

SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.

SQL>  select OLDEST_FLASHBACK_SCN os,OLDEST_FLASHBACK_TIME ot,RETENTION_TARGET rt ,FLASHBACK_SIZE fs,ESTIMATED_FLASHBACK_SIZE efs from v$flashback_database_log;
        OS OT                          RT         FS        EFS
---------- ------------------- ---------- ---------- ----------
   2219976 2017-04-26 11:02:28       1440  209715200  154951680

5.2 v$flashback_database_stat
这个视图用来对Flashback log  空间情况进行更细粒度的记录和估计。 这个视图以小时为单位记录单位时间内数据库的活动量,
Flashback_Data  代表 Flashback log 产生数量,
DB_Date  代表数据改变数量,
Redo_Date 代表日志数量,
通过这 3 个数量可以反映出数据的活动特点,更准确的预计 Flash Recovery Area 的空间需求
SQL> set line 150
SQL> select BEGIN_TIME bt,END_TIME et,FLASHBACK_DATA fd,DB_DATA dd,REDO_DATA rd,ESTIMATED_FLASHBACK_SIZE efs from v$flashback_database_stat;
BT                  ET                          FD         DD         RD        EFS
------------------- ------------------- ---------- ---------- ---------- ----------
2017-04-27 09:09:38 2017-04-27 09:35:21      81920     638976      43008          0
2017-04-27 08:09:35 2017-04-27 09:09:38    4399104    4939776    1470976  156745728
2017-04-27 07:09:32 2017-04-27 08:09:35    4128768    4898816    1358336  159178752
2017-04-27 06:09:29 2017-04-27 07:09:32    4284416    4980736    1508352  162177024
2017-04-27 05:09:26 2017-04-27 06:09:29    4456448    5570560    1486336  165298176
2017-04-27 04:09:23 2017-04-27 05:09:26    4415488    5177344    1446400  168517632
2017-04-27 03:09:20 2017-04-27 04:09:23    4014080    5185536    1362944  172179456
2017-04-27 02:09:17 2017-04-27 03:09:20    4767744    5095424    1634816  176898048
2017-04-27 01:09:14 2017-04-27 02:09:17    4415488    5332992    1556480  181051392
2017-04-27 00:09:11 2017-04-27 01:09:14    4530176    5357568    1481728  186384384
2017-04-26 23:09:08 2017-04-27 00:09:11    4431872    5275648    1570304  192307200
2017-04-26 22:09:05 2017-04-26 23:09:08   28606464   30031872   29907968  199409664
2017-04-26 21:09:02 2017-04-26 22:09:05   25034752   32915456   22842880  155590656
2017-04-26 20:08:59 2017-04-26 21:09:02    4603904    5177344    1482240  111550464
2017-04-26 19:08:56 2017-04-26 20:08:59    4374528    5193728    1420800  111697920

5.3 v$flashback_database_logfile
该视图主要记录闪回日志的详细信息,NAME闪回日志的位置,FIRST_CHANGE#闪回日志中记录的最早的SCN,FIRST_TIME闪回日志中记录的最早时间
SQL> col name for a75
SQL> select name,LOG#,BYTES,FIRST_CHANGE# ftchg,FIRST_TIME,TYPE from v$flashback_database_logfile;
NAME                                                                              LOG#      BYTES      FTCHG FIRST_TIME          TYPE
--------------------------------------------------------------------------- ---------- ---------- ---------- ------------------- ---------
/u01/app/oracle/fast_recovery_area/SHOPGUIDE/flashback/o1_mf_dj03g3do_.flb           1   52428800    2219976 2017-04-26 11:02:28 NORMAL
/u01/app/oracle/fast_recovery_area/SHOPGUIDE/flashback/o1_mf_dj03g5yc_.flb           2   52428800    2239371 2017-04-26 22:00:06 NORMAL
/u01/app/oracle/fast_recovery_area/SHOPGUIDE/flashback/o1_mf_dj19z8ln_.flb           3   52428800    2245689 2017-04-27 00:00:59 NORMAL
/u01/app/oracle/fast_recovery_area/SHOPGUIDE/flashback/o1_mf_dj1k1wmv_.flb           4   52428800          0                     RESERVED

5.4 v$flash_recovery_area_usage
视图记录闪回日志占快速恢复区的比例,还有文件数等
SQL> select * from v$flash_recovery_area_usage;
FILE_TYPE            PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE NUMBER_OF_FILES
-------------------- ------------------ ------------------------- ---------------
CONTROL FILE                          0                         0               0
REDO LOG                              0                         0               0
ARCHIVED LOG                          0                         0               0
BACKUP PIECE                          0                         0               0
IMAGE COPY                            0                         0               0
FLASHBACK LOG                      1.95                         0               4
FOREIGN ARCHIVED LOG                  0                         0               0

6、闪回实际应用
6.1 闪回到某个时间点和SCN
alter table TEST enable row movement;
flashback table TEST to timestamp to_timestamp('2016-12-25 16:04:56','yyyy-mm-dd hh24:mi:ss');
flashback table TEST to scn 1146940;

注:如在期间改变表结构,就无法恢复

6.2 查看一个小时前SCOTT.TEST的情况
select * from SCOTT.TEST as of timestamp sysdate-1/24 where EMPNO=7844;

6.3 查看5分钟内的变化情况
SQL> set lines 300 pages 1000
SQL> col versions_starttime format a19
SQL> select versions_xid,
            to_char(versions_starttime, 'yyyy-mm-dd hh24:mi:ss') versions_starttime,
            versions_startscn,
            versions_operation,
            sal
       from TEST versions between timestamp (systimestamp - interval'5' minute) and systimestamp
      where empno = 7369
   order by nvl(versions_startscn,-1);

VERSIONS_XID  VERSIONS_STARTTIME  VERSIONS_STARTSCN V SAL
---------------- ------------------- ----------------- - ----------
              1500
010003000A040000 2016-12-26 10:33:40        1534009 U       3444
08000400F6040000 2016-12-26 10:35:07        1534107 U       4589

基本语法:

SELECT column_name [,…] FROM table_name
[VERSIONS BETWEEN SCN|TIMESTAMP
MINVALUE|expression AND MAXVALUE|expression]
[AS OF SCN|TIMESTAMP expression]
WHERE condition

参数说明:
VERSIONS BETWEEN:用于指定闪回版本查询时查询的时间段或SCN段;
AS OF:用于指定闪回查询时查询的时间点或SCN。
在闪回版本查询的目标列中,可以使用下列几个伪列返回版本信息。
VERSIONS_STARTTIME:基于时间的版本有效范围的下界;
VERSIONS_ENDTIME:基于时间的版本有效范围的上界;
VERSIONS_STARTSCN:基于SCN的版本有效范围的下界;
VERSIONS_ENDSCN:基于SCN的版本有效范围的上界;
VERSIONS_XID:操作的事务ID;
VERSIONS_OPERATION:执行操作的类型,I 表示INSERT,D 表示DELETE,U 表示UPDATE。

基于VERSIONS BETWEEN TIMESTAMP的闪回版本查询。
SELECT versions_xid  XID,versions_starttime STARTTIME,versions_endtime ENDTIME,
versions_operation OPERATION, sal  FROM scott.emp
VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE
WHERE  empno=7844
ORDER BY STARTTIME;

基于VERSIONS BETWEEN SCN的闪回版本查询。
SELECT versions_xid ,to_char(versions_starttime, 'yyyy-mm-dd hh24:mi:ss') versions_starttime,
       to_char(versions_endtime, 'yyyy-mm-dd hh24:mi:ss') versions_endtime ,versions_startscn,
       versions_operation, sal
  FROM scott.emp VERSIONS BETWEEN timestamp (systimestamp - interval'13' minute) and systimestamp
 WHERE empno=7844
 ORDER BY nvl(versions_startscn,-1);

6.4 可以将数据恢复到过去某个时刻的状态。
某条数据:
UPDATE scott.emp SET sal=(SELECT sal FROM scott.emp AS OF TIMESTAMP TO_TIMESTAMP('2016-12-25 16:04:56','YYYY-MM-DDHH24:MI:SS')
                                    WHERE empno=7844
                         )
 WHERE empno=7844;
COMMIT;

注:在进行闪回版本查询时,可以同时使用VERSIONS 短语和 AS OF 短语。AS OF 短语决定了进行查询的时间点或SCN,VERSIONS 短语决定了
可见的行的版本信息。对于在VERSIONS BETWEEN下界之前开始的事务,或在 AS OF 指定的时间或SCN之后完成的事务,系统返回的版本信息为NULL。

6.5 限制生成的闪回数据量
默认情况下,如果启用了闪回数据库,那么会记录所有表空间的闪回数据。使用如下命令关闭表空间闪回属性:
alter tablespace <tablespace_name> flashback off;
可以在任何时候执行上面或在数据库处于mounted模式时执行下面的命令:
alter tablespace <tablespace_name> flashback on;
V$TABLESPACE视图提供了flashback_on列标记是否为表空间启用闪回:
SQL> select name, flashback_on from v$tablespace;
NAME                           FLA
------------------------------ ---
SYSTEM                         YES
SYSAUX                         YES
UNDOTBS1                       YES
USERS                          YES
TEMP                           YES
INDEX01                        YES
RMAN01                         YES
TBS_OGG                        YES
TEST10                         YES
FLASHBK_TB                     YES

6.6 闪回整个数据库
基于时间点的闪回
SQL> flashback database to timestamp sysdate-60/1440;
基于SCN的闪回
SQL> flashback database to scn 945956;

打开数据库:
在执行完flashback database 命令之后,oracle 提供了两种方式让你修复数据库:
(1) 直接 alter database open resetlogs 打开数据库,当然,指定scn 或者 timestamp 时间点之后产生的数据统统丢失。
(2) 先执行alter database open read only 命令以read-only 模式打开数据库,然后立刻通过逻辑导出的方式将误操作涉及表的数据导出,再执行
    recover database 命令以重新应用数据库产生的redo,将数据库修复到flashback database 操作前的状态,然后再通过逻辑导入的方式,将之
    前误操作的表重新导入,这样的话对现有数据的影响最小,不会有数据丢失。

闪回数据库需要注意的几点:
a.一旦关闭闪回数据库,flashback recovery area中的闪回日志将自动全部删除
b.即便以resetlogs打开数据库,当前闪回日志里的内容仍然保留,仍然可以继续进行闪回以restlogs方式打开数据库。之所以考虑以read only放是
  打开数据库,主要是因为以resetlog方式打开数据库后,用户即可操作数据库,无法校验闪回的准确性。另外,当闪回数据库与DATA GUARD结合后,
  当主库发生逻辑损坏,我们可以闪回备库,然后以 read only方式打开备库,将数据从备库中导出后导入到主库中,这样将对数据和业务的影响减
  小到最小。
c.如果闪回数据库的时间点之间进行了控制文件的恢复或重建,数据文件的收缩,或删除了某个表空间,则闪回将失败。
d.闪回日志在出现空间压力的情况下,oracle会自动删除闪回日志,则有可能导致无法闪回到指定的时间点。如果希望闪回到指定的时间点,可进行
  如下操作:
  SQL> create restore point must_to_flashback guarantee flashback database;
  这样我们就给当前时间点取 must_to_flashback 这个名字,确保能闪回到该时间点上
e.闪回删除 只能用于非系统表空间和本地管理的表空间
f.对象的参考约束、索引不会被恢复,指向该对象的外键约束需要重建。
g.对象能否恢复成功,取决与对象空间是否被覆盖重用。
h.当删除表时,信赖于该表的物化视图也会同时删除,但是由于物化视图并不会被放入recycle bin,因此当你执行flashback table to before drop
  时,也不能恢复依赖其的物化视图,需要dba 手工介入重新创建。
i.对于Recycle Bin中的对象,只支持查询。

三、闪回删除(Flashback Drop)
1、功能描述
    闪回删除可以轻松将一个已经被Drop的表还原回来。相应的索引,数据库约束也会被还原(除了外键约束)

2、原理描述
    Drop命令其实是Rename命令,早期的Oracle版本(10g之前),闪回删除意味着从数据字典中删除了该表的所有引用,虽然表中数据可能还存在,
但已成了孤魂野鬼,没法进行恢复了,10g版本之后,Drop命令则仅仅是一个Rename操作,所以恢复就很容易了。

3、测试闪回删除
3.1 查看原表
SQL> select count(*) from shopguide.t1;
  COUNT(*)
----------
        16
SQL> desc shopguide.t1
 Name                           Null?    Type
 ------------------------------ -------- ------------
 CUST_ID                          NUMBER
 TRADE_DT                         DATE
 WEIGHT                           NUMBER(6,2)

3.2 删除表
SQL> drop table shopguide.t1;
Table dropped.

3.3 查看回收站
SQL> set line 150
SQL> col original_name for a10
SQL> col ts_name for a10
SQL> col type for a10
SQL> select object_name,original_name,ts_name,type from dba_recyclebin where owner='SHOPGUIDE' and original_name='T1';
OBJECT_NAME                    ORIGINAL_N TS_NAME    TYPE
------------------------------ ---------- ---------- ----------
BIN$TWiWCi8aeabgU6QKqMCYmw==$0 T1         USERS      TABLE
BIN$Tgx3AHatMFzgU6QKqMAN6w==$0 T1         USERS      TABLE
BIN$TfkbT5oCRiPgU6QKqMDj+Q==$0 T1         USERS      TABLE

SQL> conn shopguide/shopguide
Connected.

SQL> show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME                OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
T1               BIN$Tgx3AHatMFzgU6QKqMAN6w==$0 TABLE        2017-04-26:13:53:51
T1               BIN$TfkbT5oCRiPgU6QKqMDj+Q==$0 TABLE        2017-04-25:14:48:08
T1               BIN$TWiWCi8aeabgU6QKqMCYmw==$0 TABLE        2017-04-18:10:23:47
.........

3.4 闪回删除表
SQL> flashback table T1 to before drop;
Flashback complete.

SQL> select count(*) from t1;
  COUNT(*)
----------
        16

3.5 如果存在多个具有相同原始名称的对象,那么将清除时间最久的对象。也可以通过指定回收站名称来避免混淆。
SQL> flashback table "BIN$TfkbT5oCRiPgU6QKqMDj+Q==$0" to before drop rename to T11;
Flashback complete.

SQL> select count(*) from t11;
  COUNT(*)
----------
     24929

3.6 清空用户回收站
SQL> purge user_recyclebin;
Recyclebin purged.

注:1.删除表并且不将它转移到回收站。drop table <table_name> purge;
    2.从回收站中清除表。purge table <table_name>;
    3.从回收站中清除索引,同样可以指定原始名称或回收站名称。purge index <index_name>;
    4.从表空间中清除所有删除的对象。purge tablespace <tablespace_name>;
    5.从表空间中清除属于一个用户的所有删除的对象。purge tablespace <tablespace_name> user <user_name>;
    6.清除删除的所有对象。purge user_recyclebin;
    7.除数据库上被删除的所有对象,需要DBA权限。purge dba_recyclebin;

四、闪回数据归档(Flashback Data Archive )
1、功能描述
    闪回数据归档可使表具有回退到过去任何时间点的能力,前面提到的闪回查询,闪回表都会受限于撤销数据是否失效,如果撤销数据被覆盖
重写了,闪回操作自然会失败,闪回删除则受限于表空间是否有足够可用空间,而闪回数据归档,则没有这些限制。

2、创建闪回归档
2.1 创建一个用户闪回数据归档的表空间,当然,也可以使用已经存在的表空间。
SQL> create tablespace flashbk_tb datafile '/u01/app/oracle/oradata/shopguide/flashbk.dbf' size 20m;
Tablespace created.

2.2 创建保留时间为2天的闪回归档
SQL> CREATE FLASHBACK ARCHIVE DEFAULT test_archive1 TABLESPACE flashbk_tb QUOTA 5M RETENTION 2 DAY;
Flashback archive created.

SQL> CREATE FLASHBACK ARCHIVE test_archive2 TABLESPACE flashbk_tb QUOTA 5M RETENTION 2 DAY;
Flashback archive created.

SQL> ALTER FLASHBACK ARCHIVE test_archive1 MODIFY RETENTION 1 MONTH;
Flashback archive altered.

为scott用户下的emp表启用闪回归档
赋予用户归档的权限
SQL> grant flashback archive on test_archive2 to scott;
Grant succeeded.

连接用户
SQL> conn scott/tiger
Connected.

为emp表启用闪回归档
SQL> ALTER TABLE scott.emp FLASHBACK ARCHIVE test_archive2;
Table altered.

3、删除闪回归档
SQL> conn / as sysdba
Connected.

SQL> DROP FLASHBACK ARCHIVE test_archive2;
Flashback archive dropped.

05-11 20:54