闪回事务查询

  • 原理:基于undo
  • 闪回事务查询可以看作一个在事务级别查询数据库改变的一个诊断工具
  • FLASHBACK_TRANSACTION_QUERY
    • retrieve transaction information for all tables involved in a transaction.
    • provides the SQL statements that you can use to undo the changes made by a particular transaction
  • 需要打开最小附加日志:
    ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;


例:

  1. \**查询所有事务信息*\
  2. SQL> SELECT operation, undo_sql, table_name FROM flashback_transaction_query;
  1. \**返回指定事务的信息*\
  2. SQL> SELECT operation, undo_sql, table_name FROM flashback_transaction_query WHERE xid = HEXTORAW('8C0024003A000000') ORDER BY undo_change#;
  3. SELECT xid,
  4. operation,
  5. start_scn,
  6. commit_scn,
  7. logon_user,
  8. undo_sql
  9. FROM flashback_transaction_query
  10. WHERE xid = HEXTORAW('000400070000004F');
  1. \**返回指定时间间隔的事务信息*\
  2. SQL> SELECT operation, undo_sql, table_name FROM flashback_transaction_query WHERE start_timestamp >= TO_TIMESTAMP ('2003-10-21 11:00:00','YYYY-MM-DD HH:MI:SS')
  3. AND commit_timestamp <= TO_TIMESTAMP('2003-10-21 11:30:00','YYYY-MM-DD HH:MI:SS');
  4. SELECT xid,
  5. logon_user
  6. FROM flashback_transaction_query
  7. WHERE xid IN ( SELECT versions_xid
  8. FROM personnel
  9. VERSIONS BETWEEN
  10. TIMESTAMP TO_TIMESTAMP('2007-03-21 19:30:00', 'YYYY-MM-DD HH24:MI:SS')
  11. AND TO_TIMESTAMP('2007-03-22 04:30:00', 'YYYY-MM-DD HH24:MI:SS') );

实操场景

1.打开附加日志,并授权

  1. alter database add supplemental log data;
  2. grant SELECT ANY TRANSACTION to hr;

2.产生事务

  1. insert into hr.departments
  2. (department_id,department_name,manager_id,location_id)
  3. values (999,'SETI',100,1700);
  4. update hr.employees set department_id=999
  5. where employee_id=200;
  6. commit;

3.获取事务号并且通过事务号得到undo sql

  1. select
  2. versions_xid,versions_startscn,department_id,department_name
  3. from hr.departments
  4. versions between timestamp minvalue and maxvalue
  5. where department_id=999
  6. order by 2 nulls first;
  7. set line 200
  8. col undo_sql for a90
  9. SELECT operation, undo_sql, table_name FROM flashback_transaction_query WHERE xid = HEXTORAW('10000A0039030000') ORDER BY undo_change#;
  10. OPERATION UNDO_SQL TABLE_NAME
  11. ---------- ------------------------------------------------------------------------------------------ ------------------------------
  12. UPDATE update "HR"."EMPLOYEES" set "DEPARTMENT_ID" = '10' where ROWID = 'AAAWXeAAEAAAAZtAAC'; EMPLOYEES
  13. INSERT delete from "HR"."DEPARTMENTS" where ROWID = 'AAAWXZAAEAAAAZMAAb'; DEPARTMENTS
  14. BEGIN
  15. ----如果需要回退,执行上面的undo_sql即可

使用下面的pl/sql语句回退事务

  1. begin
  2. for rec in
  3. (select undo_sql
  4. from flashback_transaction_query
  5. where xid='10000A0039030000')
  6. loop
  7. if rec.undo_sql is not null then
  8. execute immediate substr(rec.undo_sql,1,length(rec.undo_sql)-1);
  9. end if;
  10. end loop;
  11. commit;
  12. end;
  13. /




posted @ 2015-07-13 12:57  hao_xiaoyu  阅读(875)  评论(0编辑  收藏  举报