使用閃回挽救咱們的數據

咱們在開發和運維過程當中,常常遇到數據被誤刪除的狀況。不管是在應用開發中的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相對應。所謂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: 未找到基於指定時間的快照

相關文章
相關標籤/搜索