?
1、
原理
?
??? 當數(shù)據UPDATE或DELETE時,原來的數(shù)據會保存在UNDO表空間中,保存的最少時間是UNDO_RETENTION。實際的保存時間與UNDO表空間的大小和數(shù)據更改的繁忙程度相關。UNDO_RETENTION的參數(shù)(單位為秒)指定Oracle保存用于FlashBack查詢的UNDO映像的時間。一般你可以將這個值設為一整天(864000秒),這樣你就能看到前一天全天的映像。當然,你的在線UNDO日志必須足夠大,大到足以能保存一整天的UNDO日志數(shù)據,對于繁忙
的Oracle系統(tǒng),這個數(shù)值可以達到很大。
?
2、
一些限制
?
??? * 服務器必須配置成使用自動 undo管理。
??? * 在使用FlashBack查詢時不能使用DDL或者DML。
??? *
FlashBack不取消DDL操作,例如DROP命令。
?
??? 數(shù)據庫管理員做一些必要的設置之后,一般用戶才能使用Flashback查詢功能:
??? SQL> ALTER SYSTEM SET UNDO_MANAGEMENT=AUTO
??? SQL> ALTER SYSTEM SET UNDO_RETENTION=86400
??? SQL> GRANT EXECUTE ON DBMS_FLASHBACK TO USERNAME;
?
3、獲得
S
CN
或時間點
?
??? 在FlashBack時,可以嘗試多個SCN,獲取最佳值。
??? 如果能得知具體時間,那么可以獲得準確的數(shù)據閃回。
??? SQL> alter session set nls_date_format='YYYY-MM-DD HH24:MI:SS';
??? SQL> select sysdate from v$database;
?
??? 可通過以下方法獲取SCN,但是不知為什么,兩種方法獲得的 SCN不一樣
??? SQL> select dbms_flashback.get_system_change_number scn from dual;
??? SQL> select max(ktuxescnw * power(2,32) + ktuxescnb) SCN from x$ktuxe;
?
4
、
啟用或禁用
f
lashback
查詢
?
使用系統(tǒng)改變數(shù)(SCN)或者真實時間來指定FlashBack的時間點來獲取數(shù)據映象。
?
方法一:
SQL> select * from [TABLE] as of scn 129292;
SQL> select * from [TABLE] as of timestamp to_timestamp('時間','時間格式');
SQL>?select?*?from [TABLE]?as?of?timestamp?to_timestamp('2007-12-18?08:40:00','YYYY-MM-DD HH24:MI:SS');
?
方法二:
啟用:
SQL> exec dbms_flashback.enable_at_system_change_number(112112);
SQL> exec dbms_Flashback.enable_at_time('28-AUG-02 11:00:00');
啟用后看到的只是閃回的結果,實際上并未恢復數(shù)據。且閃回狀態(tài)下不能做
DML操作??梢韵然謴偷揭粋€臨時表中。見示例。
?
禁用:
SQL> exec dbms_flashback.disable();
?
5、
示例:
?
declare
? cursor c1 is
??? select * from scott.emp_temp;
? r_c1 scott.e%rowt ype;
begin
? loop
??? dbms_flashback.enable_at_system_change_number(49570);
??? if c1%isopen = false then
????? open c1;
??? end if;
??? fetch c1
????? into r_c1;
??? dbms_flashback.disable();
??? exit when c1%notfound;
??? update scott.emp_temp set sal = r_c1.sal where empno = r_c1.empno;
??? commit;
? end loop;
? exec dbms_flashback.disable();
? close c1;
end;
/
?
?
?
轉一篇的yangtingkun文章:
====================================================================================================
?
?
??? 從9i開始,Oracle提供了閃回(FLASHBACK)功能。即查找當前時間之前的某個時間點系統(tǒng)或表的狀態(tài)。
??? 可以閃回的最大時間和回滾空間有關。如果使用了自動管理回滾表空間,那么UNDO_RETENTION給出了閃回支持的最小時間。也就是說,F(xiàn)LASHBACK最少可以支持UNDO_RETENTION給出的時間,如果系統(tǒng)比較閑,則可以閃回更長的時間。(當然,如果回滾表空間的空間分配不足,當系統(tǒng)處于忙時,有可能重用還沒有達到UNDO_RETENTION時間限制的數(shù)據的空間)
???
使用閃回的一個前提是表不能進行DDL操作。不但不能對DDL操作進行回閃,而且,也無法閃回到DDL操作以前的數(shù)據了。
?
??? Oracle提供兩種方法支持閃回:
?
???
一種是使用DBMS_FLASHBACK包,這是SESSION級的回閃。執(zhí)行DBMS_FLASHBACK包的ENABLE_AT_TIME或者ENABLE_AT_SYSTEM_CHANGE_NUMBER過程后,當前session處于閃回狀態(tài),此時任何的查詢返回的是ENABLE_AT_TIME指定的時間點或ENABLE_AT_SYSTEM_CHANGE_NUMBER指定的SCN的時刻對應的狀態(tài)。當執(zhí)行DISABLE過程后,系統(tǒng)恢復到當前狀態(tài)。
??? 這種方法是SESSION級別,此后對任何表的任意的查詢語句都返回以前某個時間點的結果。不過缺點是閃回狀態(tài)下,不支持DML語句。如果用以前的某個時間點的數(shù)據恢復當前數(shù)據,則必須ENABLE_AT_TIME后,打開一個游標,然后DIABLE閃回狀態(tài),然后從游標中讀取數(shù)據并插入到當前表中。
?
??? 第二種方式是采用AS OF語句,這是語句級的回閃。AS OF后面可以跟TIMESTAMP或SCN。通過在查詢表后面直接加AS OF時間點的方式,可以查詢到那一時刻的數(shù)據。這種方法直觀方便,使用于恢復個別表,或對某個表提供基于時間點的訪問。
??? 下面給出一個例子:
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
會話已更改。
SQL> create table t (id number, name varchar2(30));
表已創(chuàng)建。
SQL> insert into t values (1, 'yangtingkun');
已創(chuàng)建 1 行。
SQL> commit;
提交完成。
SQL> select sysdate from dual;
SYSDATE
-------------------
2005-01-24 23:21:23
SQL> commit;
提交完成。
SQL> select sysdate from dual;
SYSDATE
-------------------
2005-01-24 23:26:05
SQL> delete t;
已刪除 1 行。
SQL> commit;
提交完成。
SQL> exec dbms_flashback.enable_at_time(to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss'))
PL/SQL 過程已成功完成。
SQL> select * from t;
??????? ID NAME
---------- ------------------------------
???????? 1 yangtingkun
SQL> exec dbms_flashback.disable
PL/SQL 過程已成功完成。
SQL> select * from t;
未選定行
SQL> select * from t as of timestamp to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss');
??????? ID NAME
---------- ------------------------------
???????? 1 yangtingkun
?
??? 上面給出了通過兩種方法實現(xiàn)回閃查詢的方法。在上面的例子中,我在執(zhí)行insert命令和delete命令直接間隔了5分鐘左右,且提交了一些空事務。這樣做的原因是由于Oracle把時間點映射到SCN上,大約每5分鐘左右映射依次。因此兩個操作間隔5分鐘,且保證兩個操作間SCN發(fā)生了變化,從而使Oracle可以將timestamp正確的映射到不同的SCN上。
?
???
下面給出兩種不同方法是如何實現(xiàn)數(shù)據恢復的。
SQL> select * from t;
未選定行
SQL> declare
? 2?? cursor c is select * from t;
? 3?? v_record c%rowtype;
? 4? begin
? 5?? dbms_flashback.enable_at_time(to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss'));
? 6?? open c;
? 7?? dbms_flashback.disable;
? 8?? loop
? 9??? fetch c into v_record;
?10??? exit when c%NOTFOUND;
?11??? insert into t values (v_record.id, v_record.name);
?12?? end loop;
?13?? close c;
?14? end;
?15? /
PL/SQL 過程已成功完成。
SQL> select * from t;
??????? ID NAME
---------- ------------------------------
???????? 1 yangtingkun
SQL> rollback;
回退已完成。
SQL> select * from t;
未選定行
SQL> insert into t
? 2? select * from t as of timestamp to_timestamp('2005-1-24 23:26:5', 'yyyy-mm-dd hh24:mi:ss');
已創(chuàng)建 1 行。
SQL> select * from t;
??????? ID NAME
---------- ------------------------------
???????? 1 yangtingkun
?