閃回技術有閃回表、閃回刪除、閃回查詢、閃回事務查詢、閃回事務、閃回數據庫、閃回數據歸檔。其中,閃回查詢、閃回事務查詢用來“觀察”過去;閃回數據歸檔並不是一個獨立的功能,其功能是擴展閃回查詢的時間窗口;閃回表、閃回刪表能夠以表為單位“回到”過去;閃回事務能夠以事務為單位“回到”過去;閃回數據庫能夠以數據庫為單位“回到”過去。
一、 閃回表(Flashback Table)
閃回表是利用UNDO表空間的撤銷數據,所以能把表閃回到多久之前受到undo_retention,UNDO表空間的數據文件是否啟動自動增長功能,是否設置guarantee等三種因素的影響。
1. 閃回到具體時間
SQL> flashback table scott.emp to timestamp to_timestamp('2014-09-16 04:32:00','yyyy-mm-dd hh24:mi:ss');
2. 閃回到10分鍾之前
SQL> flashback table scott.emp to timestamp(systimestamp-interval '10' minute);
3. 將scott.emp閃回到SCN為1086000的時候
SQL> flashback table scott.emp to scn 1086000;
--關於SCN與時間戳間如何轉換可參看Oracle碎碎念第31條
4. 將scott.emp和scott.dept兩張表同時閃回到SCN為1086000的時候(主要用於有外鍵約束的表)
SQL> flashback table scott.emp,scott.dept to scn 1086000;
使用閃回表注意如下事項:
(1)被閃回的表必須啟用行移動功能
SQL> alter table dept enable row movement;
(2)“FLASHBACK TABLE”命令的執行者必須有“FLASHBACK ANY TABLE”系統權限或者在被閃回的表上具有“FLASHBACK”對象權限。
(3)“FLASHBACK TABLE”屬於DDL命令,隱式提交。
(4)SYS用戶的任何表無法使用此功能。
二、 閃回刪表(Flashback Drop)
閃回刪表指的是撤銷“DROP TABLE”的效果。
1. 閃回被刪掉的scott.emp表
SQL> flashback table scott.emp to before drop;
2. 表被刪掉后,又新建了一個同名表,如果試圖用上述命令閃回原表,則會報ORA-38312: original name is used by an existing object錯誤,可重新命名。
SQL> flashback table test to before drop rename to test1;
3. 如果表名重復,則閃回時遵循后入先出的原則。
4. 閃回時可指明被恢復的回收站對象
SQL> flashback table "BIN$AyId7ZbBjWngUKjADQIIuA==$0" to before drop;
閃回刪表的工作原理是:當“drop table”命令執行時,表及其索引並沒有被真正刪除,其所占空間只是分配給了另一個數據庫對象:回收站對象,本質上相當於重命名。注意:表空間在自動增長的壓力下會按照先入先出的規則將回收站對象的空間分配給需要空間的段,在將回收站對象耗盡之前數據文件是不會自動增長的。
5. 可禁用回收站功能
SQL> alter system set recyclebin='OFF' scope=spfile;
6. 刪除當前用戶回收站的所有對象
SQL> purge recyclebin;
三、 閃回查詢(Flashback Query)
以表為單位查詢過去的數據稱為閃回查詢,主要有兩種方式:1. 閃回時間點查詢。利用select命令的“as of”子句與PL/SQL包dbms_flashback在過去的一個時間點上的查詢。2. 閃回版本查詢。利用select命令的“versions between”子句在過去的一段時間范圍內的查詢。
閃回時間點查詢
利用“as of”子句
1. 查詢7788號員工在具體時間的工資
SQL> select sal from emp as of timestamp to_timestamp('2014-09-16 10:02:30','yyyy-mm-dd,hh24:mi:ss') where empno=7788;
2. 查詢7788號員工在五分鍾前的工資
SQL> select sal from emp as of timestamp (systimestamp - interval '5' minute) where empno=7788;
3. 查詢具體SCN
SQL> select * from emp as of scn 1095000;
4. 將7788號員工的工資修改為15分鍾之前的值
SQL> update emp set sal=(select sal from emp as of timestamp(systimestamp - interval '15' minute) where empno=7888) where empno=7788;
利用dbms_flashback包
利用dbms_flashback包的enable_at_time或enable_at_scn存儲過程鎖定一個會話級別的閃回時間目標,即進入閃回模式,隨后的查詢命令可以省略“as of”,直到調用dbms_flashback_disable存儲過程將其關閉為止。
比如,將閃回模式會話定格在15分鍾前:
SQL> exec dbms_flashback.enable_at_time(systimestamp - interval '15' minute);
現在進行查詢,注意,此時查詢的是15分鍾之前的表。
SQL> select sal from emp where empno=7788; --忽略了“as of”子句
此時若訪問SYSDATE、SYSTIMESTAMP等日期函數,它們的返回值仍是當前值,而不是15分鍾之前的值。
處於閃回會話模式時,執行dml和ddl將報錯
SQL> update emp set sal=4000 where empno=7788;
update emp set sal=4000 where empno=7788
*
ERROR at line 1:
ORA-08182: operation not supported while in Flashback mode
如果查詢完畢,可調用disable存儲過程關閉閃回會話模式。
SQL> exec dbms_flashback.disable;
閃回版本查詢
閃回版本查詢可以貫穿一定長度的時間窗口,通過只使用一條查詢命令就能返回該時間窗口內不同時間點上的數據。
比如,首先通過3個事務將7788號員工的工資進行修改。其值原來是4000,然后是5000,然后是10000,最后是3000.
SQL> select sal from emp where empno=7788; SAL ---------- 4000 SQL> update emp set sal=5000 where empno=7788; 1 row updated. SQL> commit; Commit complete. SQL> update emp set sal=10000 where empno=7788; 1 row updated. SQL> commit; Commit complete. SQL> update emp set sal=3000 where empno=7788; 1 row updated. SQL> commit; Commit complete.
執行閃回版本查詢
SQL> select empno,sal from emp 2 versions between timestamp(systimestamp -interval '15' minute) and maxvalue 3 where empno=7788; EMPNO SAL ----- ---------- 7788 3000 7788 10000 7788 5000 7788 4000
通過“versions between”,我們可以看到在15分鍾之內,7788號員工的工資用4個值,說明共有3個事務對其進行過修改。為了能看清這些事務的先后順序,可以在查詢列表中使用偽字段。如下所示:
SQL> select 2 versions_xid,versions_startscn,versions_endscn, 3 empno,sal 4 from emp 5 versions between timestamp(systimestamp - interval '15' minute) and maxvalue 6 where empno=7788 7 order by 2 nulls first; VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN EMPNO SAL ---------------- ----------------- --------------- ----- ---------- 060002000F030000 1097139 7788 4000 02001100FB020000 1097139 1097148 7788 5000 03001D001E030000 1097148 1097153 7788 10000 0900170000030000 1097153 7788 3000
其中,versions_xid為事務號versions_startscn和versions_endscn分別是事務開始時的SCN和修改該行的下一個事務開始時的SCN。首尾銜接這兩個字段的SCN號很容易得出真實的修改順序:4000,5000,10000,最后是3000.
基於《臨危不懼:Oracle 11g數據庫恢復技術》整理