关于flashback versions query 和flashback transaction query 特性 - kongkongye的专栏 - CSDNBlog

来源:互联网 发布:linux中vim编辑器 编辑:程序博客网 时间:2024/05/17 23:08
导读:

  前面提到了oracle 自9i以来的flashback query 特性,借助该特性,可以看到某个过去某个时间点的某张表的数据,这为我们修正dml 误操作等提供了很大的方便。

  但是对于该特性来说,如果只是想回退某个时间点以来的部分数据,那么纯粹依靠前后的数据对比来判断,就会显的非常吃力,或许根本就是无法办到的。比如,你某时刻同时跑起了多个job作业,

  如果一个job有问题,而其他的job正常完成的,此时,如果你仅仅是想回复错误job处理过的数据,而要保留正常job的处理结果,但是或许你无法判断后面变化的数据哪些是正常job的,哪些是错误job的,因此,很难进行部分数据的修复工作。

  10g提供了flashback versions query 和 flashback transaction query 特性,它强化了9i 的flashback query 特性,正是解决上面类似问题的利器。

  

  1.flashback versions query

  flashback versions query 能够得到某个时间段内,某些数据行的所有不同版本。这里的版本以事务为单位,事务中的每次数据变化就是一个版本。

  举例说明,下面的会话2次update id=1 时的 name 值,因此分别提交过2次,因此是2个不同的事务,在flashback versions query 的结果中,关于

  id=1 ,我们看到了3个不同的版本,一个是原来的值,一个是第一次修改的值,一个是第二次修改的值;通过flashback versions query 中的versions_startscn,versions_starttime

  versions_endscn, versions_endtime,versions_xid, versions_operation 等伪列,我们也获得了相关版本的开始scn,结束scn,开始时间和结束时间,以及做dml操作的具体transaction id (xid),以及操作类型等;

  同时,我们也看到对于id=1的数据行,三个版本的VERSIONS_ENDSCN,VERSIONS_ENDtime 和 VERSIONS_startscn,VERSIONS_starttime 是承上启下的,一个版本的结束,也就是下一个版本的开始。

  15:37:22 SQL> select * from test;

  ID NAME

  ---------- --------------------

  1 kkk

  2 fff

  4 kkk

  Executed in 0.031 seconds

  15:37:34 SQL> update test set name='TEST' where id=1;

  1 row updated

  Executed in 0.015 seconds

  15:37:54 SQL> commit;

  Commit complete

  Executed in 0 seconds

  15:37:56 SQL> update test set name='TEST_new' where id=1;

  1 row updated

  Executed in 0.015 seconds

  15:38:04 SQL> commit;

  Commit complete

  Executed in 0 seconds

  15:38:06 SQL>

  15:39:12 SQL> SELECT versions_startscn, versions_starttime,

  2 versions_endscn, versions_endtime,

  3 versions_xid, versions_operation,

  4 id,name

  5 FROM test

  6 VERSIONS BETWEEN TIMESTAMP

  7 TO_TIMESTAMP('2008-04-27 15:37:30', 'YYYY-MM-DD HH24:MI:SS')

  8 AND TO_TIMESTAMP('2008-04-27 15:38:30', 'YYYY-MM-DD HH24:MI:SS')

  9 ;

  VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID VERSIONS_OPERATION ID NAME

  ----------------- -------------------------------------------------------------------------------- --------------- -------------------------------------------------------------------------------- ---------------- ------------------ ---------- --------------------

  819393 27-4月 -08 03.38.06 下午 040015006F010000 U 1 TEST_new

  819387 27-4月 -08 03.37.54 下午 819393 27-4月 -08 03.38.06 下午 0500150088010000 U 1 TEST

  819387 27-4月 -08 03.37.54 下午 1 kkk

  2 fff

  4 kkk

  Executed in 0.031 seconds

  15:39:13 SQL> select * from test;

  ID NAME

  ---------- --------------------

  1 TEST_new

  2 fff

  4 kkk

  Executed in 0 seconds

  15:43:52 SQL>

  2. flashback transaction query

  flashback transaction query 其实就是查询历史的事务信息,通过查询,我们可以得到过去某个事务操作信息,包括改变的数据行rowid,事务开始和结束时间,事务对应的loggon user,以及用来撤销某个数据行改变的undo sql等。

  flashback transaction query 其实就是查询 FLASHBACK_TRANSACTION_QUERY 视图。

  比如,通过上面 versions query 得到的xid,我们可以得到这些xid 对应的信息。

  15:43:52 SQL> SELECT xid, operation, start_scn,commit_scn, logon_user, undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('&1');

  XID OPERATION START_SCN COMMIT_SCN LOGON_USER UNDO_SQL

  ---------------- -------------------------------- ---------- ---------- ------------------------------ --------------------------------------------------------------------------------

  040015006F010000 UPDATE 819387 819393 TEST1 update "TEST1"."TEST" set "NAME" = 'TEST' where ROWID = 'AAAM1/AAEAAAAGsAAA';

  040015006F010000 BEGIN 819387 819393 TEST1

  Executed in 0.297 seconds

  15:57:34 SQL> SELECT xid, operation, start_scn,commit_scn, logon_user, undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('&1');

  XID OPERATION START_SCN COMMIT_SCN LOGON_USER UNDO_SQL

  ---------------- -------------------------------- ---------- ---------- ------------------------------ --------------------------------------------------------------------------------

  0500150088010000 UPDATE 819184 819387 TEST1 update "TEST1"."TEST" set "NAME" = 'kkk' where ROWID = 'AAAM1/AAEAAAAGsAAA';

  0500150088010000 BEGIN 819184 819387 TEST1

  Executed in 0.032 seconds

  15:58:07 SQL>

  3.一个例子

  flashback versions query 和flashback transaction query 一般都是结合起来用的,通过前者得到某个时间段的某些数据的多个版本的xid,然后通过后者得到具体的xid的操作信息及undo_sql,最后根据需要做适当的数据修复操作。

  SQL> create table test (id number ,name varchar2(20));

  Table created

  SQL> set time on

  14:55:14 SQL> set timing on

  14:55:18 SQL> insert into test values ( 1,'kkk');

  1 row inserted

  Executed in 0.016 seconds

  14:55:27 SQL> insert into test values ( 2,'fff');

  1 row inserted

  Executed in 0.016 seconds

  14:55:34 SQL> commit;

  Commit complete

  Executed in 0 seconds

  14:55:39 SQL>

  此时打开第二个会话窗口,执行如下:

  SQL> insert into test1.test values ( 4,'kkk');

  1 row inserted

  SQL> commit;

  Commit complete

  SQL>

  --再回到第一个窗口,进行 flashback versions query

  15:00:20 SQL> SELECT versions_startscn, versions_starttime,

  2 versions_endscn, versions_endtime,

  3 versions_xid, versions_operation,

  4 id,name

  5 FROM test

  6 VERSIONS BETWEEN TIMESTAMP

  7 TO_TIMESTAMP('2008-04-27 14:55:20', 'YYYY-MM-DD HH24:MI:SS')

  8 AND TO_TIMESTAMP('2008-04-27 14:57:00', 'YYYY-MM-DD HH24:MI:SS')

  9 ;

  VERSIONS_STARTSCN VERSIONS_STARTTIME VERSIONS_ENDSCN VERSIONS_ENDTIME VERSIONS_XID VERSIONS_OPERATION ID NAME

  ----------------- -------------------------------------------------------------------------------- --------------- -------------------------------------------------------------------------------- ---------------- ------------------ ---------- --------------------

  817371 27-4月 -08 02.55.39 下午 0900070081010000 I 2 fff

  817371 27-4月 -08 02.55.39 下午 0900070081010000 I 1 kkk

  817386 27-4月 -08 02.56.03 下午 0700280072010000 I 4 kkk

  Executed in 0.016 seconds

  15:00:21 SQL>

  -- flashback transaction query

  15:00:21 SQL> SELECT xid, operation, start_scn,commit_scn, logon_user, undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('&1');

  XID OPERATION START_SCN COMMIT_SCN LOGON_USER UNDO_SQL

  ---------------- -------------------------------- ---------- ---------- ------------------------------ --------------------------------------------------------------------------------

  0900070081010000 INSERT 817359 817371 TEST1 delete from "TEST1"."TEST" where ROWID = 'AAAM1/AAEAAAAGsAAB';

  0900070081010000 INSERT 817359 817371 TEST1 delete from "TEST1"."TEST" where ROWID = 'AAAM1/AAEAAAAGsAAA';

  0900070081010000 BEGIN 817359 817371 TEST1

  Executed in 0.593 seconds

  15:03:54 SQL>

  15:11:27 SQL>

  15:11:27 SQL>

  15:11:27 SQL> SELECT xid, operation, start_scn,commit_scn, logon_user, undo_sql FROM flashback_transaction_query WHERE xid = HEXTORAW('&1');

  XID OPERATION START_SCN COMMIT_SCN LOGON_USER UNDO_SQL

  ---------------- -------------------------------- ---------- ---------- ------------------------------ --------------------------------------------------------------------------------

  0700280072010000 INSERT 0 817386 TEST2 delete from "TEST1"."TEST" where ROWID = 'AAAM1/AAEAAAAGwAAA';

  0700280072010000 BEGIN 0 817386 TEST2

  Executed in 0.031 seconds

  15:11:47 SQL>

  4.undo_rentention

  和9i flashback query 一样,flashback versions query和flashback transaction query 也都是依赖于undo tablespace,依赖于undo_retention 的。换句话说,对于已经不存在于undo tablespace 的数据版本信息,

  你当然是无法通过 这些特性把它查出来的。因此设置好undo tablespace 的大小,设置好undo_rentention 的大小就尤为重要(10g 虽然有自动tuning undo_retention 的功能,不过考量并设置合适的undo_retention 最小值也是很有必要的)



本文转自

http://blog.csdn.net/kongkongye/archive/2008/04/27/2335254.aspx
原创粉丝点击