oracle10G新特性之閃回特性
事務:是作為邏輯單元的SQL DML語句的集合
撤消表空間作用:邏輯事務的復原,讀一緻性,各種資料庫恢複操作及閃回功能
復原:當DML指令對表進行改動時,DML指令改變的舊資料值記錄在撤消表空間中,當復原整個事務時,沒有存儲點的事務,oracle就會使用
撤消記錄來撤消從事務開始以來DML指令進行的所有改動,釋放受影響行上的鎖,并且結束事務,當復原到指定的存儲點為止的部分事務,則
oracle會撤消存儲點後DML指令進行的所有改動。所有随後的存儲點都會丢失,釋放在存儲點後獲得的所有鎖,并且事務保持活動
讀一緻性:如果一個使用者正在讀取涉及另一個使用者的DML事務中的記錄,那麼撤消為這些使用者提供了讀一緻性,就是說所有正在讀取受影響行
的使用者将不會看到行中的任何改動,即讀取的還是撤消表空間中的舊資料庫記錄,直到他們在DML使用者送出事務(commit)後發出一個新的
查詢,這樣才會查取DML操作後的新資料。
資料庫恢複:聯機重做日志将送出和未送出的事務帶入到執行個體崩潰的時間點,撤消資料用于復原在崩潰或執行個體失敗時沒有送出的任何事務。
閃回操作:flashback table,flashback query,DBMS_FLASHBACK。
UNDO_RETENTION:指定為查詢保留撤消資訊的最小時間量,預設為900秒
撤消表空間中有3種類型的撤消資料:活動的或未到期的、到期的、未使用的
活動的或未到期的撤消資料是指讀一緻性仍然需要的撤消資料,即使在事務已經執行以後。
到期的撤消資料是指一旦需要活動撤消資料的所有查詢已經完成,并達到撤消保留周期,活動的撤消資料就變成了到期的撤消資料。
未使用的撤消資料是指撤消表空間中從來沒有使用過的空間。是以撤消表空間的最小大小是儲存所有未送出或未復原事務中所有資料的前像
版本所需要的空間。
撤消表空間過少導緻查詢失敗的查詢方法:
select to_char(end_time,'yyyy-mm-dd hh24:mi') end_time,undoblks,ssolderrcnt from v$undostat where ssolderrcnt <> 0;
ssolderrcnt:表明有多少查詢失敗并顯示snapshot too old錯誤。
根據經驗,可以使用下面公式來計算撤消表空間所需要的大小:
undo_tablespace_size=UR*UPS+overhead
UR等同于以秒為機關的撤消保留,通過undo_retention獲得
UPS 等同于每秒使用的撤消塊最大值:如資料庫塊為8K,每秒生成500個撤消塊,則ups=500*8192
overhead等同于撤消中繼資料,通常是相對于整個大小的非常小的數量,可以忽略。
算出undo_tablespace_size後一般會增加10-20%,在10G中可以通過撤消顧問(undo advisor)來确定撤消表空間的使用率是最好的。
撤消表空間的動态性能視圖:
dba_tablespaces 主要給出表空間名及其特征,如:TEMP表空間名,類型是temporary
dba_undo_extents 主要給出資料庫中所有撤消段的大小,盤區,駐留的表空間及目前狀态(未過期/過期)
v$undostat 主要給出10分鐘間隔内資料庫的撤消利用的數量,包含最多1008行(7天的資料)
v$rollstat 復原段統計,包括大小和狀态
v$transaction 包含執行個體的每個活動事務的一行
撤消保留保證(retention guarantee):一般是在表空間級别上的,并且可以任意時刻改動,設定撤消保留保證可確定表空間中未到期的
撤消被保留,即意味着DML事務可能沒有足夠的撤消表空間來成功完成。預設是noguarantee.可以更改為guarantee,如:
alter tablespace undotbs1 retention guarantee;
撤消表空間的支援的閃回特性:flashback query,flashback table,flashback version query,flashback transaction query。
flashback database,flashback drop.其中flashback database是使用閃回恢複區域中的閃回日志而不是撤消表空間中的撤消資料。
可以允許其他使用者對别人的表進行flashback操作,隻需要給該使用者flashback權限,如:
grant flashback on hr.departments to scott;
flashback query:
從oracle9i2開始可以在select查詢中使用as of子句檢索在給定時間戳或SCN時表的狀态。假如不小心一個小時前删除了兩條記錄,如:
delete from employees where employee_id in (195,186);
commit;
要恢複這兩條記錄,可以使用時間戳和flashback query來檢索删除的行,如:
insert into employees_archive select * from employees as of timestamp systimestamp - interval '60' minute where
employees.employee_id not in (select employee_id from employees);
commit;
然後再插入到employees表:
insert into employees select * from employees_archive;
commit;
與使用時間戳相比,更可取的方法是使用SCN用于閃回,SCN非常精确,而時間戳值隻是每5分鐘存儲一次以支援閃回操作。
當然可以使用flashback table來恢複整個表,這樣更快,但不清楚删除的是哪幾行。
當然也可以使用CTAS(不适合的恢複)進行恢複,如:
create table employees_del as select * from employees as of timestamp systimestamp - interval '60' minute where
employees.employee_id not in (select employee_id from employees);
然後再插入到employees表:
insert into employees select * from employees_del;
commit;
dbms_flashback:
其實是實作flashback query的另一種方法,與flashback query的關鍵差別是:flashback query是對象級别上的操作,而dbms_flashback是
在會話級别上的操作。從特定的時間戳或SCN啟用dbms_flashback後,資料庫就如同回到了特定的時間戳或SCN的狀态,直到禁用
dbms_flashback,這樣就不允許有DML操作了(因為資料庫的狀态不是目前狀态了),如果要使用DML操作并更新到目前狀态時間點的資料庫中,
可以在啟用dbms_flashback之前打開遊标。
dbms_flashback可用的過程有:
disable 表示禁用該會話的閃回模式
enable_at_system_change_number 啟用該會話的閃回模式,指定SCN
enable_at_time 啟用該會話的閃回模式,使用最接近于指定的timestamp的SCN
get_system_change_number 傳回目前的SCN
scn_to_timestamp
timestamp_to_scn 轉換oracle timestamp,并且傳回最接近timestamp值的SCN
execute dbms_flashback.enable_at_time(to_timestamp(sysdate - interval '45' minute));
為了確定dbms_flashback啟動後能進行DML操作,需要建立遊标,需要建立匿名塊,在此不在叙述。
flashback table:
為了在一個表或多個表上使用flashback table,必須在執行閃回操作之前在表上啟用行移動(如果應用程式是基于rowid的,則不要使用
行移動),執行恢複操作如下:
flashback table employees to timestamp systimestamp - interval '60' minute;
如果是多表恢複的話,可以使用
flashback table employees,departments to timestamp systimestamp - interval '60' minute;
flashback version query:
是傳回兩個SCN或時間戳之間給定行的完整曆史記錄。在此不做詳細說明
當不小心使用了drop table employees cascade constraints;在10G以後,drop的表并沒有完全消失,它的塊仍就保持在其表空間中,并占用
空間,可以通過recyclebin(user_recyclebin)資料字典視圖來檢視删除的對象,可以通過如下指令從資源回收筒中恢複該表
flashback table employees to before drop;需要注意的是不能恢複該表引用的限制.如果對drop掉的表進行清除,可以使用purge指令
來删除所有在recycle中的被删除的對象.
閃回查詢可以将查詢結果儲存在一個分離的表中也可以根據閃回查詢的結果來更新表中的行.
比如在update時因未加where條件,更新了所有的資料,如:
update employees set empname='wang';
commit;
這樣整個表都出現了錯誤資料,如果要恢複該表到以前的資料,我們可以做如下操作:
1、确定目前的SCN号
execute dbms_flashback.get_system_change_number 得到目前的SCN号,如結果為:71220
2、允許該表可以進行行移動
alter table employees enable row movement;
3、閃回到以前的一個SCN
flashback table employees to scn(71000)
flashback database指令
該指令将資料庫傳回到一個過去的時間戳或SCN,提供一種執行不完整的恢複,在使用該操作時,必須使用alter database open resetlogs
指令再次打開它,必須擁有sysdba系統權限,以便使用flashback database指令。
flashback database指令的文法如下:
flashback [standby] database [database]
{to {scn | timestamp} expr |to before {scn |timestamp} expr }
如果不使用時間戳或SCN的話,可以使用如下指令進行閃回
startup mount exclusive;
alter database archivelog;
alter database flashback on;
alter database open;
其中有兩個初始化參數來控制保留在資料庫中的閃回資料的數量。
db_flashback_retention_target 設定閃回資料庫的時間程度設定上限(機關是分鐘)
db_recovery_file_dest 設定flash recovery area的大小,用于控制儲存閃回日志的總大小
注意點:flashback table 使用已經存在撤消表空間中的資料,flashback database依賴于flash recovery area中的閃回日志
可以通過v$flashback_database_log來确定可以閃回資料庫的程度。可以通過v$database來檢視閃回的狀态
如果通過時間戳來進行恢複,可以使用如下指令
startup mount exclusive;
flashback database to timestamp sysdate-1/24; 恢複一小時之前的資料庫
一旦完成閃回,必須使用alter database open resetlogs;來進行打開,如果為了關閉閃回資料庫選項,需要執行以下指令:
startup mount exclusive;
alter database flashback off;
alter database open;