Chinaunix首页 | 论坛 | 博客
  • 博客访问: 545310
  • 博文数量: 302
  • 博客积分: 10010
  • 博客等级: 上将
  • 技术积分: 4765
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-15 23:10
文章分类

全部博文(302)

文章存档

2011年(1)

2008年(301)

我的朋友

分类: 服务器与存储

2008-07-18 22:13:35

从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到归档策略内的任何一个时间点上。

  1. SYS@11gR1>CREATE FLASHBACK ARCHIVE DEFAULT data_test1 TABLESPACE tbs_test1
  2.   2    QUOTA 100M RETENTION 1 YEAR;
  3. Flashback archive created.
  4. SYS@11gR1>CREATE FLASHBACK ARCHIVE data_test2 TABLESPACE tbs_test1 RETENTION 2 day;
  5. Flashback archive created.

一个归档区可以不仅仅对应一个表空间,可以采用如下的命令增加或者删除该归档区的表空间的个数,也就是增加或者是减少该归档区空间的一种方法。如,给数据归档区1增加一个表空间

  1. SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 ADD TABLESPACE tbs_test2 QUOTA 100M;
  2. Flashback archive altered.

或者删除这个表空间,注意的是,这个删除仅仅是表示从数据归档区删除,并不是删除该表空间。

  1. SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 REMOVE TABLESPACE tbs_test2;
  2. Flashback archive altered.

也可以直接修改现有的表空间,可以分配给数据归档区的空间,注意的是,这个配额空间可以大于表空间的大小。

  1. SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 MODIFY TABLESPACE tbs_test1 QUOTA 200M;
  2. Flashback archive altered.

也可以修改该归档区的保留策略,如为一个月,这里把默认归档区的保留策略修改为一个月。

  1. SYS@11gR1>ALTER FLASHBACK ARCHIVE data_test1 MODIFY RETENTION 1 month;
  2. Flashback archive altered.

以上的一些工作做完,现在就可以在业务用户下,指定特定的表,对应到特定的数据归档区了。把表指定到对应的数据归档区,有2种方法,一是在创建的时候直接指定归档区,一种是对现有的表指定一个归档区。

注意,如果不指定归档区的名称,则指定到默认归档区,否则,就属于指定的数据归档区。以下创建了3个表,一个指定到默认归档区,一个指定到数据归档区data_test2,另外一个为了做对比,没有指定到任何数据归档区。

  1. SYS@11gR1>connect piner/piner
  2. Connected.
  3. Piner@11gR1>create table test1(a int) flashback archive;
  4. Table created.
  5. Piner@11gR1>create table test2(b int);
  6. Table created.
  7. Piner@11gR1>alter table test2 flashback archive data_test2;
  8. Table altered.
  9. Piner@11gR1>create table test3(c int);
  10. Table created.

现在,把时间打开,并往这两个表中插入一些数据,看看数据归档区怎么生效。

  1. 09:33:37 Piner@11gR1>select * from test1;
  2.          A
  3. ----------
  4.          1
  5.          2
  6.          3
  7. 09:33:38 Piner@11gR1>select * from test2;
  8.          B
  9. ----------
  10.          4
  11.          5
  12.          6
  13. 09:33:43 Piner@11gR1>select * from test3;
  14.          C
  15. ----------
  16.          7
  17.          8
  18.          9
  19. 09:33:46 Piner@11gR1>select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') time from dual;
  20. TIME
  21. --------------------------------------
  22. 2007-09-04 09:33:52

可以看到,这些数据是在9:33分左右写进去的,最新数据保留策略应当是,表test1对应的是默认的数据归档区data_test1,数据保留策略是一个月,表test2对应的是数据归档区data_test2,数据保留策略是2天,而表test3没有数据保留策略。

然后,对这三个表再做一些操作,如删除现有记录,并插入一些新记录,最后,只要证明没有经过undo,我们查询时间点2007-09-04 09:33:52,能找回原来的数据即可证明数据归档区是真正有效的。

  1. 09:34:19 Piner@11gR1>delete from test1;
  2. 3 rows deleted.
  3. 09:34:23 Piner@11gR1>delete from test2; 
  4. 3 rows deleted.
  5. 09:34:30 Piner@11gR1>delete from test3;
  6. 3 rows deleted.
  7. 09:34:35 Piner@11gR1>insert into test1 values(10);
  8. 1 row created.
  9. 09:34:47 Piner@11gR1>insert into test2 values(20);
  10. 1 row created.
  11. 09:34:53 Piner@11gR1>insert into test3 values(30);
  12. 1 row created.
  13. 09:34:58 Piner@11gR1>commit;
  14. Commit complete.
  15. 09:36:32 Piner@11gR1>select * from test1;
  16.          A
  17. ----------
  18.         10
  19. 09:36:51 Piner@11gR1>select * from test2;
  20.          B
  21. ----------
  22.         20
  23. 09:36:56 Piner@11gR1>select * from test3;
  24.          C
  25. ----------
  26.         30

现在,先利用flashback 功能去查询数据,均可以获得正确的数据,但是,不能确认的是,这些数据的获得到底是经过undo获得的还是数据归档区获得的。

  1. 09:43:17 Piner@11gR1>select * from test1 as of timestamp
  2. 09:43:17   2  to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
  3.          A
  4. ----------
  5.          1
  6.          2
  7.          3
  8. 09:43:17 Piner@11gR1>select * from test2 as of timestamp
  9. 09:43:24   2  to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
  10.          B
  11. ----------
  12.          4
  13.          5
  14.          6
  15. 09:43:25 Piner@11gR1>select * from test3 as of timestamp
  16. 09:43:30   2  to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
  17.          C
  18. ----------
  19.          7
  20.          8
  21.          9

如果我们把undo 表空间swith一下,看情况有什么变化。为了确保生效,我们先重起该db,等重起完成以后,完成如下操作:

切换到新的undo表空间,如果没有,需要新创建

  1. SYS@11gR1>ALTER SYSTEM SET undo_tablespace=TBS_UNDO2;
  2. System altered.

删除原来的undo表空间

  1. SYS@11gR1>drop tablespace UNDOTBS1;
  2. Tablespace dropped.

然后,再执行如下的查询:

  1. Piner@11gR1> select * from test3 as of timestamp
  2.   2  to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
  3. select * from test3 as of timestamp
  4.               *
  5. ERROR at line 1:
  6. ORA-01555: snapshot too old: rollback segment number  with name "" too small   
  7.       
  8.       
  9. Piner@11gR1> select * from test1 as of timestamp
  10.   2  to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
  11.          A
  12. ----------
  13.          1
  14.          2
  15.          3
  16. Piner@11gR1> select * from test2 as of timestamp
  17.   2  to_timestamp('2007-09-04 09:33:52', 'yyyy-mm-dd hh24:mi:ss');
  18.          B
  19. ----------
  20.          4
  21.          5
  22.          6

可以看到,没有设置数据归档策略的表test3,查询的时候会报01555错误,但是,设置过数据归档策略的test1与test2,都能正常查询到数据,可以看到,数据归档是生效了。

这里是一个简单的实验,时间可能远远没有达到设置的策略期,但是,却可以证明数据不是经过undo查询而获得的。

最后,可以简单的说一下数据归档区的管理,如清除所有归档区的数据,如果数据归档空间如果不够,将会导致表DML出错,错误信息为ORA-55617。

  1. ALTER FLASHBACK ARCHIVE data_test1 PURGE ALL;

清除一天以前的数据

  1. ALTER FLASHBACK ARCHIVE data_test1
  2.   PURGE BEFORE TIMESTAMP (SYSTIMESTAMP - INTERVAL '1' DAY);

清除特定SCN之前的数据

  1. ALTER FLASHBACK ARCHIVE data_test1 PURGE BEFORE SCN 728969;

也可以把指定的表不再设置数据归档

  1. ALTER TABLE test1 NO FLASHBACK ARCHIVE;

或者是删除这个数据归档区

  1. DROP FLASHBACK ARCHIVE data_test2;

不过,如果放入了数据归档区的表,是不能执行如下操作的

·删除,重令名,或者修改列

·做分区或者子分区操作

·转换long到lob类型

·ALTER TABLE …… UPGRADE TABLE 操作

·drop、rename、trunacte表

  1. Piner@11gR1> drop table test1;
  2. drop table test1
  3.            *
  4. ERROR at line 1:
  5. ORA-55610: Invalid DDL statement on history-tracked table
  6. Piner@11gR1> truncate table test1;
  7. truncate table test1
  8.                *
  9. ERROR at line 1:
  10. ORA-55610: Invalid DDL statement on history-tracked table
  11. Piner@11gR1> alter table test1 add b int;
  12. Table altered.
  13. Piner@11gR1> alter table test1 drop column b;
  14. alter table test1 drop column b
  15. *
  16. ERROR at line 1:
  17. ORA-55610: Invalid DDL statement on history-tracked table
阅读(654) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~