1. 概述 :
Oracle 的闪回技术 有时间穿越的功能 , 主要是针对 失误操作 (误删除数据) 一系列问题 , 提供的 闪回技术 (flashback) . 操作 主要 有两类 : 闪回查询 和 闪回数据 .
闪回查询 主要有 :
- 普通闪回查询
- 闪回版本查询
- 闪回事务查询
闪回数据 主要有:
- 闪回表
- 闪回删除
- 闪回事务
- 闪回数据库
- 闪回数据档
2 . 闪回查询
概述 : 以表为单位查询过去的数据 .
① 闪回时间点查询 . (利用 as of / dbms_dlashback)
as of 子句
1. 查询7788号员工在具体时间的工资
SQL> select sal from emp as of timestamp to_timestamp('2014-09-16 10:02:30','yyyy-mm-dd,hh24:mi:ss') where empno=7788;
2. 查询7788号员工在五分钟前的工资
SQL> select sal from emp as of timestamp (systimestamp - interval '5' minute) where empno=7788;
3. 查询具体SCN
SQL> select * from emp as of scn 1095000;
4. 将7788号员工的工资修改为15分钟之前的值
SQL> update emp set sal=(select sal from emp as of timestamp(systimestamp - interval '15' minute) where empno=7888) where empno=7788;
dbms_flashback包
利用dbms_flashback包的enable_at_time或enable_at_scn存储过程锁定一个会话级别的闪回时间目标,即进入闪回模式,随后的查询命令可以省略'as of’,直接调用dbms_flashback_disable存储过程将其关闭位置。需要注意的是这里需要给用户赋予这个包的可执行权限
首先赋予test用户对这个包可执行权限grant execute on sys.dbms_flashback to test; 比如,将闪回模式会话定格在15分钟前:
SQL> exec dbms_flashback.enable_at_time(systimestamp - interval '15' minute);
现在进行查询,注意,此时查询的是15分钟之前的表。
SQL> select sal from emp where empno=7788; --忽略了“as of”子句
此时若访问SYSDATE、SYSTIMESTAMP等日期函数,它们的返回值仍是当前值,而不是15分钟之前的值。
处于闪回会话模式时,执行dml和ddl将报错
SQL> update emp set sal=4000 where empno=7788;
update emp set sal=4000 where empno=7788
*
ERROR at line 1:
ORA-08182: operation not supported while in Flashback mode
如果查询完毕,可调用disable存储过程关闭闪回会话模式。
SQL> exec dbms_flashback.disable;
② 闪回版本查询 .
概述 : 闪回版本查询可以贯穿一定长度的时间窗口,通过只使用一条查询命令就能返回该时间窗口内不同时间点上的数据。
示例 : 比如,首先通过3个数据将7788号员工的工资进行修改,其值原来是4000,然后是5000,然后是10000,最后是3000
SQL> select sal from emp where empno=7788;
SAL
----------
4000
SQL> update emp set sal=5000 where empno=7788;
1 row updated.
SQL> commit;
Commit complete.
SQL> update emp set sal=10000 where empno=7788;
1 row updated.
SQL> commit;
Commit complete.
SQL> update emp set sal=3000 where empno=7788;
1 row updated.
SQL> commit;
Commit complete.
SQL> select empno,sal from emp
2 versions between timestamp(systimestamp -interval '15' minute) and maxvalue
3 where empno=7788;
EMPNO SAL
----- ----------
7788 3000
7788 10000
7788 5000
7788 4000
通过‘version between',我们可以看到在15分钟之内,7788号员工的工作用4个值,说明共有3个事务对其进行过修改。为了能看清这些事务的先后顺序,可以在查询列表中使用伪字段。如下所示:
SQL> select
2 versions_xid,versions_startscn,versions_endscn,
3 empno,sal
4 from emp
5 versions between timestamp(systimestamp - interval '15' minute) and maxvalue
6 where empno=7788
7 order by 2 nulls first;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN EMPNO SAL
---------------- ----------------- --------------- ----- ----------
060002000F030000 1097139 7788 4000
02001100FB020000 1097139 1097148 7788 5000
03001D001E030000 1097148 1097153 7788 10000
0900170000030000 1097153 7788 3000
其中,versions_xid为事务号,versions_startscn和versions_endscn分别是事务开始时的scn和修改该行的下一个事务开始时的scn。首尾衔接这两个字段的scn号很容易得出真实的修改顺序:4000,5000,10000,最后是3000.