Oracle闪回查询

Oracle闪回查询Flashback

参考

http://www.chinaunix.net/jh/19/286443.html

用途

自我维护过程中的修复

当一些重要的行被意外的从一个表中被删除了,用户希望恢复它。做这样一个修理,用户可以向后移动到一个时间点,查看丢失的行并把他们重新插入现在的表内。但是需要注意不要带来逻辑矛盾。

恢复类似于email的应用程序包

在处理类似email和voice mail的应用包体上。当用户因为按错键意外的删除了一封mail或者声音信息时,他们可以通过移回到固定时间点来恢复删除的mail或者信息并将他们重新插入现在的信息箱内。

用于趋势分析的决策支持系统

决策支持系统,联机分析等不得不执行一个长时间运行的事务。有时需要执行对过去数据的分析和建模,例如遮光剂随季节变化需求的变化。

概述

这一特性允许用户查看过去某一时间点数据库的映像视图

用户可以利用系统时间或者System change number(SCN)来指定这个只读视图。所有的在这个时间点之前提交的事务市可见的,之后提交的不可见

Oracle flashback的实质是自动管理undoubtedly information

Undo information在系统级的一个特定的保持力时间间隔内被保存(需要确保在保持力时间间隔内的undo信息对重构映像市足够的)

Oracle flashback是在session级生效的

Pl/sql游标可在flashback被关闭前打开,以执行dml语句

Smon通过表smon_scn_time保证了系统时间和scn号的对应关系

包dbms_flashback提供了闪回到指定的系统时间或者scn的功能。一旦flashback在session级被enable,用户可以执行任意查询或者pl/sql包。所有的对于数据库的查询都是运行在指定时间或者scn的数据库中。因此,用户的会话纪录了基于指定时间的数据库映像,当一个会话断开或者另一个会话连接上来,闪回则自动关闭。用户也可以利用包的disable显式的关闭闪回。这个包可以用在登陆触发器里自动使闪回升效,而不需要更改程序代码。

 
   在flashback状态下打开的pl/sql游标可以记录下当游标打开时系统的基于scn或者时间的闪回状态的数据。不同的并发会话或者连接可以将数据库闪回到不同的时间点或者scn,dml,ddl操作和分布式操作在会话运行于flashback状态时,将被禁止运行,在flashback disable之前打开的pl/sql游标能够被用来执行dml.

当我们用基于时间点的enabling flashback时,数据库自动选择一个在这个指定时间之前的5分钟内产生的一个scn,作为闪回的基点。对于细粒度闪回用户可以用scn来enable flashback.

闪回技术只能是闪回dml操作,而不能闪回ddl操作,例如drop,truncate都不能被闪回,这是因为rollback segments不能存储足够的信息来重建以前的object.另外闪回也不能应用于pl/sql包,存储过程,或者函数。

相关操作

DBA必须设定undo保持力足够大以能够重构需要闪回的数据

ALTER SYSTEM SET UNDO_RETENTION=<SECONDS>;seconds值委undo数据保持的秒数。

Flashback view是由undo retention interval来限制的。

包DBMS_FLASHBACK提供了需求接口

call dbms_flashback.enable_at_time(9-nov-01:11:00:00);

select * from employees;

call dbms_flashback.disable();

enable_at_time:会话级的enable flashback,映像时间被设定为最接近指定时间戳的scn

enable_at_system_change_number:将数据库闪回到指定的scn号。

get_system_change_number:返回当前的scn。

disable:这个存储过程允许我们在整个会话内停止flashback并将你带回当前时间的数据状态。

dbms_flashback.enable存储过程不可以在有活动事务的时候执行,并且,这个包不能用sys身份执行。

在使用DBMS_FLASHBACK.ENABLE_AT_TIME前,你必须设定你的NLS_DATE_FORMAT的精确程度,Oracle默认的是精确到天

示例

1、使用闪回查询查询误删除数据。 
SQL>; create user flashback identified by flashback; 
用户已创建 
SQL>; grant connect, resource to flashback; 
授权成功。 
SQL>; grant execute on dbms_flashback to flashback; 
授权成功。 
SQL>; conn 
请输入用户名:  flashback/flashback 
已连接。 
SQL>; set echo on 
SQL>; create table t(a date); 
表已创建。 
15:40:18 SQL>; select * from t; 
未选定行 
15:40:22 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
15:40:35 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
15:40:42 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
15:40:46 SQL>; commit; 
提交完成。 
15:40:59 SQL>; select to_char(a,'yyyy-mm-dd hh:mi:ss') from t; 
TO_CHAR(A,'YYYY-MM- 
------------------- 
2004-03-22 03:40:35 
2004-03-22 03:40:42 
2004-03-22 03:40:46 


15:41:06 SQL>; 
15:42:06 SQL>; 
15:45:37 SQL>; 
15:54:18 SQL>; delete from t where rownum<2; 
已删除 1 行。 
15:54:41 SQL>; commit; 
提交完成。 
15:54:42 SQL>; select * from t; 

---------- 
22-3月 -04 
22-3月 -04 

15:55:55 SQL>; execute DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2004-03-22 15:50:00 
','yyyy-mm-dd hh24:mi:ss')); 
PL/SQL 过程已成功完成。 
15:56:32 SQL>; select * from t; 

---------- 
22-3月 -04 
22-3月 -04 
22-3月 -04 

15:56:38 SQL>; select to_char(a,'yyyy-mm-dd hh:mi:ss') from t; 
TO_CHAR(A,'YYYY-MM- 
------------------- 
2004-03-22 03:40:35 
2004-03-22 03:40:42 
2004-03-22 03:40:46 
15:56:45 SQL>; 


2、使用闪回查询恢复误删数据 
16:18:57 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
16:19:05 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
16:19:08 SQL>; commit; 
提交完成。 
16:19:10 SQL>; 
16:20:58 SQL>; 
16:24:01 SQL>; 
16:25:39 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
16:25:44 SQL>; insert into t select sysdate from dual; 
已创建 1 行。 
16:25:45 SQL>; commit; 
提交完成。 
16:25:47 SQL>; select to_char(a,'yyyy-mm-dd hh:mi:ss') from t; 
TO_CHAR(A,'YYYY-MM- 
------------------- 
2004-03-22 04:25:45 
2004-03-22 04:19:05 
2004-03-22 04:19:08 
2004-03-22 04:25:44 

16:26:05 SQL>; select to_char(a,'yyyy-mm-dd hh24:mi:ss') from t; 
TO_CHAR(A,'YYYY-MM- 
------------------- 
2004-03-22 16:25:45 
2004-03-22 16:19:05 
2004-03-22 16:19:08 
2004-03-22 16:25:44 

16:26:15 SQL>; delete from t where rownum<4; 
已删除3行。 
16:26:38 SQL>; commit; 
提交完成。 
16:26:40 SQL>; select to_char(a,'yyyy-mm-dd hh24:mi:ss') from t; 
TO_CHAR(A,'YYYY-MM- 
------------------- 
2004-03-22 16:25:44 

16:26:42 SQL>; declare 
16:27:36   2  cursor flash_recover is 
16:27:36   3  select * from t; 
16:27:36   4  t_recode t%rowtype; 
16:27:36   5  begin 
16:27:36   6  DBMS_FLASHBACK.ENABLE_AT_TIME(to_date('2004-03-22 16:26:05','yyyy 
mm-dd hh24:mi:ss')); 
16:27:36   7  open FLASH_RECOVER; 
16:27:36   8  DBMS_FLASHBACK.DISABLE; 
16:27:36   9  loop 
16:27:36  10  FETCH FLASH_RECOVER INTO t_recode; 
16:27:36  11  EXIT WHEN FLASH_RECOVER%NOTFOUND; 
16:27:36  12  insert into t values (t_recode.a); 
16:27:36  13  end loop; 
16:27:36  14  CLOSE FLASH_RECOVER; 
16:27:36  15  commit; 
16:27:36  16  end; 
16:27:36  17  / 
PL/SQL 过程已成功完成。 
16:27:37 SQL>; select to_char(a,'yyyy-mm-dd hh24:mi:ss') from t; 
TO_CHAR(A,'YYYY-MM- 
------------------- 
2004-03-22 16:19:05 
2004-03-22 16:19:08 
2004-03-22 16:25:44 

16:27:48 SQL>;

我们可以看到利用游标我们可以将丢失的数据找回来,但是我们同时也发现,在找回数据的时候我们丢失了一条数据,这个就是我们前面介绍的在应用基于时间点的闪回的时候,oracle数据库自动选择一个在这个指定时间之前的5分钟内产生的一个scn,作为闪回的基点。在我上面操作的例子中,由于我在第二次提交后两条数据和删除之间的时间间隔太短,而这里面的scn和系统时间对照表5分钟刷新一次,距离我闪回的时间最近的scn不是最后一次提交的时间,而是插入前两条记录后提交的时间,导致后面插入的所有数据无法闪回,所以如果发生插入纪录和删除记录时间间隔太短,中间恰好没有scn记录时,这些数据将无法恢复。

flashback简易用法

使用AS OF SCN 或 AS OF TIMESTAMP子句

select count(*) from emp AS OF SCN :scn;

表smon_scn_time记录scn和time的对应关系

这是一个sys用户的表。 
16:46:37 SQL>; select count(*) from sys.smon_scn_time; 
  COUNT(*) 
---------- 
      1440 
可以看出表内共1440条记录。 
16:47:17 SQL>; select to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_ 
time where rownum<10; 
TO_CHAR(TIME_DP,'YY 
------------------- 
2004-03-19 16:24:51 
2004-03-19 16:29:58 
2004-03-19 16:35:05 
2004-03-19 16:40:12 
2004-03-19 16:45:20 
2004-03-19 16:50:27 
2004-03-19 16:55:39 
2004-03-19 17:00:47 
2004-03-19 17:05:54

smon_scn_time每5分钟记录一次对照当我们指定时间后,smon利用这个表查找前面的最近scn号。

这个表每过5分钟自动删除最旧记录,加入新纪录,记录总数一直保持1440,也就是5天时间,所以如果我们通过enable_at_time是无法恢复5天前的数据的,这个时候就必须使用scn。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值