作者
gototop
一
簡介
在過去
如果用戶誤刪/更新了數據後
作為用戶並沒有什麼直接的方法來進行恢復
他們必須求助DBA來對數據庫進行恢復
到了Oracle
i
這一個難堪局面有所改善
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_FLASHBACK
ENABLE_AT_TIME(to_date(
:
:
));
PL/SQL procedure successfully completed
:
:
SQL> select * from t;
A
gototop
:
:
SQL> execute DBMS_FLASHBACK
DISABLE;
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_FLASHBACK
ENABLE_AT_TIME(to_date(
:
:
));
:
:
open FLASH_RECOVER;
:
:
DBMS_FLASHBACK
DISABLE;
:
:
loop
:
:
FETCH FLASH_RECOVER INTO t_recode;
:
:
EXIT WHEN FLASH_RECOVER%NOTFOUND;
:
:
insert into t values (t_recode
a);
:
:
end loop;
:
:
CLOSE FLASH_RECOVER;
:
:
commit;
:
:
end;
:
:
/
PL/SQL procedure successfully completed
:
:
SQL>
:
:
SQL>
:
:
SQL> select * from t;
A
:
:
SQL>
我們可以已經恢復了
條紀錄
但我們要恢復的
條紀錄
為什麼會少一條呢?原因就在下面
三
局限性
閃回查詢是基於SCN的
雖然我執行的是
DBMS_FLASHBACK
ENABLE_AT_TIME(to_date(
:
:
));
但Oracle並不會精確的這個時間點
而是ROUND DOWN到最近的一次SCN
然後從這個SCN開始進行恢復
而Oracle
i是每五分鐘記錄一次SCN的
並將SCN和對應時間的映射做個紀錄
這正是上面我們進行恢復時少了一條的原因
因此如果使用DBMS_FLASHBACK
ENABLE_AT_TIME來進行恢復
為了避免恢復失敗
我可以先等
分鐘
然後再進行恢復
使用DBMS_FLASHBACK
ENABLE_AT_TIME進行恢復還有一個缺點
那就是在Oracle
i中SCN和對應時間的映射信息只會保留
天
因此我們無法通過DBMS_FLASHBACK
ENABLE_AT_TIME來恢復
天前的數據
如果你想使用閃回查詢來恢復
天前的數據
你必須自己來確定需要恢復的SCN
然後使用
DBMS_FLASHBACK
ENABLE_AT_SYSTEM_CHANGE_NUMBER(SCN_NUMBER); 來定位你的恢復時間點
下面是使用方法
:
:
SQL> VARIABLE SCN_SAVE NUMBER;
:
:
SQL> EXECUTE :SCN_SAVE := DBMS_FLASHBACK
GET_SYSTEM_CHANGE_NUMBER;
PL/SQL procedure successfully completed
:
:
SQL> print SCN_SAVE;
SCN_SAVE
E+
:
:
SQL> execute DBMS_FLASHBACK
ENABLE_AT_SYSTEM_CHANGE_NUMBER(:SCN_SAVE);
PL/SQL procedure successfully completed
另外
在使用DBMS_FLASHBACK
ENABLE_AT_TIME前
你必須設定你的NLS_DATE_FORMAT的精確程度
Oracle默認的是精確到天
如果你不設定
像上面的例子你不會得到預期結果
如果你使用sysdate和DBMS_FLASHBACK
GET_SYSTEM_CHANGE_NUMBER來獲取時間點或者SCN值
你必須注意它們取得都是當前的時間點和SCN值
你只能在事務開始時進入閃回查詢模式
如果之前有DML操作
則必須COMMIT
閃回查詢無法恢復到表結構改變之前
因為閃回查詢使用的當前的數據字典
From:http://tw.wingwit.com/Article/program/Oracle/201311/18870.html