熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Oracle >> 正文

閃回查詢(Flashback Query)

2013-11-13 22:21:32  來源: Oracle 

  
  作者gototop
  
  一簡介
  
  在過去如果用戶誤刪/更新了數據後作為用戶並沒有什麼直接的方法來進行恢復他們必須求助DBA來對數據庫進行恢復到了Oraclei這一個難堪局面有所改善Oracle i中提供了一項新的技術手段閃回查詢用戶使用閃回查詢可以及時取得誤操作前的數據並可以針對錯誤進行相應的恢復措施而這一切都無需DBA干預
  
  下面我們通過一個例子來具體說明閃回查詢的用法
  
  二示例
  
  使用閃回查詢前必須確定下面兩個參數
  
  UNDO_MANAGEMENT = AUTO
  
  undo_retention = ; #這個時間可以隨便設他表示在系統中保留提交了的UNDO信息的時間就是保留分鐘
  
  使用閃回查詢
  
  SQL> conn sys/sys as sysdba
  
  Connected
  
  SQL> create user flash identified by flash;
  
  User created
  
  SQL> grant connect resource to flash;
  
  Grant succeeded
  
  SQL> grant execute on dbms_flashback to flash;
  
  Grant succeeded
  
  SQL> conn flash/flash
  
  Connected
  
  SQL> set echo on
  
  SQL> create table t (a varchar());
  
  Table created
  
  SQL> insert into t values(gototop);
  
   row created
  
  SQL> insert into t values();
  
   row created
  
  SQL> /
  
  SQL> select * from t;
  
  A
  
  
  
  gototop
  
  
  
  
  
  SQL> set time on
  
  :: SQL>
  
  :: SQL>
  
  :: SQL> delete t where a=gototop;
  
   row deleted
  
  :: SQL> commit;
  
  Commit complete
  
  :: SQL> select * from t;
  
  A
  
  
  
  
  
  
  
  :: SQL> execute DBMS_FLASHBACKENABLE_AT_TIME(to_date( ::));
  
  PL/SQL procedure successfully completed
  
  :: SQL> select * from t;
  
  A
  
  
  
  gototop
  
  
  
  
  
  :: SQL> execute DBMS_FLASHBACKDISABLE;
  
  PL/SQL procedure successfully completed
  
  :: SQL> select * from t;
  
  A
  
  
  
  
  
  
  
  使用閃回查詢恢復數據
  
  :: SQL> select * from t;
  
  no rows selected
  
  :: SQL> insert into t values();
  
   row created
  
  :: SQL> /
  
   row created
  
  :: SQL> /
  
   row created
  
  :: SQL> /
  
   row created
  
  :: SQL> /
  
   row created
  
  :: SQL> commit;
  
  Commit complete
  
  :: SQL> /
  
  Commit complete
  
  :: SQL> /
  
  Commit complete
  
  :: SQL> select * from t;
  
  A
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
   rows selected
  
  :: SQL>
  
  :: SQL> delete t;
  
   rows deleted
  
  :: SQL> commit;
  
  Commit complete
  
  :: SQL> commit;
  
  Commit complete
  
  :: SQL> /
  
  Commit complete
  
  :: SQL> declare
  
  :: cursor flash_recover is
  
  :: select * from t;
  
  :: t_recode t%rowtype;
  
  :: begin
  
  :: DBMS_FLASHBACKENABLE_AT_TIME(to_date( ::));
  
  :: open FLASH_RECOVER;
  
  :: DBMS_FLASHBACKDISABLE;
  
  :: loop
  
  :: FETCH FLASH_RECOVER INTO t_recode;
  
  :: EXIT WHEN FLASH_RECOVER%NOTFOUND;
  
  :: insert into t values (t_recodea);
  
  :: end loop;
  
  :: CLOSE FLASH_RECOVER;
  
  :: commit;
  
  :: end;
  
  :: /
  
  PL/SQL procedure successfully completed
  
  :: SQL> :: SQL>
  
  :: SQL> select * from t;
  
  A
  
  
  
  
  
  
  
  
  
  
  
  
  
  :: SQL>
  
  我們可以已經恢復了條紀錄但我們要恢復的條紀錄為什麼會少一條呢?原因就在下面
  
  三局限性
  
  閃回查詢是基於SCN的雖然我執行的是
  
  DBMS_FLASHBACKENABLE_AT_TIME(to_date( ::));
  
  但Oracle並不會精確的這個時間點而是ROUND DOWN到最近的一次SCN然後從這個SCN開始進行恢復而Oracle i是每五分鐘記錄一次SCN的並將SCN和對應時間的映射做個紀錄
  
  這正是上面我們進行恢復時少了一條的原因因此如果使用DBMS_FLASHBACKENABLE_AT_TIME來進行恢復為了避免恢復失敗我可以先等分鐘然後再進行恢復
  
  使用DBMS_FLASHBACKENABLE_AT_TIME進行恢復還有一個缺點那就是在Oracle i中SCN和對應時間的映射信息只會保留因此我們無法通過DBMS_FLASHBACKENABLE_AT_TIME來恢復天前的數據如果你想使用閃回查詢來恢復天前的數據你必須自己來確定需要恢復的SCN然後使用
  
  DBMS_FLASHBACKENABLE_AT_SYSTEM_CHANGE_NUMBER(SCN_NUMBER); 來定位你的恢復時間點下面是使用方法
  
  :: SQL> VARIABLE SCN_SAVE NUMBER;
  
  :: SQL> EXECUTE :SCN_SAVE := DBMS_FLASHBACKGET_SYSTEM_CHANGE_NUMBER;
  
  PL/SQL procedure successfully completed
  
  :: SQL> print SCN_SAVE;
  
  SCN_SAVE
  
  
  
  E+
  
  :: SQL> execute DBMS_FLASHBACKENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);
  
  PL/SQL procedure successfully completed
  
  另外在使用DBMS_FLASHBACKENABLE_AT_TIME前你必須設定你的NLS_DATE_FORMAT的精確程度Oracle默認的是精確到天如果你不設定像上面的例子你不會得到預期結果
  
  如果你使用sysdate和DBMS_FLASHBACKGET_SYSTEM_CHANGE_NUMBER來獲取時間點或者SCN值你必須注意它們取得都是當前的時間點和SCN值
  
  你只能在事務開始時進入閃回查詢模式如果之前有DML操作則必須COMMIT
  
  閃回查詢無法恢復到表結構改變之前因為閃回查詢使用的當前的數據字典

From:http://tw.wingwit.com/Article/program/Oracle/201311/18870.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.