使用閃回挽救我們的資料

szjxlyj發表於2015-01-23

 

我們在開發和運維過程中,經常遇到資料被誤刪除的情況。無論是在應用開發中的Bug,還是修改資料的時候,如果提交了錯誤資料修改結果,會帶來很多問題。一般來說,一旦提交Commit事務,我們是不能獲取到之前的資料情況,除非使用較複雜的資料恢復手段,利用備份資料恢復。

 

但是在Oracle中,可以使用其閃回FlashBack特性來解決這個問題。首先,宣告一點,閃回Flashback的範圍很大,包括資料庫、表、資料均是可以Flashback的,但是機制差別很大。本文說的是簡單的資料flashback,用來快速的挽救回我們的資料。

 

首先構建實驗環境,和版本資訊。

 

 

SQL> select * from v$version;

 

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE     11.2.0.1.0       Production

 

TNS for Linux: Version 11.2.0.1.0 - Production

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相對應。所謂SCNSystem Commit Number),就相當於Oracle系統中的時鐘,每次程式會話commit一次,相當於推進一次scn值。相對於時鐘,SCNOracle資料庫至關重要。

 

對資料,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: 未找到基於指定時間的快照

 

 

 

 

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

相關文章