咱們在開發和運維過程當中,常常遇到數據被誤刪除的狀況。不管是在應用開發中的Bug,仍是修改數據的時候,若是提交了錯誤數據修改結果,會帶來不少問題。通常來講,一旦提交Commit事務,咱們是不能獲取到以前的數據狀況,除非使用較複雜的數據恢復手段,利用備份數據恢復。數據庫
可是在Oracle中,可使用其閃回FlashBack特性來解決這個問題。首先,聲明一點,閃回Flashback的範圍很大,包括數據庫、表、數據均是能夠Flashback的,可是機制差異很大。本文說的是簡單的數據flashback,用來快速的挽救回咱們的數據。運維
首先構建實驗環境,和版本信息。spa
SQL> select * from v$version;進程
BANNER事務
--------------------------------------------------------------------------------開發
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Productionget
PL/SQL Release 11.2.0.1.0 - Productionstring
CORE 11.2.0.1.0 Productionflash
TNS for Linux: Version 11.2.0.1.0 - Productionit
NLSRTL Version 11.2.0.1.0 – Production
構建一張簡單的數據表,定位時間信息。
SQL> create table t as select owner,object_id,object_name from dba_objects where rownum<3;
Table created
SQL> select sysdate from dual;
SYSDATE
-----------
2011-1-12 8
SQL> select * from t;
OWNER OBJECT_ID OBJECT_NAME
------------------------------ ---------- --------------------------------------------------------------------------------
SYS 20 ICOL$
SYS 46 I_USER1
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YYYY-MM-DDHH2
------------------------------
2011-01-12 08:23:59 //注意這個時間點。
若是咱們此時誤刪除了數據,而且將刪除結果提交。
SQL> delete t;
2 rows deleted
SQL> commit;
Commit complete
SQL> select count(*) from t;
COUNT(*)
----------
0
這時,雖然咱們已經commit了刪除事務,可是仍能夠指定一個時間點,獲取到那個時間點的數據。
SQL> select * from t as of timestamp to_timestamp('2011-01-12 08:23:59','yyyy-mm-dd hh24:mi:ss');
OWNER OBJECT_ID OBJECT_NAME
------------------------------ ---------- --------------------------------------------------------------------------------
SYS 20 ICOL$
SYS 46 I_USER1
刪除的數據集合又能夠查詢到。這樣恢復數據的思路有了,能夠將結果集合直接插入回數據表。
SQL> insert into t select * from t as of timestamp to_timestamp('2011-01-12 08:23:59','yyyy-mm-dd hh24:mi:ss');
2 rows inserted
SQL> commit;
Commit complete
SQL> select * from t;
OWNER OBJECT_ID OBJECT_NAME
------------------------------ ---------- --------------------------------------------------------------------------------
SYS 20 ICOL$
SYS 46 I_USER1
數據恢復了,利用的是閃回特性。
結論:Oracle在進行處理的時候,對過去提交過的數據,是保存過一個鏡像的,而且與一個SCN相對應。所謂SCN(System Commit Number),就至關於Oracle系統中的時鐘,每次進程會話commit一次,至關於推動一次scn值。相對於時鐘,SCN對Oracle數據庫相當重要。
對數據,Oracle是能夠保存多個版本的。每一個版本是和對應的SCN相關聯。咱們利用閃回,能夠必定程度的查找回過去一個時間SCN的數據版本。而SCN是一個絕對整數,如:
// Oracle 9i以上版本中,獲取到當前系統SCN的方法;
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
1169694
閃回標準的作法應爲:
SQL> select * from t as of scn 1169694;
可是這樣作,存在不方便的問題。咱們就須要不斷的試算合適的SCN取值,相對而言,時間日期較容易理解。使用as of timestamp更加容易。
所謂「No free lunch」,使用閃回是受到一些限制的。
受到系統參數的限制。閃回是一個系統配置,須要系統參數的支持。
//Undo相關的參數
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
在自動管理Undo的狀況下,undo_retention表示支持閃回的秒數,默認爲15分鐘。可是,要注意,這只是一個近似值,實際上要根據系統繁忙程度和其餘不少因素來決定閃回的時間。實際上,若是超過了閃回15分鐘,能夠得到結果。
若是閃回的時間過長,保存的SCN版本已經消失,系統會報錯。
SQL> select * from emp as of timestamp to_timestamp('2008-01-12 08:23:59','yyyy-mm-dd hh24:mi:ss');
select * from emp as of timestamp to_timestamp('2008-01-12 08:23:59','yyyy-mm-dd hh24:mi:ss')
ORA-08180: 未找到基於指定時間的快照