从Oracle 11g开始,又提供了一个全新的flashback方式,叫闪回数据归档,已经有所描述。与以前的绝大部分flashback不一样的是,flashback data archive不再依赖于undo来构造历史数据,而是依靠现有的表空间来存放历史数据。
flashback data archive并不是记录数据库的所有变化,而只是记录了指定表的数据变化,所以,flashback data archive是针对对象的保护,是flashback database的一个有力补充。
通过flashback data archive,可以查询指定对象的任何时间点(只要满足保护策略)的数据,而且不需要利用到undo,这个在有审计需要的环境,或者是安全性特别重要的高可用数据库中,是一个非常好的特性。缺点就是如果该表变化很频繁,对空间的要求可能很高。
下面,将做一个测试,来证明flashback data archive。首先创建一个数据归档区,每一个数据归档区都可以有一个唯一的名称,这个名称对应了一定的数据保留策略,如假定数据归档区一的数据可以保存1年,而数据归档区2的数据仅仅是保留2天,以后把表放到对应的数据归档区,则按照该归档区的策略来保留数据的历史。
一个系统中,可以有一个默认的数据归档区,可以有很多其它的数据归档区,这里的数据归档区其实也是一个逻辑的概念,表示从一个或者多个表空间中拿出一定的空间,来保留表的修改历史,方便表不利用undo就可以flashback到归档策略内的任何一个时间点上。
- SYS@11gR1>CREATE FLASHBACK ARCHIVE DEFAULT data_test1 TABLESPACE tbs_test1
- 2 QUOTA 100M RETENTION 1 YEAR;
- Flashback archive created.
-
- SYS@11gR1>CREATE FLASHBACK ARCHIVE data_test2 TABLESPACE tbs_test1 RETENTION 2 day;
- Flashback archive created.
一个归档区可以不仅仅对应一个表空间,可以采用如下的命令增加或者删除该归档区的表空间的个数,也就是增加或者是减少该归档区空间的一种方法。如,给数据归档区1增加一个表空间
- SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 ADD TABLESPACE tbs_test2 QUOTA 100M;
- Flashback archive altered.
或者删除这个表空间,注意的是,这个删除仅仅是表示从数据归档区删除,并不是删除该表空间。
- SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 REMOVE TABLESPACE tbs_test2;
- Flashback archive altered.
也可以直接修改现有的表空间,可以分配给数据归档区的空间,注意的是,这个配额空间可以大于表空间的大小。
- SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 MODIFY TABLESPACE tbs_test1 QUOTA 200M;
- Flashback archive altered.
也可以修改该归档区的保留策略,如为一个月,这里把默认归档区的保留策略修改为一个月。
- SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 MODIFY RETENTION 1 month;
- Flashback archive altered.
以上的一些工作做完,现在就可以在业务用户下,指定特定的表,对应到特定的数据归档区了。把表指定到对应的数据归档区,有2种方法,一是在创建的时候直接指定归档区,一种是对现有的表指定一个归档区。
注意,如果不指定归档区的名称,则指定到默认归档区,否则,就属于指定的数据归档区。以下创建了3个表,一个指定到默认归档区,一个指定到数据归档区data_test2,另外一个为了做对比,没有指定到任何数据归档区。
- SYS@11gR1>connect piner/piner
- Connected.
- Piner@11gR1>create table test1(a int) flashback archive;
- Table created.
-
- Piner@11gR1>create table test2(b int);
- Table created.
-
- Piner@11gR1>alter table test2 flashback archive data_test2;
- Table altered.
-
- Piner@11gR1>create table test3(c int);
- Table created.
现在,把时间打开,并往这两个表中插入一些数据,看看数据归档区怎么生效。
- 09:33:37 Piner@11gR1>select * from test1;
-
- A
- ----------
- 1
- 2
- 3
-
- 09:33:38 Piner@11gR1>select * from test2;
-
- B
- ----------
- 4
- 5
- 6
-
- 09:33:43 Piner@11gR1>select * from test3;
-
- C
- ----------
- 7
- 8
- 9
-
- 09:33:46 Piner@11gR1>select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') time from dual;
-
- TIME
- --------------------------------------
- 2007-09-04 09:33:52
可以看到,这些数据是在9:33分左右写进去的,最新数据保留策略应当是,表test1对应的是默认的数据归档区data_test1,数据保留策略是一个月,表test2对应的是数据归档区data_test2,数据保留策略是2天,而表test3没有数据保留策略。
然后,对这三个表再做一些操作,如删除现有记录,并插入一些新记录,最后,只要证明没有经过undo,我们查询时间点2007-09-04 09:33:52,能找回原来的数据即可证明数据归档区是真正有效的。
- 09:34:19 Piner@11gR1>delete from test1;
- 3 rows deleted.
-
- 09:34:23 Piner@11gR1>delete from test2;
- 3 rows deleted.
-
- 09:34:30 Piner@11gR1>delete from test3;
- 3 rows deleted.
-
- 09:34:35 Piner@11gR1>insert into test1 values(10);
- 1 row created.
-
- 09:34:47 Piner@11gR1>insert into test2 values(20);
- 1 row created.
-
- 09:34:53 Piner@11gR1>insert into test3 values(30);
- 1 row created.
-
- 09:34:58 Piner@11gR1>commit;
- Commit complete.
-
- 09:36:32 Piner@11gR1>select * from test1;
- A
- ----------
- 10
-
- 09:36:51 Piner@11gR1>select * from test2;
- B
- ----------
- 20
-
- 09:36:56 Piner@11gR1>select * from test3;
- C
- ----------
- 30
现在,先利用flashback 功能去查询数据,均可以获得正确的数据,但是,不能确认的是,这些数据的获得到底是经过undo获得的还是数据归档区获得的。
- 09:43:17 Piner@11gR1>select * from test1 as of timestamp
- 09:43:17 2 to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
- A
- ----------
- 1
- 2
- 3
-
- 09:43:17 Piner@11gR1>select * from test2 as of timestamp
- 09:43:24 2 to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
- B
- ----------
- 4
- 5
- 6
-
- 09:43:25 Piner@11gR1>select * from test3 as of timestamp
- 09:43:30 2 to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
- C
- ----------
- 7
- 8
- 9
如果我们把undo 表空间swith一下,看情况有什么变化。为了确保生效,我们先重起该db,等重起完成以后,完成如下操作:
切换到新的undo表空间,如果没有,需要新创建
- SYS@11gR1>ALTER SYSTEM SET undo_tablespace=TBS_UNDO2;
- System altered.
删除原来的undo表空间
- SYS@11gR1>drop tablespace UNDOTBS1;
- Tablespace dropped.
然后,再执行如下的查询:
- Piner@11gR1> select * from test3 as of timestamp
- 2 to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
- select * from test3 as of timestamp
- *
- ERROR at line 1:
- ORA-01555: snapshot too old: rollback segment number with name "" too small
-
-
- Piner@11gR1> select * from test1 as of timestamp
- 2 to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
- A
- ----------
- 1
- 2
- 3
-
- Piner@11gR1> select * from test2 as of timestamp
- 2 to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
- B
- ----------
- 4
- 5
- 6
可以看到,没有设置数据归档策略的表test3,查询的时候会报01555错误,但是,设置过数据归档策略的test1与test2,都能正常查询到数据,可以看到,数据归档是生效了。
这里是一个简单的实验,时间可能远远没有达到设置的策略期,但是,却可以证明数据不是经过undo查询而获得的。
最后,可以简单的说一下数据归档区的管理,如清除所有归档区的数据,如果数据归档空间如果不够,将会导致表DML出错,错误信息为ORA-55617。
- ALTER FLASHBACK ARCHIVE data_test1 PURGE ALL;
清除一天以前的数据
- ALTER FLASHBACK ARCHIVE data_test1
- PURGE BEFORE TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' DAY);
清除特定SCN之前的数据
- ALTER FLASHBACK ARCHIVE data_test1 PURGE BEFORE SCN 728969;
也可以把指定的表不再设置数据归档
- ALTER TABLE test1 NO FLASHBACK ARCHIVE;
或者是删除这个数据归档区
- DROP FLASHBACK ARCHIVE data_test2;
不过,如果放入了数据归档区的表,是不能执行如下操作的
·删除,重令名,或者修改列
·做分区或者子分区操作
·转换long到lob类型
·ALTER TABLE …… UPGRADE TABLE 操作
·drop、rename、trunacte表
如
- Piner@11gR1> drop table test1;
- drop table test1
- *
- ERROR at line 1:
- ORA-55610: Invalid DDL statement on history-tracked table
-
-
- Piner@11gR1> truncate table test1;
- truncate table test1
- *
- ERROR at line 1:
- ORA-55610: Invalid DDL statement on history-tracked table
-
-
- Piner@11gR1> alter table test1 add b int;
-
- Table altered.
-
- Piner@11gR1> alter table test1 drop column b;
- alter table test1 drop column b
- *
- ERROR at line 1:
- ORA-55610: Invalid DDL statement on history-tracked table
发表于 2007-09-04 12:27:05 目录:, , 所有|All Blogs 你可以, 或者从您的网站