从Oracle9i开始,Oracle开始提供闪回查询特性(flashback query),允许将回滚段中的数据进行闪回。通过这个例子我们来看一下这个从Oracle9i开始提供的新特性。
首先我们注意到这里存在一个信息: ctl max scn: 0x0819.003f594b,这个转换为SCN值就是:SQL>select(to_number('819','xxxx')*power(2,32)+to_number('3f594b','xxxxxxxx'))scn
2fromdual;
SCN
-----------------
8903471356235
可以查询一下当前数据库的SCN:SQL>selectdbms_flashback.get_system_change_numberscnfromdual;
SCN
-----------------
8903471437610
通过特定的语法,我们可以将SCN为8903471356235的历史状态数据查询出来:SQL>select*fromempasofscn8903471356235whereempnoin(7788,7782,7698);
EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
------------------------------------------------------------------------------
7698BLAKEMANAGER783901-MAY-81285030
7782CLARKMANAGER783909-JUN-81245010
7788SCOTTANALYST756619-APR-87300020
在结果中,我们注意到3名员工的薪水恢复到了之前值。而在当前的查询中,这个数值是变化后的4000:SQL>select*fromempwhereempnoin(7788,7782,7698);
EMPNOENAMEJOBMGRHIREDATESALCOMMDEPTNO
------------------------------------------------------------------------------
7698BLAKEMANAGER783901-MAY-81400030
7782CLARKMANAGER783909-JUN-81400010
7788SCOTTANALYST756619-APR-87400020
由于这个查询需要从UNDO中获取前镜像信息,如果UNDO中的信息被覆盖,则以上查询将会失败。为了模拟不同情况,创建一个新的UNDO表空间,切换数据库使用新的UNDO表空间,再将原表空间Offline:SQL>createundotablespaceundotbsdatafile'/opt/oracle/oradata/conner/undotbs.dbf'size2M;
Tablespacecreated.
SQL>altersystemsetundo_tablespace=undotbs;
Systemaltered.
SQL>altertablespaceUNDOTBS1offline;
Tablespacealtered.
SQL>altersessionsetevents='immediatetracenameflush_cache';
Sessionaltered.
再来查询,此时出现错误,记录该文件已经不可读取:SQL>select*fromempasofscn8903471356235whereempnoin(7788,7782,7698);
select*fromempasofscn8903471356235whereempnoin(7788,7782,7698)
*
ERRORatline1:
ORA-00376:file2cannotbereadatthistime
ORA-01110:datafile2:'/opt/oracle/oradata/conner/undotbs1.dbf'
将UNDOTBS1重新启用,则此时前镜像信息再次可以查询:SQL>altertablespaceUNDOTBS1online;
Tablespacealtered.
SQL>altersystemsetundo_tablespace=UNDOTBS1;
Systemaltered.
在其他Session执行大量事务,使得前镜像信息被覆盖:SQL>begin
2foriin1..2000loop
3updateempsetsal=4000;
4rollback;
5endloop;
6end;
7/
PL/SQLproceduresuccessfullycompleted.
SQL>/
PL/SQLproceduresuccessfullycompleted.
SQL>/
观察回滚段的使用:SQL>selectusn,xacts,RSSIZE,HWMSIZEfromv$rollstatwhereusn=6;
USNXACTSRSSIZEHWMSIZE
----------------------------------------
6173318407331840
那么再次查询就可能收到如下错误:SQL>select*fromempasofscn8903471356235whereempnoin(7788,7782,7698);
select*fromempasofscn8903471356235whereempnoin(7788,7782,7698)
*
ERRORatline1:
ORA-01555:snapshottooold:rollbacksegmentnumber6withname"_SYSSMU6$"toosmall
ORA-01555错误出现,说明要查询的前镜像信息已经失去。