Flashback 技術是以Undo segment中的內容為基礎的, 因此受限于UNDO_RETENTON參數。要使用flashback 的特性,必須啟用自動撤銷管理表空間。
在Oracle 10g中, Flash back家族分為以下成員: Flashback Database, Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query, Flashback Transaction Query 三種) 和Flashback Table。
一. Flashback Database
Flashback Database 功能非常類似與RMAN的不完全恢復, 它可以把整個數據庫回退到過去的某個時點的狀態, 這個功能依賴于Flashback log 日志。 比RMAN更快速和高效。 因此Flashback Database 可以看作是不完全恢復的替代技術。 但它也有某些限制:
1. Flashback Database 不能解決Media Failure, 這種錯誤RMAN恢復仍是唯一選擇
2. 如果刪除了數據文件或者利用Shrink技術縮小數據文件大小,這時不能用Flashback Database技術回退到改變之前的狀態,這時候就必須先利用RMAN把刪除之前或者縮小之前的文件備份restore 出來, 然后利用Flashback Database 執行剩下的Flashback Datbase。
3. 如果控制文件是從備份中恢復出來的,或者是重建的控制文件,也不能使用Flashback Database。
4. 使用Flashback Database鎖能恢復到的最早的SCN, 取決與Flashback Log中記錄的最早SCN。
Flashback Database 架構
Flashback Database 整個架構包括一個進程Recover Writer(RVWR)后臺進程,Flashback Database Log日志 和Flash Recovery Area。一旦數據庫啟用了Flashback Database, 則RVWR進程會啟動,該進程會向Flash Recovery Area中寫入Flashback Database Log, 這些日志包括的是數據塊的 " 前鏡像(before image)", 這也是Flashback Database 技術不完全恢復塊的原因。
[oracle@dba ~]$ ps -ef|grep rvw
oracle 12620 12589 0 13:21 pts/1 00:00:00 grep rvw
啟用Flashback Database
數據庫的Flashback Database功能缺省是關閉的,要想啟用這個功能,就需要做如下配置。
1. 配置Flash Recovery Area
要想使用Flashback Database, 必須使用Flash Recovery Area,因為Flashback Database Log只能保存在這里。 要配置的2個參數如下,一個是大小,一個是位置。如果數據庫是RAC,flash recovery area 必須位于共享存儲中。數據庫必須處于archivelog 模式.
啟用Flash Recovery Area:
SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=20G SCOPE=BOTH;
SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='/DBA/FB' SCOPE=BOTH;
禁用Flash Recovery Area:
SQL>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='' ;
對于Flash Recovery Area,Oracle 是這樣建議的,flash recovery area 設置的越大,flashback database 的恢復能力就越強,因此建議flash recovery area 能夠放的下所有的數據文件,增量備份,以及所有尚未備份的歸檔文件,當然還有它自己產生的flashback logs。
在數據庫運行過程中,oracle 自動向該區域寫入文件,當剩余空間不足15%的時候,它就會在alert 中增加警告,提示你空間不足。但此時不會影響數據庫的正常運轉,直到所有空間統統被用掉之后,oracle 首先嘗試刪除尋些過期的文件,冗余文件或備份過的文件,如果這些做完了,還是沒有空閑空間的話,數據庫就被hang 住了。
對于因Flash Recovery Area導致的數據庫hang的處理,請參考:
或者
2. 啟用數據庫Flashback 功能
1). 數據庫啟動到mount狀態
SQL> startup mount;
2). 檢查Flashback 功能, 缺省時功能是關閉的。
SQL> select name, current_scn, flashback_on from v$database;
NAME CURRENT_SCN FLASHBACK_ON
-------- ----------- ------------------
DBA 945715 NO
3). 啟動Flashback功能
SQL> alter database flashback on;
數據庫已更改。
SQL> select name, current_scn, flashback_on from v$database;
NAME CURRENT_SCN FLASHBACK_ON
--------- ----------- ------------------
DBA 0 YES
4). 設置初始化參數:DB_FLASHBACK_RETENTION_TARGET:
SQL>alter system set db_flashback_retention_target=1440 scope=both;
該參數用來控制flashback log 數據保留的時間,或者說,你希望flashback database 能夠恢復的最早的時間點。默認值是1440,單位是minute,即24 小時,需要注意的是該參數雖然未直接指定flash recovery area大小,但卻受其制約,舉個例子假如數據庫每天有10%左右的數據變動的話,如果該初始化參數值設置為1440,則flash recovery area 的大小至少要是當前數據庫實際容量的10%,如果該初始化參數設置為2880,則flash recovery area 的大小就至少是數據庫所占容量的20%。
5). 啟動數據庫
SQL>alter database open;
Flashback Database操作示例
做操作前先備份數據庫
RMAN> backup database;
1. 檢查是否啟動了flash recovery area:
SQL> show parameter db_recovery_file
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest tring D:\oracle/flash_recovery_area
db_recovery_file_dest_size big integer 1G
2. 檢查是否啟用了歸檔
SQL> archive log list;
數據庫日志模式 存檔模式
自動存檔 啟用
存檔終點 USE_DB_RECOVERY_FILE_DEST
最早的聯機日志序列 9
下一個存檔日志序列 11
當前日志序列 11
3. 檢查是否啟用了flashback database
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
4. 查詢當前的scn
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
947921
5. 查詢當前的時間
SQL> select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual;
TIME
-----------------
09-10-14 14:37:05
6. 刪除表A
SQL> select * from A;
ID NAME
---------- ----------
1 tianle
2 dave
SQL> drop table A;
表已刪除。
SQL> commit;
7. Flashback Database 實際是對數據庫的一個不完全恢復操作,因為需要關閉數據庫重啟到mount狀態。
SQL> shutdown immediate
數據庫已經關閉。
已經卸載數據庫。
ORACLE 例程已經關閉。
SQL> startup mount
ORACLE 例程已經啟動。
Total System Global Area 209715200 bytes
Fixed Size 1248116 bytes
Variable Size 79692940 bytes
Database Buffers 121634816 bytes
Redo Buffers 7139328 bytes
數據庫裝載完畢。
8. 執行恢復:分timestamp 或者SCN兩種
SQL> Flashback database to timestamp to_timestamp('09-10-14 14:37:05','yy-mm-dd
hh24:mi:ss');
閃回完成。
或者:
SQL> Flashback database to scn 947921;
閃回完成。
9. 打開數據庫:
在執行完flashback database 命令之后,oracle 提供了兩種方式讓你修復數據庫:
1). 直接alter database open resetlogs 打開數據庫,當然,指定scn 或者timestamp 時間點之后產生的數據統統丟失。
2). 先執行alter database open read only 命令以read-only 模式打開數據庫,然后立刻通過邏輯導出的方式將誤操作涉及表的數據導出,再執行recover database 命令以重新應用數據庫產生的redo,將數據庫修復到flashback database 操作前的狀態,然后再通過邏輯導入的方式,將之前誤操作的表重新導入,這樣的話對現有數據的影響最小,不會有數據丟失。
這里演示,就以resetlogs方式打開:
SQL> alter database open resetlogs;
數據庫已更改。
驗證數據:
SQL> select * from A;
ID NAME
---------- ----------
1 tianle
2 dave
和Flashback Database 相關的2個視圖:
1. V$database
這個視圖可以查看是否啟用了Flashback database功能
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
2. V$flashback_database_log
Flashback Database 所能回退到的最早時間,取決與保留的Flashback Database Log 的多少, 該視圖就可以查看許多有用的信息。
Oldest_flashback_scn / Oldest_flashback_time : 這兩列用來記錄可以恢復到最早的時點
Flashback_size: 記錄了當前使用的Flash Recovery Area 空間的大小
Retention_target: 系統定義的策略
Estimated_flashback_size: 根據策略對需要的空間大小的估計值
SQL> select oldest_flashback_scn os, to_char(oldest_flashback_time,'yy-mm-dd hh2
4:mi:ss') ot, retention_target rt,flashback_size fs, estimated_flashback_size es
from v$flashback_database_log;
OS OT RT FS ES
---------- ----------------- ---------- ---------- ----------
946088 09-10-14 13:49:59 1440 16384000 350920704
3. V$flashback_database_stat
這個視圖用來對Flashback log 空間情況進行更細粒度的記錄和估計。 這個視圖以小時為單位記錄單位時間內數據庫的活動量,Flashback_Data 代表Flashback log產生數量,DB_Date 代表數據改變數量,Redo_Date代表日志數量,通過這3個數量可以反映出數據的活動特點,更準確的預計Flash Recovery Area的空間需求
SQL> alter session set nls_date_format='hh24:mi:ss';
會話已更改。
SQL> select *from v$flashback_database_stat;
BEGIN_TI END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
-------- -------- -------------- ---------- ---------- ------------------------
14:43:10 15:15:28 6455296 29310976 3898368 0
Flashback DROP
Flashback Drop 是從Oracle 10g 開始出現的, 用于恢復用戶誤刪除的對象(包括表,索引等), 這個技術依賴于Tablespace Recycle Bin(表空間回收站),這個功能和windows的回收站非常類似。
Flashback 不支持sys用戶. system表空間下的對象,也不能從回收站里拿到。故使用SYS 或者SYSTEM用戶登陸時, show recyclebin 為空。
1. Tablespace Recycle Bin
從Oracle 10g 開始, 每個表空間都會有一個叫作回收站的邏輯區域,當用戶執行drop命令時, 被刪除的表和表的關聯對象( 包括索引, 約束,觸發器,LOB段,LOB index 段) 不會被物理刪除, 這些對象先轉移到回收站中,這就給用戶提供了一個恢復的可能。
初始化參數recyclebin 用于控制是否啟用recyclebin功能,缺省是ON, 可以使用OFF關閉。
SQL> show parameter recycle
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle string
db_recycle_cache_size big integer 0
recyclebin string on
禁用該功能:
SQL> alter system set recyclebin=off;
SQL> alter system set recyclebin=on;
SQL> alter session set recyclebin=off;
SQL> alter session set recyclebin=on;
禁用后刪除的對象將直接刪除,不會寫到Recycle中,當然在刪除時,指定purge 參數,表也將直接刪除,不會寫到recyclebin中。
SQL> drop table name purge;
查看recyclebin中的對象列表:
SQL> select * from A;
ID
----------
1
2
3
SQL> drop table A;
表已刪除。
SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ----------------------------- ------------ -------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0 TABLE 2009-10-15:12:44:33
查看recyclebin中對象:
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
查看recyblebin對象里的內容:
SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
ID
----------
1
2
3
表空間的Recycle Bin 區域只是一個邏輯區域,而不是從表空間上物理的劃出一塊區域固定用于回收站,因此Recycle Bin是和普通對象共用表空間的存儲區域,或者說是Recycle Bin的對象要和普通對象搶奪存儲空間。當發生空間不夠時,Oracle會按照先入先出的順序覆蓋Recycle Bin中的對象。也可以手動的刪除Recycle Bin占用的空間。
1). Purge tablespace tablespace_name : 用于清空表空間的Recycle Bin
2). Purge tablespace tablespace_name user user_name: 清空指定表空間的Recycle Bin中指定用戶的對象
3). Purge recyclebin: 刪除當前用戶的Recycle Bin中的對象
4). Purge dba_recyclebin: 刪除所有用戶的Recycle Bin中的對象,該命令要sysdba權限
5). Drop table table_name purge: 刪除對象并且不放在Recycle Bin中,即永久的刪除,不能用Flashback恢復。
6). Purge index recycle_bin_object_name: 當想釋放Recycle bin的空間,又想能恢復表時,可以通過釋放該對象的index所占用的空間來緩解空間壓力。 因為索引是可以重建的。
2. Flashback Drop 實例操作
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
A BIN$RWXQQcTPRde0ws4h9ewJcg==$0
SQL> flashback table a to before drop;
閃回完成。
SQL> select * from a;
ID
----------
1
2
3
當我們刪除表A后,在新建表A,這時在恢復的時候就會報錯,此時我們在閃回時,對表重命名就可以了:
SQL> drop table a;
表已刪除。
SQL> create table a
2 (id number(1));
表已創建。
SQL> flashback table a to before drop ;
flashback table a to before drop
*
第 1 行出現錯誤:
ORA-38312: 原始名稱已被現有對象使用
SQL> flashback table a to before drop rename to B;
閃回完成。
SQL> select * from B;
ID
----------
1
2
3
當我們刪除表A,在新建表A,在刪除它,這是在Recycle Bin中就會有2個相同的表明,此時恢復我們就要指定object_name才行.
SQL> select * from B;
ID
----------
1
2
3
SQL> drop table B;
表已刪除。
SQL> create table B(name varchar(20));
表已創建。
SQL> drop table B;
表已刪除。
SQL> select original_name,object_name from recyclebin;
ORIGINAL_NAME OBJECT_NAME
-------------------------------- ------------------------------
B BIN$vYuv+g9fTi2exYP9X2048Q==$0
B BIN$geQ9+NekSjuRvzG+TqDVWw==$0
SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;
閃回完成。
SQL> select * from B;
ID
----------
1
2
3
一旦完成閃回恢復,Recycle Bin中的對象就消失了. Flashback Drop 需要注意的地方:
1). 只能用于非系統表空間和本地管理的表空間
2). 對象的參考約束不會被恢復,指向該對象的外鍵約束需要重建。
3). 對象能否恢復成功,取決與對象空間是否被覆蓋重用。
4). 當刪除表時,信賴于該表的物化視圖也會同時刪除,但是由于物化視圖并不會被放入recycle bin,因此當你執行flashback table to before drop 時,也不能恢復依賴其的物化視圖,需要dba 手工介入重新創建。
5). 對于Recycle Bin中的對象,只支持查詢.
Flashback Query
Flashback 是ORACLE 自9i 就開始提供的一項特性,在9i 中利用oracle 查詢多版本一致的特點,實現從回滾段中讀取表一定時間內操作過的數據,可用來進行數據比對,或者修正意外提交造成的錯誤數據,該項特性也被稱為Flashback Query。
一、Flashback Query
正如前言中所提,Flashback Query 是利用多版本讀一致性的特性從UNDO 表空間讀取操作前的記錄數據!
什么是多版本讀一致性
Oracle 采用了一種非常優秀的設計,通過undo 數據來確保寫不堵塞讀,簡單的講,不同的事務在寫數據時,會將數據的前映像寫入undo 表空間,這樣如果同時有其它事務查詢該表數據,則可以通過undo 表空間中數據的前映像來構造所需的完整記錄集,而不需要等待寫入的事務提交或回滾。
flashback query 有多種方式構建查詢記錄集,記錄集的選擇范圍可以基于時間或基于scn,甚至可以同時查詢出記錄在undo 表空間中不同事務時的前映象。用法與標準查詢非常類似,要通過flashback query 查詢undo 中的撤銷數據,最簡單的方式只需要在標準查詢語句的表名后面跟上as of timestamp(基于時間)或as of scn(基于scn)即可。as of timestamp|scn 的語法是自9iR2 后才開始提供支持。
1、As of timestamp 的示例:
SQL> alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';
會話已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2009-10-15 19:04:16
SQL> select * from A;
ID
----------
2
1
3
4
模擬用戶誤操作,刪除數據
SQL> delete from A;
已刪除4行。
SQL> commit;
提交完成。
SQL> select * from A;
未選定行
查看刪除之前的狀態:
假設當前距離刪除數據已經有5 分鐘左右的話:
SQL> select * from A as of timestamp sysdate-5/1440;
ID
----------
2
1
3
4
或者:
SQL>select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
ID
----------
2
1
3
4
用Flashback Query恢復之前的數據:
SQL>Insert into A select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');
已創建4行。
SQL> COMMIT;
提交完成。
SQL> select * from A;
ID
----------
2
1
3
4
如上述示例中所表示的,as of timestamp 的確非常易用,但是在某些情況下,我們建議使用as of scn 的方式執行flashback query,比如需要對多個相互有主外鍵約束的表進行恢復時,如果使用as of timestamp 的方式,可能會由于時間點不統一的緣故造成數據選擇或插入失敗,通過scn 方式則能夠確保記錄的約束一致性。
2. As of scn 示例
查看SCN:
SELECT dbms_flashback.get_system_change_number FROM dual;
SELECT CURRENT_SCN FROM V$DATABASE;
SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
1095782
刪除數據:
SQL> delete from A;
已刪除4行。
SQL> commit;
提交完成。
查看刪除之前的狀態:
SQL> select * from A as of scn 1095782;
ID
----------
2
1
3
4
用Flashback Query恢復之前的數據:
SQL> insert into A select * from A as of scn 1095782;
已創建4行。
SQL> commit;
提交完成。
SQL> select * from A;
ID
----------
2
1
3
4
事實上,Oracle 在內部都是使用scn,即使你指定的是as of timestamp,oracle 也會將其轉換成scn,系統時間標記與scn 之間存在一張表,即SYS 下的SMON_SCN_TIME
SQL> desc sys.smon_scn_time
名稱 是否為空? 類型
----------------------------------------- -------- ---------------------------
THREAD NUMBER
TIME_MP NUMBER
TIME_DP DATE
SCN_WRP NUMBER
SCN_BAS NUMBER
NUM_MAPPINGS NUMBER
TIM_SCN_MAP RAW(1200)
SCN NUMBER
ORIG_THREAD NUMBER
每隔5 分鐘,系統產生一次系統時間標記與scn 的匹配并存入sys.smon_scn_time 表,該表中記錄了最近1440個系統時間標記與scn 的匹配記錄,由于該表只維護了最近的1440 條記錄,因此如果使用as of timestamp 的方式則只能flashback 最近5 天內的數據(假設系統是在持續不斷運行并無中斷或關機重啟之類操作的話)。
注意理解系統時間標記與scn 的每5 分鐘匹配一次這句話,舉個例子,比如scn:339988,339989 分別匹配08-05-3013: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 這個時刻的數據。
查看SCN 和 timestamp 之間的對應關系:
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;
Flashback version Query
相對于Flashback Query 只能看到某一點的對象狀態, Oracle 10g引入的Flashback Version Query可以看到過去某個時間段內,記錄是如何發生變化的。 根據這個歷史,DBA就可以快速的判斷數據是在什么時點發生了錯誤,進而恢復到之前的狀態。
先看一個偽列 ORA_ROWSCN. 所謂的偽列,就是假的,不存在的數據列,用戶創建表時雖然沒有指定,但是Oracle為了維護而添加的一些內部字段,這些字段可以像普通文件那樣的使用。
最熟悉的偽列就是 ROWID, 它相當于一個指針,指向記錄在磁盤上的位置。ORA_ROWSCN 是Oracle 10g 新增的,暫且把它看作是記錄最后一次被修改時的SCN。 Flashback Version Query 就是通過這個偽列來跟蹤出記錄的變化歷史。
舉個例子:
SQL> select * from A;
ID
----------
2
1
3
4
SQL> insert into A values(5);
已創建 1 行。
SQL> select * from A;
ID
----------
2
1
3
4
5
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from A;
ORA_ROWSCN ID
---------- ----------
1098443 2
1098443 1
1098443 3
1098443 4
1098443 5
獲取更多的歷史信息
SQL>Select versions_xid,versions_startscn,versions_endscn,
DECODE(versions_operation,'I','Insert','U','Update','D','Delete', 'Original') "Operation", id from A versions between scn minvalue and maxvalue;
或者
SQL>select xid,commit_scn,commit_timestamp,operation,undo_sql
from flashback_transaction_query q where q.xid in(select versions_xid from B versions between scn 413946 and 413959);
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio ID
---------------- ----------------- --------------- -------- ----------
05001A0054020000 1099482 Update 3
05001A0054020000 1099482 Delete 3
05001A0054020000 1099482 Delete 2
05001A0054020000 1099482 Delete 1
0400150005020000 1098443 Insert 5
下面我們來講下偽列, Flashback Version Query 技術其實有很多偽列,但是ORA_ROWSCN是最重要。它記錄的是最后一次被修改時的SCN, 注意是被提交的修改。如果沒有提交,這個偽列不會發生變化。
ORA_ROWSCN 缺省是數據塊級別的,也就是一個數據塊內的所有記錄都是一個ORA_ROWSCN,數據塊內任意一條記錄被修改,這個數據庫塊內的所有記錄的ORA_ROWSCN都會同時改變。上例的查詢結果以證明。
不過我們可以在建表時使用關鍵字 rowdependencies, 可以改變這種缺省行為,使用這個關鍵字后,每條記錄都有自己的ORA_ROWSCN。
舉例:
SQL> create table B (id number(2)) rowdependencies;
表已創建。
SQL> insert into B values(1);
已創建 1 行。
SQL> insert into B values(2);
已創建 1 行。
SQL> insert into B values(3);
已創建 1 行。
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100560 1
1100560 2
1100560 3
此處SCN一樣,一定很奇怪,這正好說明是最后一次被修改時的SCN,如果沒有提交,是不會變的,我們重做一下就清楚了。
SQL> analyze table B compute statistics;
表已分析。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100560 1
1100560 2
1100560 3
SQL> delete from B;
已刪除4行。
SQL> select ora_rowscn, id from B;
未選定行
SQL> insert into B values(1);
已創建 1 行。
SQL> commit;
提交完成。
SQL> insert into B values(2);
已創建 1 行。
SQL> commit;
提交完成。
SQL> select ora_rowscn, id from B;
ORA_ROWSCN ID
---------- ----------
1100723 1
1100729 2
Flashback Transaction Query
Flashback Transaction Query也是使用UNDO信息來實現。利用這個功能可以查看某個事務執行的所有變化,它需要訪問flashback_transaction_query 視圖,這個視圖的XID列代表事務ID,利用這個ID可以區分特定事務發生的所有數據變化。
示例:
SQL> insert into B values(3);
已創建 1 行。
SQL> commit;
提交完成。
SQL> select * from B;
ID
----------
1
2
3
查看視圖,每個事務都對應相同的XID
SQL>Select xid,operation,commit_scn,undo_sql from flashback_transaction_query where xid in (
Select versions_xid from B versions between scn minvalue and maxvalue);
或者
SQL>select xid,commit_scn,commit_timestamp,operation,undo_sql
from flashback_transaction_query q where q.xid in(select versions_xid from B versions between scn 413946 and 413959);
XID OPERATION COMMIT_SCN
---------------- -------------------------------- ----------
UNDO_SQL
--------------------------------------------------------------------------------
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('4');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('3');
03001C006A020000 DELETE 1100723
insert into "SYS"."B"("ID") values ('2');
Flashback Table
注意SYS用戶不支持閃回,這點前面已經說明過。
Flashback Table也是使用UNDO tablespace的內容來實現對數據的回退。該命令相對簡單,輸入:flashback table table_name to scn(to timestamp) 即可。
注意:如果想要對表進行flashback,必須允許表的row movement.
Alter table table_name row movement;
要查看某表是否啟用row movement,可以到user_tables 中查詢(或all_tables,dba_tables),
例如:
SQL> select row_movement from user_tables where table_name='C';
ROW_MOVE
--------
ENABLED
要啟用或禁止某表row movement,可以通過下列語句:
--啟用
JSSWEB> ALTER TABLE table_name ENABLE ROW MOVEMENT;
表已更改。
--禁止
JSSWEB> ALTER TABLE table_name DISABLE ROW MOVEMENT;
表已更改。
舉例:
SQL> create table C (id number(2));
表已創建。
SQL> insert into C values(1);
已創建 1 行。
SQL> insert into C values(2);
已創建 1 行。
SQL> commit;
提交完成。
SQL> select * from c;
ID
----------
1
2
SQL> alter session set nls_date_format="yyyy-mm-dd hh24:mi:ss";
會話已更改。
SQL> select sysdate from dual;
SYSDATE
-------------------
2009-10-15 21:17:47
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
1103864
刪除數據并恢復
SQL> delete from C;
已刪除2行。
SQL> commit;
提交完成。
SQL> alter table c enable row movement;
表已更改。
SQL> flashback table c to scn 1103864;
閃回完成。
或者:
SQL> flashback table c to timestamp to_timestamp('2009-10-15 21:17:47','yyyy-mm-
dd hh24:mi:ss');
SQL> select * from c;
ID
----------
1
2
Flashback table 命令支持同時操作多個表,表名中間以逗號分隔即可,如果你執行一條flashback table命令時同時指定了多個表,要記住單個flashback table 是在同一個事務中,因此這些表的恢復操作要么都成功,要么都失敗。
如:
flashback table a,b ,c to scn 1103864;
一些注意事項
1. 基于undo 的表恢復,需要注意DDL 操作的影響
第三個就是修改并提交過數據之后,對表做過DDL 操作,包括:
drop/modify 列, move 表, drop 分區(如果有的話), truncate table/partition,這些操作會另undo 表空間中的撤銷數據失效,對于執行過這些操作的表應用flashback query 會觸發ORA-01466 錯誤。另外一些表結構修改語句雖然并不會影響到undo 表空間中的撤銷記錄,但有可能因表結構修改導致undo 中重做記錄無法應用的情況,比如對于增加了約束,而flashback query 查詢出的undo 記錄已經不符合新建的約束條件,這個時候直接恢復顯然不可能成功,你要么暫時disable 約束,要么通過適當邏輯,對要恢復的數據進行處理之后,再執行恢復。
另外,flashback query 對v$tables,x$tables 等動態性能視圖無效,不過對于dba_*,all_*,user_*等數據字典是有效的。同時該特性也完全支持訪問遠端數據庫,比如select * from
tbl@dblink as of scn 360;的形式。
2. 基于undo 的表恢復,flashback table 實際上做的也是dml 操作(會在被操作的表上加dml 鎖),因此還需要注意triggers 對其的影響,默認情況下,flashback table to scn/timestamp 在執行時會自動disable 掉與其操作表相差的triggers,如果你希望在此期間trigger 能夠繼續發揮做用,可以在flashback table 后附加
ENABLE TRIGGERS 子句。
補充:
什么是Automatic Undo Management( 自動撤銷管理表空間)
提到自動撤銷管理表空間,就不得不提手動管理的回滾段。在9i 之前,回滾段的管理和監控是需要dba手工介入的,創建合適的回滾段是件非常耗費dba 精力的事情,你可能需要不斷關注oracle 運行狀況很長一陣子時間后,通過不斷的調整才能基本確認一段時期內回滾段的大小,一旦回滾段創建的不合適,就極有可能引起性能問題甚至錯誤,比如ora-1555 就是典型的回滾段設置不合適觸發的。
9i 之后呢(含9i),oracle 為了清晰它的整個概念,取消了回滾段這個說法(實際上并未取消回滾段),而完全以undo 來代替,這也它正好與redo 相對應,一個重做,一個撤銷?;貪L段可以不再由dba 手工介入,而是完全由它自己在運行時自動分配,這在一定程度上即解放了dba,也確實起到了提高性能的作用,比如采用自動管理表空間就可以最大程序的降低ora-1555發生的機率(注意是降低,不是避免,我們不可能創建一個無限大的回滾段,ora-1555 也并不完全是回滾段造成的,關于ora-1555 的問題這里就不深入討論了,互聯網上已經有太多文章描述和介紹該問題及解決方案)
是否起用自動管理的撤銷表空間由二個初始化參數決定:
UNDO_MANAGEMENT:值為AUTO 表示使用了自動撤銷管理表空間,MANUAL 則表示手動管理
UNDO_TABLESPACE:當UNDO_MANAGEMENT 值為AUTO 時,該參數用來指定當前的undo 表空間名稱。
undo 表空間的大小,直接影響到flashback query 的查詢能力,因為多版本查詢所依賴的undo 數據都存儲在undo 表空間中,該表空間越大,所能夠存儲的undo 數據自然也越多,如果該表空間可用空間非常小,別說flashback 了,恐怕正常查詢都有可能觸發ora-1555 吧。
初始化參數UNDO_RETENTION
該參數用來指定undo 記錄保存的最長時間,以秒為單位,是個動態參數,完全可以在實例運行時隨時修改通常默認是900 秒,也就是15 分鐘。
一定要注意,undo_retention 只是指定undo 數據的過期時間,并不是說,undo 中的數據一定會在undo表空間中保存15 分鐘,比如說剛一個新事務開始的時候,如果undo 表空間已經被寫滿,則新事務的數據會自動覆蓋已提交事務的數據,而不管這些數據是否已過期,因此呢,這就又關聯回了第一點,當你創建
一個自動管理的undo 表空間時,還要注意其空間大小,要盡可能保證undo 表空間有足夠的存儲空間。
同時還要注意,也并不是說,undo_retention 中指定的時間一過,已經提交事務中的數據就立刻無法訪問,它只是失效,只要不被別的事務覆蓋,它會仍然存在,并可隨時被flashback 特性引用。如果你的undo表空間足夠大,而數據庫又不是那么繁忙,那么其實undo_retention 參數的值并不會影響到你,哪怕你設置成1,只要沒有事務去覆蓋undo 數據,它就會持續有效。因此呢,這里還是那句話,要注意undo 表空間的大小,保證其有足夠的存儲空間。
只有在一種情況下,undo 表空間能夠確保undo 中的數據在undo_retention 指定時間過期前一定有效,就是為undo 表空間指定Retention Guarantee,指定之后,oracle 對于undo 表空間中未過期的undo 數據不會覆蓋,
例如:
SQL> Alter tablespace undotbs1 retention guarantee;
如果想禁止undo 表空間retention guarantee,
例如:
SQL> Alter tablespace undotbs1 retention noguarantee;
本文轉載于:
http://blog.csdn.net/tianlesoftware/archive/2009/10/16/4677378.aspx