Oracle Study之案例--数据恢复神器Flashback(4)

简介:

Oracle数据库10g提供了五个新的闪回功能:闪回版本查询,闪回事务查询,闪回删除,闪回表和闪回数据库。Oracle数据库11gR1提供了一个有趣的新的闪回功能:闪回数据存档,它允许一个Oracle数据库管理员维护一个记录,对指定时间范围内对所有表的的改变情况进行记录。

OCP 考试题:

验证:

15:44:05 SYS@ cuug>select flashback_archive_name,status from dba_flashback_archive;FLASHBACK_ARCHIVE_NA STATUS-------------------- -------FBA1     DEFAULTFBA2FBA3FBA415:44:09 SYS@ cuug>drop flashback archive fba1;Flashback archive dropped.16:13:22 SYS@ cuug>select flashback_archive_name,status from dba_flashback_archive;FLASHBACK_ARCHIVE_NA STATUS-------------------- -------FBA2FBA3FBA416:13:26 SYS@ cuug>alter table scott.dept flashback archive;alter table scott.dept flashback archive*ERROR at line 1:ORA-55608: Default Flashback Archive does not exist

FBDA工作原理:

闪回数据归档(FBDA)是一个新的后台进程,负责跟踪和归档开启了FBDA的表的历史数据,它通过异步处理自动收集和向指定的闪回数据归档写入原始数据。

当开启FBDA的表中任何数据发生变化时,FBDA首先询问存储在数据库缓冲区中的UNDO数据,如果数据仍然在那里,FBDA就会使用它,如果UNDO数据已经从数据库缓冲区中移除,FBDA就会尝试从UNDO表空间中的UNDO段中获取数据发生的变化。

当FBDA捕捉到变化数据时,它会整理开启FBDA的表中的行,然后将这些行写入FBDA中的历史表,这些表数据经过压缩,就和内部分区一样。

有趣的是,FBDA不包括捕获数据的原始索引,当在FBDA中可以对历史数据创建另一个索引。

自动保留策略:按照类似的保留需求,可以将FBDA对象中的历史表数据聚集在一起,Oracle 11g也提供了自动清理FBDA中数据的方法,一旦超出了指定的保留期限就会自动执行清理工作,多个表可以共享同一个数据保留和清理策略,因为FBDA是由一个或多个表空间构成的,所以可以创建多个FBDA,每个FBDA指定不同的保留期限,这样就可以创建多个FBDA满足不同需求的保留策略

配置闪回数据归档

准备一个Oracle 11g数据库使用FBDA功能是相当简单的,只需要经过几个简单的步骤即可:

(1)创建或指定一个或多个表空间用于FBDA保留历史数据

(2)随意指派一个FBDA作为数据库的默认FBDA

(3)指派一个用户账户作为FBDA管理员,授予它FLASHBACK ARCHIVE ADMINISTER系统权限

(4)授予FBDA权限给适合的用户账号

(5)授予FLASHBACK和SELECT权限给合适的FBDA表用户

(6)为FBDA用户授予DBMS_FLASHBACK存储过程EXECUTE权限

具体步骤:

-- 创建FBDA管理员用户账号

CREATE USER fbda_admin IDENTIFIED BY fbda_admin;GRANT FLASHBACK ARCHIVE ADMINISTER TO fbda_admin;

-- 授予其它用户合适的闪回权限

GRANT FLASHBACK ANY TABLE TO hr;GRANT EXECUTE ON DBMS_FLASHBACK TO hr;GRANT FLASHBACK ANY TABLE TO oe;GRANT EXECUTE ON DBMS_FLASHBACK TO oe;GRANT FLASHBACK ANY TABLE TO sh;GRANT EXECUTE ON DBMS_FLASHBACK TO sh;

-- 为闪回数据归档创建表空间

CREATE TABLESPACE fbdaDATAFILE '/u01/app/oracle/oradata/ORCL/tsp_fdba01.dbf'SIZE 24M;

-- 创建一个闪回数据归档保留5天有价值的历史

CREATE FLASHBACK ARCHIVE fbda_1TABLESPACE fbdaQUOTA 1MRETENTION 5 DAY;GRANT FLASHBACK ARCHIVE ON fbda_1 TO hr;GRANT FLASHBACK ARCHIVE ON fbda_1 TO oe;GRANT FLASHBACK ARCHIVE ON fbda_1 TO sh;

-- 创建一个闪回数据归档保留1整年有价值的历史

CREATE FLASHBACK ARCHIVE fbda_2TABLESPACE fbdaQUOTA 4MRETENTION 1 YEAR;GRANT FLASHBACK ARCHIVE ON fbda_2 TO hr;GRANT FLASHBACK ARCHIVE ON fbda_2 TO oe;GRANT FLASHBACK ARCHIVE ON fbda_2 TO sh;

-- 创建一个闪回数据归档保留7年有价值的历史

CREATE FLASHBACK ARCHIVE fbda_3TABLESPACE fbdaQUOTA 20MRETENTION 7 YEAR;GRANT FLASHBACK ARCHIVE ON fbda_3 TO hr;GRANT FLASHBACK ARCHIVE ON fbda_3 TO oe;GRANT FLASHBACK ARCHIVE ON fbda_3 TO sh;

-- 将闪回数据归档FBDA_2作为默认FBDA

ALTER FLASHBACK ARCHIVE fbda_2 SET DEFAULT;

-- 将FBDA_1改为默认的FBDA

ALTER FLASHBACK ARCHIVE fbda_1 SET DEFAULT;

-- 启用一个现有表使用默认的FBDA(fbda_1)

ALTER TABLE hr.applicants FLASHBACK ARCHIVE;

-- 启用表使用指定的FBDA

ALTER TABLE hr.departments FLASHBACK ARCHIVE fbda_1;ALTER TABLE hr.job_history FLASHBACK ARCHIVE fbda_2;ALTER TABLE oe.customers FLASHBACK ARCHIVE fbda_3;

-- 在指定表上禁用闪回数据归档

ALTER TABLE hr.departments NO FLASHBACK ARCHIVE;

删除闪回归档区:

17:04:39 SYS@ cuug>drop flashback archive fbda_1;Flashback archive dropped.17:04:39 SYS@ cuug>drop flashback archive fbda_2;Flashback archive dropped.17:04:48 SYS@ cuug>drop flashback archive fbda_3;Flashback archive dropped.17:04:51 SYS@ cuug>drop flashback archive fbda_4;Flashback archive dropped.

FBDA元数据:Oracle 11gR1提供了几个关于FBDA元数据的数据字典视图,包括哪个表空间支持可扩展的历史数据存储,以及FBDA中保留了哪个表:

使用闪回数据归档:审计和数据修复

至此,闪回数据归档已经建立起来,但有什么用途呢?下面就列举几个情景来说明它的用途:

审计历史事务

现在我们已经在HR.APPLICANTS表上建立起FBDA跟踪了,所有发生变化的数据将会自动保留下来,这样我们就可以向同等雇佣机会委员会(EEOC)证明我们在招聘人员时没有歧视,因为我们最近和美国联邦政府签订了这样一份协议,以后我就可以拿事实数据进行说明了。

数据粉碎

相信大部分对于保留历史数据在法律上的重要性都有深刻的理解,好的记账原则要求至少保留关键财务数据达7年之久,方便国家税务机关审计。Oracle 11g将会自动删除超出保留期限的数据,在数据粉碎期间,只针对历史数据,而不是FBDA自身。

修复丢失的或错误修改的数据

以我过去30年的IT经历来看,很多时候用户、程序开发人员甚至DBA可能不经意错误地修改了关键数据,甚至物理地删除了关键表中的行,更可怕的是,这些错误可能过了很久才被发现,那个时候可能最希望能够如魔法般地重建数据,这放在过去,只能不完全恢复数据,闪回数据当然也支持不完全恢复,但它的粒度是数据库和指定的SCN(但前提是在犯错前已经开启了闪回日志功能),闪回表仍然受限于当前UNDO表空间UNDO保留的数量。

下面给出一段代码显示如何使用闪回数据归档数据和闪回查询来找回丢失的数据的:

DELETE FROM hr.applicantsWHERE application_date <= TO_DATE('11-10-2008','dd-mm-yyyy');COMMIT;INSERT INTO hr.applicantsSELECT *FROM hr.applicantsVERSIONS BETWEEN TIMESTAMP TO_TIMESTAMP('2008-12-04 10:00','yyyy-mm-dd hh24:mi')AND MAXVALUEWHERE VERSIONS_OPERATION = 'D';COMMIT;

虽然闪回数据归档自身可以完成维护,但有时还是需要手动维护,如:维护闪回数据归档

扩大现有FBDA的大小(新的大小不能超过授予FBDA管理用户限额的最大表空间尺寸)。

改变FBDA上历史数据保留策略。

手动清洗FBDA内比指定日期时间还旧的数据。

删除现有FBDA(注意删除FBDA时并没有删除对应的表空间)。

请看下面的代码:

-- 清洗现有FBDA中超过1天的数据

ALTER FLASHBACK ARCHIVE fbda_1PURGE BEFORE TIMESTAMP(SYSTIMESTAMP - INTERVAL '1' DAY);

-- 修改现有FBDA的空间限额,减小到2M

ALTER FLASHBACK ARCHIVE fbda_1MODIFY TABLESPACE fbda QUOTA 2M;

-- 减少现有FBDA的保留期限为90天

ALTER FLASHBACK ARCHIVE fbda_3MODIFY RETENTION 90 DAY;

-- 给现有FBDA增加一个无空间限额的新表空间,这样就允许FBDA使用新增加表空间的所有可用空间

DROP TABLESPACE fbda_extd INCLUDING CONTENTS AND DATAFILES;CREATE TABLESPACE fbda_extdDATAFILE '/u01/app/oracle/oradata/ORCL/tsp_fdba_extd01.dbf'SIZE 16M;ALTER FLASHBACK ARCHIVE fbda_1ADD TABLESPACE fbda_extd;

-- 删除一个现有FBDA,注意对应的表空间仍然存在

DROP FLASHBACK ARCHIVE fbda_1;

FBDA空间管理:当一个FBDA用尽了所有可用的空间时,由这个FBDA支持的表如果发生修改操作时,其会话会接收到一个或两个错误消息(下面用fbda_1来解释这两个错误):

ORA-55617: Flashback Archive fbda_1 runs out of space and tracking on fda1 is suspended

这个错误消息指出了哪个FBDA空间几乎用完了,当FBDA达到90%或更高时就会报这个错误。

ORA-55623: Flashback Archive fbda_1 is blocking and tracking on all tables is suspended

这种情况下,FBDA已经完全用完了可用空间。

不管出现哪个错误,DBA都可以手动增加FBDA的限额,或直接增加FBDA所在表空间的大小,注意这些错误也会记录到Alert.log文件中。

闪回数据归档:限制和建议

你可能已经猜到这么强大的功能肯定会有限制条件的,不错,下面就列举出这些限制条件:

DDL限制

如果在开启FBDA的表上应用下面这些DDL命令,Oracle 11g将会产生一个异常:

(1)ALTER TABLE <表名>命令,如

删除一列

重命名列

修改列

执行PARTITION 或SUBPARTITION 操作

将列的数据类型从LONG转换为LOB

调用UPGRADE TABLE操作,不管是否指定了INCLUDING DATA选项

(2)DROP TABLE <表名>;

(3)RENAME TABLE <表明>;

(4)TRUNCATE TABLE <表名>;

最佳实践

最后,我还是列出在Oracle 11g中使用闪回数据归档特性时推荐的最佳实践:

(1)在查询以往数据之前执行一下COMMIT 或ROLLBACK 操作,这样可以确保数据库的一致性。

(2)闪回数据归档进程总是使用当前会话设置,包括NLS设置如NLS_LANGUAGE和NLS_CHARACTERSET,但实际中当历史数据被保留时,这些变量的设置可能并不匹配。

(3)Oracle推荐使用INTERVAL和TIMESTAMP变量转换函数来估算过去的时间,如指定SYSTIMESTAMP – INTERVAL‘20’DAYS 来获得启用FBDA特性的表过去的数据。

(4)为了更精确地查询FBDA中的数据,Oracle推荐使用SCN,记住TIMESTAMP_TO_SCN函数可以用来直接从TIMESTAMP值中获得一个相对准确的SCN值,但它的精确度也只能达到3秒左右。

案例分析:

1、建立存储flashback archive表空间14:07:33 SYS@ test1 >create tablespace farch14:08:21   2  datafile '/u01/app/oracle/oradata/test1/farch01.dbf' size 100m;Tablespace created.14:09:17 SYS@ test1 >select file_id,file_name,tablespace_name from dba_data_files;   FILE_ID FILE_NAME                                          TABLESPACE_NAME---------- -------------------------------------------------- ------------------------------         1 /u01/app/oracle/oradata/test1/system01.dbf         SYSTEM         6 /u01/app/oracle/oradata/test1/dict1.dbf            DICT1         9 /dsk1/oradata/test1/users02.dbf                    USERS         4 /u01/app/oracle/oradata/test1/users01.dbf          USERS         3 /u01/app/oracle/oradata/test1/test1.dbf            TEST1         2 /u01/app/oracle/oradata/test1/sysaux01.dbf         SYSAUX         ......        16 /u01/app/oracle/oradata/test1/farch01.dbf          FARCH         7 /u01/app/oracle/oradata/test1/undotbs2.dbf         UNDOTBS2        13 /u01/app/oracle/oradata/test1/tbs_16.dbf           TBS_1616 rows selected.2、建立flashback archive在farch表空间,retention为1个月14:09:26 SYS@ test1 >create flashback archive ftb1 tablespace farch retention 1 month;Flashback archive created.3、设置默认flashback archive(可以建立多个flashback archive)14:13:15 SYS@ test1 >alter flashback archive ftb1 set default;Flashback archive altered.14:14:20 SYS@ test1 >col FLASHBACK_ARCHIVE_NAME for a3014:14:31 SYS@ test1 >select flashback_archive_name,status from dba_flashback_archiveFLASHBACK_ARCHIVE_NAME         STATUS------------------------------ -------FTB1                           DEFAULT4、建立一个小的undo tablespace用于测试14:14:31 SYS@ test1 >show parameter undoNAME                                 TYPE                             VALUE------------------------------------ -------------------------------- ------------------------------undo_management                      string                           AUTOundo_retention                       integer                          900undo_tablespace                      string                           UNDOTBS214:17:18 SYS@ test1 >create undo tablespace sm_undo14:17:37   2  datafile '/u01/app/oracle/oradata/test1/sm_undo01.dbf' size 4m;Tablespace created.14:18:22 SYS@ test1 >alter system set undo_tablespace=sm_undo ;System altered.14:18:43 SYS@ test1 >show parameter undoNAME                                 TYPE                             VALUE------------------------------------ -------------------------------- ------------------------------undo_management                      string                           AUTOundo_retention                       integer                          900undo_tablespace                      string                           SM_UNDO5、授权用户可以使用flashback archive14:29:25 SYS@ test1 >grant flashback archive on ftb1 to scott;Grant succeeded.6、设置table启用flashback archive14:29:29 SCOTT@ test1 >alter table emp1 flashback archive ;Table altered.7、建立测试环境(查询闪回归档可以基于scn或timestamp)14:30:08 SYS@ test1 >select current_scn from v$database;CURRENT_SCN-----------   1201538114:32:15 SCOTT@ test1 > select count(*) from emp1  COUNT(*)----------     13001DML误操作:          14:33:18 SCOTT@ test1 >delete from emp1 where rownum <3001;3000 rows deleted.14:33:23 SCOTT@ test1 >commit;Commit complete.14:33:33 SCOTT@ test1 >select count(*) from emp1;  COUNT(*)----------     10001循环脚本,覆盖undo block:     14:35:25 SCOTT@ test1 >begin14:35:27   2  for i in  1..1000 loop14:35:34   3  insert into emp2 select * from emp;14:35:38   4  commit;14:35:41   5  end loop;14:35:44   6  end;14:35:45   7  /PL/SQL procedure successfully completed.14:35:47 SCOTT@ test1 >set autotrace on14:36:01 SCOTT@ test1 >select count(*) from emp1 as of scn 12015381;  COUNT(*)----------     13001Elapsed: 00:00:00.13Execution Plan----------------------------------------------------------Plan hash value: 3926065282-----------------------------------------------------------------------------------------------------------------| Id  | Operation                  | Name               | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |-----------------------------------------------------------------------------------------------------------------|   0 | SELECT STATEMENT           |                    |     1 |       |    91   (2)| 00:00:02 |       |       ||   1 |  SORT AGGREGATE            |                    |     1 |       |            |          |       |       ||   2 |   VIEW                     |                    |   340 |       |    91   (2)| 00:00:02 |       |       ||   3 |    UNION-ALL               |                    |       |       |            |          |       |       ||*  4 |     FILTER                 |                    |       |       |            |          |       |       ||   5 |      PARTITION RANGE SINGLE|                    |     1 |    26 |     6   (0)| 00:00:01 |     1 |     1 ||*  6 |       TABLE ACCESS FULL    | SYS_FBA_HIST_18440 |     1 |    26 |     6   (0)| 00:00:01 |     1 |     1 ||*  7 |     FILTER                 |                    |       |       |            |          |       |       ||*  8 |      HASH JOIN OUTER       |                    |   339 |   675K|    91   (2)| 00:00:02 |       |       ||*  9 |       TABLE ACCESS FULL    | EMP1               |   339 |  4068 |    84   (0)| 00:00:02 |       |       ||* 10 |       TABLE ACCESS FULL    | SYS_FBA_TCRV_18440 |     1 |  2028 |     6   (0)| 00:00:01 |       |       |-----------------------------------------------------------------------------------------------------------------Predicate Information (identified by operation id):---------------------------------------------------   4 - filter(NULL IS NOT NULL)   6 - filter("ENDSCN">12015381 AND "ENDSCN"<=12015350 AND ("STARTSCN" IS NULL OR "STARTSCN"<=12015381))   7 - filter("STARTSCN"<=12015381 OR "STARTSCN" IS NULL)   8 - access("T".ROWID=CHARTOROWID("RID"(+)))   9 - filter("T"."VERSIONS_STARTSCN" IS NULL)  10 - filter(("ENDSCN"(+) IS NULL OR "ENDSCN"(+)>12015350) AND ("STARTSCN"(+) IS NULL OR              "STARTSCN"(+)<12015350))Note-----   - dynamic sampling used for this statement (level=2)Statistics----------------------------------------------------------         26  recursive calls          0  db block gets       9140  consistent gets          0  physical reads          0  redo size        424  bytes sent via SQL*Net to client        415  bytes received via SQL*Net from client          2  SQL*Net roundtrips to/from client          3  sorts (memory)          0  sorts (disk)          1  rows processed通过查询的执行计划可以看到,数据是从SYS_FBA_TCRV_18440(闪回区)读出,可以证明此历史数据不是从undo block而是flashback archive读出。          8、和flashback archive相关的视图          14:36:21 SCOTT@ test1 >desc SYS_FBA_TCRV_18440 Name                                                              Null?    Type ----------------------------------------------------------------- -------- -------------------------------------------- RID                                                                        VARCHAR2(4000) STARTSCN                                                                   NUMBER ENDSCN                                                                     NUMBER XID                                                                        RAW(8) OP                                                                         VARCHAR2(1)14:39:51 SCOTT@ test1 >select count(*) from SYS_FBA_TCRV_18440;  COUNT(*)----------      3000      14:40:18 SCOTT@ test1 >select * from tab;TNAME                          TABTYPE  CLUSTERID------------------------------ ------- ----------BONUS                          TABLEDEPT                           TABLEEMP                            TABLEEMP1                           TABLEEMP2                           TABLESALGRADE                       TABLESYS_FBA_DDL_COLMAP_18440       TABLESYS_FBA_HIST_18440             TABLESYS_FBA_TCRV_18440             TABLE9 rows selected.14:41:02 SCOTT@ test1 >select table_name,tablespace_name from user_tables where table_name like '%FBA%';TABLE_NAME                     TABLESPACE_NAME------------------------------ ------------------------------SYS_FBA_DDL_COLMAP_18440       FARCHSYS_FBA_TCRV_18440             FARCHSYS_FBA_HIST_1844014:41:47 SCOTT@ test1 >col object_name for a3014:42:02 SCOTT@ test1 >select object_name,object_type from user_objects where object_name like '%FBA%'OBJECT_NAME                    OBJECT_TYPE------------------------------ -------------------SYS_FBA_DDL_COLMAP_18440       TABLESYS_FBA_HIST_18440             TABLE PARTITIONSYS_FBA_HIST_18440             TABLESYS_FBA_TCRV_18440             TABLESYS_FBA_TCRV_IDX_18440         INDEX14:42:36 SCOTT@ test1 >col table_name for a1014:42:46 SCOTT@ test1 >col owner_name for a1014:42:52 SCOTT@ test1 >col FLASHBACK_ARCHIVE_NAME for a2014:43:02 SCOTT@ test1 >col ARCHIVE_TABLE_NAME for a2014:43:12 SCOTT@ test1 >select * from user_flashback_archive_tablesTABLE_NAME OWNER_NAME FLASHBACK_ARCHIVE_NA ARCHIVE_TABLE_NAME   STATUS---------- ---------- -------------------- -------------------- --------EMP1       SCOTT      FTB1                 SYS_FBA_HIST_18440   ENABLED14:43:49 SCOTT@ test1 >col table_name for a3014:44:04 SCOTT@ test1 >select table_name from dict where table_name like '%FLASHBACK_ARCHIVE%'TABLE_NAME------------------------------DBA_FLASHBACK_ARCHIVEUSER_FLASHBACK_ARCHIVEDBA_FLASHBACK_ARCHIVE_TSDBA_FLASHBACK_ARCHIVE_TABLESUSER_FLASHBACK_ARCHIVE_TABLES14:44:05 SCOTT@ test1 >desc USER_FLASHBACK_ARCHIVE Name                                                              Null?    Type ----------------------------------------------------------------- -------- -------------------------------------------- OWNER_NAME                                                                 VARCHAR2(30) FLASHBACK_ARCHIVE_NAME                                            NOT NULL VARCHAR2(255) FLASHBACK_ARCHIVE#                                                NOT NULL NUMBER RETENTION_IN_DAYS                                                 NOT NULL NUMBER CREATE_TIME                                                                TIMESTAMP(9) LAST_PURGE_TIME                                                            TIMESTAMP(9) STATUS                                                                     VARCHAR2(7) 14:44:45 SCOTT@ test1 >select OWNER_NAME,FLASHBACK_ARCHIVE_NAME,FLASHBACK_ARCHIVE#,RETENTION_IN_DAYS from USER_FLASHBACK_ARCHIVE;OWNER_NAME FLASHBACK_ARCHIVE_NA FLASHBACK_ARCHIVE# RETENTION_IN_DAYS---------- -------------------- ------------------ -----------------SYS        FTB1                                  1                30Elapsed: 00:00:00.10案例2:14:45:22 SCOTT@ test1 >alter table emp flashback archive;Table altered.Elapsed: 00:00:00.1314:58:08 SCOTT@ test1 >select count(*) from emp;  COUNT(*)----------        13Elapsed: 00:00:00.0114:58:22 SCOTT@ test1 >delete from emp where empno=7788;1 row deleted.Elapsed: 00:00:00.0814:58:31 SCOTT@ test1 >commit;Commit complete.Elapsed: 00:00:00.0314:58:34 SCOTT@ test1 >select count(*) from emp;  COUNT(*)----------        12Elapsed: 00:00:00.0014:58:38 SCOTT@ test1 >set autotrace on14:58:55 SCOTT@ test1 >select count(*) from emp as of timestamp to_timestamp('2015-01-15 14:55:00','yyyy-mm-dd hh24:mi:ss');  COUNT(*)----------        13Elapsed: 00:00:00.01Execution Plan----------------------------------------------------------Plan hash value: 2083865914-------------------------------------------------------------------| Id  | Operation          | Name | Rows  | Cost (%CPU)| Time     |-------------------------------------------------------------------|   0 | SELECT STATEMENT   |      |     1 |     6   (0)| 00:00:01 ||   1 |  SORT AGGREGATE    |      |     1 |            |          ||   2 |   TABLE ACCESS FULL| EMP  |   409 |     6   (0)| 00:00:01 |-------------------------------------------------------------------Statistics----------------------------------------------------------         23  recursive calls          0  db block gets         10  consistent gets          0  physical reads          0  redo size        422  bytes sent via SQL*Net to client        415  bytes received via SQL*Net from client          2  SQL*Net roundtrips to/from client          0  sorts (memory)          0  sorts (disk)          1  rows processed 从查询的执行计划可以看出,此次历史数据的查询是从undo block读出!                   为了实现Flashback Archive的功能,Oracle新引入了一个实例进程为FBDA(Flashback Archived Process)。该进程启动时随着数据库同时启动。FBDA的作用如下:     FBDA首先从buffer cache中的undo表空间数据中查找过去数据表时间点数据。这点是与flashback query的特性相似;     如果要查找的数据在undo tablespace中,但是该块没有在buffer cache中。FBDA会从undo segment中获取到数据块,复制在buffer cache中;     当进行flashback archive操作的数据表发生修改的时候,FBDA会去将需要保存的数据存放在对应的适当内部数据表中;

小结:

Oracle 11g新的闪回数据归档特性让DBA有能力将历史数据保留非常长的时间,只要保存历史数据的表空间的容量足够大,因为闪回查询、闪回版本查询和闪回事务查询也受到支持,因此Oracle DBA也可以利用FBDA特性来纠正对数据的错误修改。FBDA安装容易,监控简单,自我维护,相信它会成为Oracle DBA受欢迎的工具。