闪回事务查询
- 原理:基于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;
例:
\**查询所有事务信息*\
SQL> SELECT operation, undo_sql, table_name FROM flashback_transaction_query;
\**返回指定事务的信息*\
SQL> SELECT operation, undo_sql, table_name FROM flashback_transaction_query WHERE xid = HEXTORAW('8C0024003A000000') ORDER BY undo_change#;
SELECT xid,
operation,
start_scn,
commit_scn,
logon_user,
undo_sql
FROM flashback_transaction_query
WHERE xid = HEXTORAW('000400070000004F');
\**返回指定时间间隔的事务信息*\
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')
AND commit_timestamp <= TO_TIMESTAMP('2003-10-21 11:30:00','YYYY-MM-DD HH:MI:SS');
SELECT xid,
logon_user
FROM flashback_transaction_query
WHERE xid IN ( SELECT versions_xid
FROM personnel
VERSIONS BETWEEN
TIMESTAMP TO_TIMESTAMP('2007-03-21 19:30:00', 'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP('2007-03-22 04:30:00', 'YYYY-MM-DD HH24:MI:SS') );
实操场景
1.打开附加日志,并授权
alter database add supplemental log data;
grant SELECT ANY TRANSACTION to hr;
2.产生事务
insert into hr.departments
(department_id,department_name,manager_id,location_id)
values (999,'SETI',100,1700);
update hr.employees set department_id=999
where employee_id=200;
commit;
3.获取事务号并且通过事务号得到undo sql
select
versions_xid,versions_startscn,department_id,department_name
from hr.departments
versions between timestamp minvalue and maxvalue
where department_id=999
order by 2 nulls first;
set line 200
col undo_sql for a90
SELECT operation, undo_sql, table_name FROM flashback_transaction_query WHERE xid = HEXTORAW('10000A0039030000') ORDER BY undo_change#;
OPERATION UNDO_SQL TABLE_NAME
---------- ------------------------------------------------------------------------------------------ ------------------------------
UPDATE update "HR"."EMPLOYEES" set "DEPARTMENT_ID" = '10' where ROWID = 'AAAWXeAAEAAAAZtAAC'; EMPLOYEES
INSERT delete from "HR"."DEPARTMENTS" where ROWID = 'AAAWXZAAEAAAAZMAAb'; DEPARTMENTS
BEGIN
----如果需要回退,执行上面的undo_sql即可
使用下面的pl/sql语句回退事务
begin
for rec in
(select undo_sql
from flashback_transaction_query
where xid='10000A0039030000')
loop
if rec.undo_sql is not null then
execute immediate substr(rec.undo_sql,1,length(rec.undo_sql)-1);
end if;
end loop;
commit;
end;
/
笔记