oracle flashback特性學習總結

balkline發表於2011-04-13

1、閃回查詢之As of timestamp 2、閃回查詢之As of scn

3、閃回查詢之Versions between 4、閃回查詢之Transaction query

5、閃回查詢之制約因素

[@more@]
實驗部分:
(1)、基於時間的方法
SQL>
1 create table flashtable(id,name) as
2* select rownum,name from(select substr(object_name,1,1) name from dba_objects group by substr(object_name,1,1) order by 1)
SQL> select * from tab;
TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
FLASHTABLE TABLE
SQL> select * from flashtable;
.............
.............
49 rows selected.
SQL> select * from flashtable where id<5;
ID N
---------- -
1 /
2 A
3 B
4 C
SQL> delete from flashtable where id<5;
4 rows deleted.
SQL> select * from flashtable where id<5;
no rows selected

此時表中id<5的記錄均已被刪除,假設過了一會兒你發現刪除操作執行有誤,仍需找回那些被誤刪的記錄該怎麼辦呢?使用備份恢復?如果是在8i,恐怕是需要這樣,自9i之後,使用flashback query的特性,我們可以很輕鬆的恢復記錄(注意並不是任何情況下都可以恢復喲,後面會講到制約flashback query的一些因素,我們這裡舉的都是理想條件下的例子),假設當前距離刪除資料已經有2分鐘左右的話:

SQL> select * from flashtable as of timestamp sysdate-2/1440;

返回的記錄數則是刪除前的資料,仍是49行記錄

49 rows selected.

SQL> insert into flashtable select * from flashtable as of timestamp sysdate-2/1440;

as of timestamp|scn的語法是自9iR2後才開始提供支援,如果是9iR1版本,需要使用DBMS_FLASHBACK包來應用flashback query的特性。如上述示例中所表示的,as of timestamp的確非常易用,但是在某些情況下,我們建議使用as of scn的方式執行flashback query,比如需要對多個相互有主外來鍵約束的表進行恢復時,如果使用as of timestamp的方式,可能會由於時間點不統一的緣故造成資料選擇或插入失敗,透過scn方式則能夠確保記錄的約束一致性。

或者:select * from fp_nsrjc as of timestamp (systimestamp-interval'10'hour);此語句也可以.

(2)、基於scn的方法

既然是基於scn的查詢,我們首先就需要得到scn,這裡我們透過dbms_flashback.get_system_change_number函式來獲取當前的scn,之後再執行資料的修改操作。

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER

------------------------

904007

SQL> delete from flashtable where id>=40;

10 rows deleted.

SQL> select * from flashtable as of scn 904007;

SQL> insert into flashtable select * from flashtable as of scn 904007 where id not in (select id from flashtable);

10 rows created.

事實上,Oracle在內部都是使用scn,即使你指定的是as of timestamp,oracle也會將其轉換成scn,系統時間標記與scn之間存在一張表,即SYS下的SMON_SCN_TIME

SQL> desc sys.smon_scn_time;

每隔5分鐘,系統產生一次系統時間標記與scn的匹配並存入sys.smon_scn_time表,該表中記錄了最近1440個系統時間標記與scn的匹配記錄,由於該表只維護了最近的1440條記錄,因此如果使用as of timestamp的方式則只能最近5天內的資料(假設系統是在持續不斷執行並無中斷或關機重啟之類操作的話)。注意理解系統時間標記與scn的每5分鐘匹配一次這句話,舉個例子,比如scn:339988,339989分別匹配08-05-30 13:52:00和2008-13:57:00,則當你透過as of timestamp查詢08-05-30 13:52:00或08-05-30 13:56:59這段時間點內的時間時,oracle都會將其匹配為scn:339988到undo表空間中查詢,也就說在這個時間內,不管你指定的時間點是什麼,查詢返回的都將是08-05-30 13:52:00這個時刻的資料。

當然,具體的情況,我想你親自執行一下select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss') from sys.smon_scn_time,會理解的更深刻一些。

(3)、versions beween

版本查詢的用法並不比as of複雜,與其類似,你只需要在標準查詢後面附加versions between timestamp[/scn] t1 and t2即可。記錄在版本查詢中可能會是一對多的關係,比如某些記錄如果被修改過多次,並分別提交,那麼你在查詢的時候,如果修改的操作是在你指定的時間段(或scn),則記錄每次修改的結果都會被選擇出來,這比較有利於我們做資料的對比,比如看看資料究竟是怎麼變化的。

VERSIONS_STARTSCN
VERSIONS_STARTTIME

該記錄失效時的scn或時間,如果為空,說明記錄當前時間在當前表記憶體在,或者已經被刪除了,可以配合著VERSIONS_OPERATION列來看,如果VERSIONS_OPERATION列值為D,說明該列已被刪除,如果該列為空,則說明記錄在這段時間無操作

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER

------------------------

905676

SQL> update flashtable set id=id+100 where id<=5;

5 rows updated.

SQL> insert into flashtable values(101,'a');

1 row created.

SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER

------------------------

905796

SQL> select id,name,versions_startscn,versions_endscn,versions_operation from flashtable versions between scn 905676 and 905796 order by 2;

根據這個結果返回我們首先來看id<5的記錄,每個記錄各有兩個版本,一行的VERSIONS_VERSIONS_ENDSCN有值,記錄了該版本失效時的scn。

另有5行id>100 and id<200的,從VERSIONS_OPERATION列可以看出操作是update,這是我們手工執行update set的結果

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25682487/viewspace-1048596/,如需轉載,請註明出處,否則將追究法律責任。