HelloDBA [English]
搜索Internet 搜索 HelloDBABA
  Oracle技术站。email: fuyuncat@gmail.com  MSN: fuyuncat@hotmail.com   acoug  acoug 

Schema的回滚快照

[English]

作者: fuyuncat

来源: www.HelloDBA.com

日期: 2015-11-03 21:41:06

分享到  新浪微博 腾讯微博 人人网 i贴吧 开心网 豆瓣 淘宝 推特 Facebook GMail Blogger Orkut Google Bookmarks

 多天前,我们的一个客户不小心在网站上做了一个"删除"操作.但他发现他无法确认被他删除的对象是否真的应该被删除.于是求助于我们,希望能看到“删除”操作之前的界面。

我们首先想到的是借助于闪回查询(Flashback Query)。但是,他的这个简单的删除操作实际上在后台数据库当中删除了十多张表的相关数据。而且用于在页面上显示这些对象的代码的逻辑也相当复杂。因此,闪回查询无助于他的要求。我们最终利用expdp的flashback_time参数,将这个schema的数据导出,再导入一个测试环境完成他的请求。

我当时想到,如果Oracle在会话级别提供一个参数flashback_scn/flashback_time控制这个会话的所有查询都闪回到某一个时间点,那这个问题就很容易解决:只要建立一个新的连接,当连上数据库后就修改该参数,就可以查询到该时间点的快照了。

于是我又想,能否找到一个方法,模拟实现出一个schema的闪回快照呢。最终,我找到一个不完善的方法:建立一个新的schema,在该schema当中,为每个源schema的表建立一个视图,在试图中引入闪回查询。并且引入一个“全局变量”来控制视图的闪回时间/scn。

以下就是代码

SQL代码
  1. -- ################################################################################  
  2. -- #  
  3. -- #         $Id: schema_snapshot.sql  
  4. -- #  
  5. -- #        File: $RCSfile: schema_snapshot.sql,v $  
  6. -- # Description: create a snapshot for a schema  
  7. -- #       Usage: sqlplus -s /nolog @schema_snapshot <existing_schema_name> <snapshot_schema_name>  
  8. -- #     Created: 07/02/2014  
  9. -- #      Author: Wei Huang  
  10. -- # User run as: / as sysdba (OS user should be oracle owner)  
  11. -- #  Parameters: 1: existing schema name  
  12. -- #  Parameters: 2: new schema name  
  13. -- #  Parameters: 3: snapshot timestamp  
  14. -- #  
  15. -- #  Copyright (c) 2014 Wei Huang  
  16. -- #  
  17. -- # History  
  18. -- # Modified by   When      Why  
  19. -- # -----------   -------   ----------------------------------------------------  
  20. -- ################################################################################  
  21.   
  22. prompt Usage: @schema_snapshot <existing_schema_name> <snapshot_schema_name>  
  23. prompt Description: create a snapshot for a schema  
  24. prompt   
  25.   
  26. declare  
  27.   sql_str varchar2(4000);  
  28.   c number;  
  29. begin  
  30.   select count(1) into c from dba_users where username = upper('&2');  
  31.   if c = 0 then  
  32.     execute immediate 'create user &2 identified by &2';  
  33.     execute immediate 'grant connect,resource to &2';  
  34.     sql_str := q'[ 
  35. CREATE OR REPLACE PACKAGE &2.var_pkg IS 
  36.   var varchar2(255); 
  37.   PROCEDURE set_var(val varchar2); 
  38.   function get_var return varchar2; 
  39. END var_pkg ; 
  40. / 
  41.  
  42. CREATE OR REPLACE PACKAGE BODY &2.var_pkg IS 
  43.   PROCEDURE set_var(val varchar2) IS 
  44.   BEGIN 
  45.     var := val; 
  46.   end set_var; 
  47.  
  48.   function get_var return varchar2  
  49.   IS 
  50.   BEGIN 
  51.     return var; 
  52.   END get_var; 
  53. END var_pkg; 
  54. / 
  55. ]';  
  56.   
  57.     execute immediate sql_str;  
  58.     for q in (select 'grant select,flashback on '||owner||'.'||table_name||' to '||upper('&2')||';' str from dba_tables where owner=upper('&1')) loop  
  59.       execute immediate q.str;  
  60.     end loop;  
  61.     for q in (select 'create or replace view '||upper('&2')||'.V_'||table_name||' as select * from '||owner||'.'||table_name||'  as of timestamp to_timestamp(var_pkg.get_var,''yyyymmddhh24miss'');' from dba_tables where owner=upper('&1') loop  
  62.       execute immediate q.str;  
  63.     end loop;  
  64.     for q in (select 'create or replace synonym '||upper('&2')||'.'||table_name||' for '||upper('&2')||'.V_'||table_name||';' from dba_tables where owner=upper('&1') loop  
  65.       execute immediate q.str;  
  66.     end loop;  
  67.   
  68.     &2.var_pkg.set_var('&3');  
  69.   end if;  
  70. end;  
  71. /  

这段代码将会产生用于创建闪回快照schema的中对象的代码。连接该schema的客户端将会读取到源schema的某个时间点的快照数据。当然,如果源schema中还有存储过程、视图等其他plsql代码的话,还要在该schema当中重新创建。

Top

Copyright ©2005,HelloDBA.Com 保留一切权利

申明
by fuyuncat