日期:2014-05-16  浏览次数:20469 次

Oracle闪回查询总结
Oracle闪回查询总结

    1、Oracle 9i以后版本的闪回查询功能描述

    在Oracle 9i之前,如果用户错误操作数据后,除了不完全恢复外,没有什么好的办法,但是可以求助DBA来对数据库恢复,但是这将消耗大量的系统资源。为了解决这个问题,Oracle提供了一个新的包(DBMS_FLASH)来实现。用户使用闪回可以及时取得操作DML前某一个时间点数据库的印象视图,也可以利用系统时间(时间戳)或是系统改编号(SCN:System Change Number)来执行恢复。闪回功能完全依赖于自动回滚段管理(AUM)。

    2、回滚段概述

     回滚段用于存放数据修改之前的位置和值,回滚段的头部包含正在使用的该回滚段事务的信息。回滚段的作用如下:

    (1)事务回滚:当事务修改表中数据的时候,该数据修改前的值(即前影像)会存放在回滚段中,当用户回滚事务时,Oracle将会利用回滚段中的数据前影像来将修改的数据恢复到原来的值。

   (2)事务恢复:当事务正在处理的时候,例程失败,回滚段的信息保存在重做日志文件中,Oracle将在下次打开数据库时利用回滚来恢复未提交的数据。

   (3)读一致性:当一个会话正在修改数据时,其它的会话将看不到该会话未提交的修改。而且,当一个语句正在执行时,该语句将看不到从该语句开始执行后的未提交的修改(语句级读一致性)。这里就涉及到Oracle的事务级别,在此不做讨论。

    3、下面看看Oracle的delete和commit操作的流程分析

   (1)delete流程

    首先Oracle将数据块读到缓冲区中; 在“重做日志缓冲区”中记录delete操作的全过程;在相应回滚段段头的事务表中创建一个回滚条目;将要删除的记录创建前镜像并存放到回滚段中;最后将相应的数据块上删除记录并标记相应的数据块为dirty。

   (2)commit流程

    Oracle产生一个SCN;在回滚段事务表中标记此事务为committed,然后日志读写进程将日志缓冲区中的记录写到日志文件。

    4、实例演示

    进行闪回查询必须设置自动回滚段管理,在init.ora设置参数UNDO_MANAGEMENT=AUTO,参数UNDO_RETENTION=n,n决定了能往前闪回的最大时间,值越大就需要越多Undo空间。
SQL> conn sys/sys as sysdba (记住要以dba身份登陆,否则创建用户后不能给其授权)
SQL> create user flash identified by flash;
SQL> grant connect, resource to flash;
SQL> grant execute on dbms_flashback to flash;
SQL> conn flash/flash 
SQL> create table t_flash (test varchar2(10));
SQL> insert into t_flash values('google');
SQL> insert into t_flash values('KingXt');
SQL> set time on
SQL> delete t_flash where test = 'google'; --执行此操作要过一段时间
SQL> commit;
SQL> execute dbms_flashback.enable_at_time(to_date('2010-05-8 17:00:00','yyyy-mm-dd hh24:mi:ss')); 
SQL> execute DBMS_FLASHBACK.DISABLE;   -- 这句话一定要执行,结束闪回模式下的操作


    通过上面的试验可以发现,虽然数据被删除且已提交,但是还可以恢复。

    4、使用闪回查询恢复数据

SQL> select * from t_flash;
TEST
----------
SQL> insert into t_flash values('google');
1 row inserted
SQL> /
1 row inserted
SQL> delete t_flash;
6 rows deleted
SQL> commit;
Commit complete
SQL> /
Commit complete 
cursor flash_recover is
select * from t_flash;
t_recode t_flash%rowtype;
begin
dbms_flashback.enable_at_time(to_date('2010-05-8 20:35:23','yyyy-mm-dd hh24:mi:ss'));
open FLASH_RECOVER;
DBMS_FLASHBACK.DISABLE;
loop
FETCH FLASH_RECOVER INTO t_recode;
EXIT WHEN FLASH_RECOVER%NOTFOUND;
insert into t_flash values (t_recode.test);
end loop;
CLOSE FLASH_RECOVER;
commit;
end; 
通过上述操作就可以将原来的数据恢复


    5、局限性

    Oracle每5分钟记录一次SCN,并将SCN和对应时间的映射进行纪录。如果原来插入的记录到做闪回操作的时间在5分钟之内,用基于时间的闪回查询可能得不到记录,因为基于时间点的查询实际上是转化为最近的一次SCN,然后从这个SCN开始进行恢复。因此,如果需要精确的查询可以采用基于SCN的闪回查询,可精确闪回到需要恢复的时间。可以通过DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER语句获取SCN。

    6、Flashback Database

    Oracle Flashback Database特性允许通过SQL语句Flashback Database语句,让数据库前滚到当前的前一个时间点或者SCN,而不需要做时间点的恢复。闪回数据库可以迅速将数据库回到误操作或人为错误的前一个时间点,可以不利用备份就快速的实现基于时间点的恢复,这样就可以节省时间。Oracle通过创建新的Flashback Logs(闪回日志),记录数据库的闪回操作。如果希望能闪回数据库,需要设置如下参数:DB_RECOVER_FILE_DEST日志的存放位置,DB_RECOVER_FILE_DEST_SIZE恢复区的大小。在创建数据库的时候,Oracle将自动创建恢复区,但默认是关闭的,需要执行alter database flashback on命令。

  例:执行Flashback Database命令格式。


SQL>flashback database to time to_timestamp(xxx);
SQL>flashback database to scn xxx


     7、Flashback Table

    Oracle Flashback Table特性允许利用Flashback Table语