oracke閃回技術總結

chenoracle發表於2014-09-04

oracle 閃回功能


為了使Oracle資料庫從任何邏輯誤操作中迅速地恢復,Oracle推出了閃回技術。該技術首先以 閃回查詢 (Flashback Query)出現在 Oracle 9i版本中,後來Oracle在 10g中對該技術進行了全面擴充套件,提供了 閃回資料庫閃回刪除閃回表閃回事物閃回版本查詢等功能,在 11g 中,Oracle繼續對該技術進行改進和增強,增加了 閃回資料歸檔功能。


在Oracle 11g中,閃回技術包括以下各項。


  1 閃回資料庫(Flashback Database):該特性允許使用者透過flashback database語句,使資料庫迅速地回滾到以前的某個時間點或者某個SCN(系統更改號)上,而不需要進行時間點的恢復操作。該功能不基於撤銷資料(undodata),而是基於閃回日誌。


   2 閃回丟棄(Flashback Drop):類似於作業系統的垃圾回收站功能,可以從中恢復被drop的表或者索引。該功能基於撤銷資料(undodata)。


    3 閃回版本查詢(Flashback Version Query):透過該功能,可以看到特定的表在某個時間段內所進行的任何修改操作,如同電影回放一樣,表在該時間段內的變化一覽無餘。該功能基於撤銷資料(undodata)。


4 閃回事務查詢(Flashback Transaction Query):使用該特性,可以在事物級別上檢查資料庫的任何改變,大大方便了對資料庫的效能最佳化、事務審計及錯誤診斷等操作。該功能基於撤銷資料(undodata)。


   5 閃回表(Flashback Table):使用該特性,可以確保資料庫表能夠被恢復到之前的某一個時間點上。注意,該功能與最早的9i中的Flashback Query不同,Flashback Query僅僅是得到了表在之前某個時間點上的快照而已,並不改變當前表的狀態;而Falshback Table卻能夠將表及附屬物件一起恢復到以前的某個時間點。該功能基於撤銷資料(undodata)。


    6 閃回資料歸檔(Flashback Data Archive):透過flashback data archive,可以查詢指定物件的任何時間點(只要滿足保護策略)的資料,而且不需要利用到undo,這在有審計需要的環境,或者是安全性特別重要的高 可用資料庫中,是一個非常好的特性。缺點就是如果該表變化很頻繁,對空間的要求可能很高。Flashback data archive是針對物件的保護,是flashback database的一個強力補充。

  


所有的閃回技術,除了閃回資料庫,都是基於撤銷資料(undodata)。

   閃回資料庫技術可以替代 不完全恢復,優勢在於閃回資料庫更快效率更高,它是基於 閃回日誌的(所以需要開啟閃回功能alter database flashback on)。


 

1 閃回資料庫(Flashback Database)


閃回資料庫概述

閃回資料庫能夠使資料庫迅速回滾到以前的某個時間點或者某個SCN(系統更改號)上。這對於資料庫從邏輯錯誤中恢復特別有用,而且也是大多數邏輯損害時恢復資料庫的最佳選擇。該功能不基於撤銷資料(undodata),而是 基於閃回日誌


Oracle系統為了使用資料庫的閃回功能,特別建立了另外一組日誌,就是Flashback_logs(閃回日誌),記錄資料庫的閃回操作。


使用閃回資料庫恢復比使用傳統的恢復方法要快得多,這是因為恢復不再受資料庫大小的影響。也就是說,傳統的恢 復時間(MTTR)是由所需重建的資料檔案的大小和所要應用的歸檔日誌的大小決定的。而使用閃回資料庫恢復,恢復時間是由恢復過程中需要備份的變化的數量 決定的,而不是資料檔案和歸檔日誌的大小。


閃回資料庫的結構是由 恢復寫入器(RVWR)後臺程式和 閃回資料庫日誌組成的。


如果要啟用閃回資料庫功能,RVWR 程式也要啟動。


閃回資料庫日誌是一種新的日誌檔案型別,它包括物理資料塊先前的“影像”。


閃回恢復區是閃回資料庫的先決條件,因為RVWR程式要將閃回日誌寫入該區域中,所以在使用閃回資料庫功能時,必須要啟用該區。


對於邏輯損害和使用者的誤操作,閃回資料庫是不完全恢復的優秀替代。但是必須要指出的是,閃回資料庫有其自身的侷限性。

侷限性:

1 使用閃回資料庫恢復不能解決媒介故障。若要從媒介故障中恢復,仍然需要重建資料檔案和恢復歸檔日誌檔案。

2  截短資料檔案(縮小資料檔案到較小的尺寸),用閃回資料庫不能恢復此類操作。


3 如果控制檔案已被重建,不能使用閃回資料庫。

4 不能完成刪除一個表空間的恢復。

5 最多隻能將資料庫恢復到在閃回日誌中最早可用的那個SCN,並不能將資料庫恢復到任意的SCN值。


配置閃回資料庫

配置閃回恢復區以後,要啟用閃回資料庫功能,還需要進行進一步的配置,需要注意如下幾點。

l 配置閃回恢復區。

2 資料庫需要執行在歸檔模式下(Archivelog)。

3透過資料庫引數DB_FLASHBACK_RETENTION_TARGET,來指定可以在多長時間內閃回資料庫。該值以分鐘為單位,預設值為1440(1天),更大的值對應更大的閃回恢復空間,類似於閃回資料庫的基線。

4 需要在MOUNT狀態下使用ALTER DATABASE FLASHBACK ON 命令啟動閃回資料庫功能。



配置閃回恢復區


DB_RECOVERY_FILE_DEST

這兩個引數分別用來指定閃回恢復區的位置與閃回恢復區的大小(預設值為空)。


DB_RECOVERY_FILE_DEST_SIZE

以下透過例項來具體說明,注意在設定這兩個動態初始化引數時,不需要重啟例項。


SQL> ALTER SYSTEM  SET db_recovery_file_dest_size=2g  SCOPE=BOTH;


SQL> ALTER SYSTEM SET db_recovery_file_dest='/u01/app/oracle/flash_recovery_area'

SCOPE=BOTH;


當然,也可以透過以下命令來檢視修改後的引數是否生效:


SQL> SHOW parameter db_recovery_file_dest


NAME                        TYPE        VALUE


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


db_recovery_file_dest       string        /u01/app/oracle/flash_recovery_area


db_recovery_file_dest_size   big integer    2G


也有專門的命令來修改閃回恢復區的大小,以及停用閃回恢復區。這些命令都使用ALTER SYSTEM語句來執行,具體如下。


①將閃回恢復區的大小設定為4GB。


SQL> ALTER SYSTEM SET db_recovery_file_dest_size=4g SCOPE=BOTH;


②要停用閃回恢復區,只需將引數db_recovery_file_dest置空就可以了。


SQL>ALTER SYSTEM SET db_recovery_file_dest=’’;


當閃回恢復區中的空間使用率超過85%的時候,資料庫將會向alert檔案中寫入警告資訊。而當超過97%的時候將會寫入嚴重告警資訊。當閃回恢復區空間全部耗盡的時候,Oracle將報告如下類似的錯誤:


ORA-19809: limit exceeded for recovery files


ORA-19804: cannot reclaim 52428800 bytes disk space from 1258291200 limit


此時查詢檢視dba_outstanding_alerts,將會給出錯誤的原因及操作建議


================

閃回目錄開啟的步驟

================

DB必須是歸檔的


1:關閉DB

2:mount DB

3:開啟閃回日誌的功能 alter database flashback on;   ----寫入控制檔案,所以必須mount

4:開啟DB alter database open;



1:

SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.


2:

[oracle@chen dbs]$ vim initdb02.ora            ---------------讓歸檔目錄去OMF自己管理的目錄/u01/app/oracle/fast_recovery_area

#*.log_archive_start=true

#*.log_archive_dest_1='location=/home/oracle/db02_archive1'

#*.log_archive_dest_2='location=/home/oracle/db02_archive2'

#*.log_archive_format=db02_%t%r_%s.arc


3:

startup mount;

SQL> alter database flashback on;


Database altered.


4:

SQL> alter database open;


Database altered.


SQL> select flashback_on from v$database;


FLASHBACK_ON

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

YES


[oracle@chen ~]$ cd /u01/app/oracle/fast_recovery_area/DB02/


[oracle@chen DB02]$ ls

archivelog  backupset  flashback  onlinelog



==========================

使用閃回database恢復資料的步驟  -----只能對付使用者做的誤操作,不能解決磁碟壞了

==========================

1 關閉DB

  shutdown immediate;


2 mount DB

  startup mount;


3 執行閃回DB的操作

  flashback database to timestamp '時間點';


4 開啟DB

  alter database open resetlogs;


閃回快取區,儲存日誌檔案,放在SGA,佔用16M的空間


反向的閃回日誌


閃回的功能在控制檔案中


有程式,記憶體,I/O開銷


====

案例

====

1:800  時間點

2:1000

3:破壞

4:恢復


==============

1:基於時間的恢復

==============

SQL> select * from emp001 where empno=7369;


     EMPNO ENAME         SAL

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

      7369 SMITH         800


SQL> select sysdate from dual;


SYSDATE

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

2014-06-25 10:57:48


2:

SQL> update emp001 set sal=1000 where empno=7369;


1 row updated.


SQL> commit;


Commit complete.


3:

SQL> drop table emp001 purge;


Table dropped.


SQL> select * from emp001;

select * from emp001

              *

ERROR at line 1:

ORA-00942: table or view does not exist


4:恢復

SQL> conn /as sysdba

Connected.


SQL> shutdown immediate

Database closed.

Database dismounted.

ORACLE instance shut down.


5:

SQL> startup mount

ORACLE instance started.


Total System Global Area  768294912 bytes

Fixed Size          2232312 bytes

Variable Size         452984840 bytes

Database Buffers      306184192 bytes

Redo Buffers            6893568 bytes

Database mounted.


6:

SQL> flashback database to timestamp '2014-06-25 10:57:48';

flashback database to timestamp '2014-06-25 10:57:48'

                                *

ERROR at line 1:

ORA-00932: inconsistent datatypes: expected TIMESTAMP got CHAR


失敗原因:2014-06-25:09:53:42是date的格式,而不是timestamp的格式;     

        日期型別和時間型別是兩個型別


SQL> flashback database to timestamp to_timestamp('2014-06-25 10:57:48','yyyy-mm-dd hh24:mi:ss');


Flashback complete.


7:

SQL> alter database open resetlogs;


Database altered.



SQL> select * from scott.emp001 where empno=7369;


     EMPNO ENAME         SAL

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

      7369 SMITH         800




====================

恢復2:基於SCN號的恢復:

====================


如何檢視當前的SCN號?


SQL> select current_scn from v$database;


CURRENT_SCN

-----------

    1051621


SQL> select current_scn from v$database;


CURRENT_SCN

-----------

    1051621


SQL> conn scott/tiger

Connected.


SQL> drop table emp002 purge;


Table dropped.


SQL> shutdown immediate


SQL> startup mount


SQL> flashback database to scn 1051621;


Flashback complete.


SQL> alter database open resetlogs;


Database altered.


SQL> select * from scott.emp002 where empno=7369;


     EMPNO ENAME         SAL

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

      7369 SMITH         800



2 閃回丟棄(Flashback Drop)

閃回丟棄是將被丟棄的資料庫物件及其相依物件的複製儲存在回收站中,以便在必要時能夠及時恢復這些物件。在回收站被清空以前,被丟棄的物件並沒有從資料庫中刪除。這就使資料庫能夠恢復被意外或者誤操作而刪除的表。


為了更好地理解閃回丟棄,需要理解回收站的工作細節,以及丟棄物件在回收站中的儲存、查詢與清除等,將在以下的小節中介紹。


回收站概念


回收站(Recycle Bin)是所有丟棄表及其相依物件的邏輯儲存容器。當一個表被丟棄時(DROP),回收站會將該表及其相依物件儲存在回收站中。儲存在回收站中的表的相依物件包括索引、約束、觸發器、巢狀表、大的二進位制物件(LOB)段和LOB索引段。


Oracle回收站將使用者所進行的DROP語句的操作記錄在一個系統表裡,即將被刪除的物件寫到一個資料字典表中,確定是不再需要的被刪除物件時,可以使用PURGE命令對回收站空間進行清除。

為了避免被刪除表與同類物件名稱的重複,被刪除表(及相依物件)放到回收站中後,Oracle系統對被刪除的物件名進行了轉換。被刪除物件(如表)的名字轉換格式如下:BIN$globalUID$version

globalUID是一個全域性唯一的、24個字元長的標識物件,它是Oracle內部使用的標識,對於使用者來說沒有任何實際意義,因為這個標識與物件未刪除前的名稱沒有關係。

    $version 是Oracle資料庫分配的版本號。


使用回收站


如果要對DROP過的表進行恢復操作,可以使用以下語句:

SQL>FLASHBACK TABLE table_name TO BEFORE DROP


為了幫助讀者理解回收站在使用中的操作過程,下面給出較詳細的回收站操作步驟。

示例:本例給出資料準備、刪除表、查詢回收站資訊、恢復及查詢恢復後的情況。

(1)連線Oracle

[oracle@localhost ~]$ sqlplus scott/tiger

SQL> set line 120;

SQL> set pagesize 50;

SQL> show user;

USER is "SCOTT"

(2)準備資料

SQL> create table my_emp as select * from emp;

Table created.

SQL> select count(*) from my_emp;

  COUNT(*)

----------

  14

(3)刪除表結構

SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID

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

BONUS                          TABLE

DEPT                           TABLE

EMP                            TABLE

EMP2                           TABLE

MY_EMP                         TABLE

SALGRADE                       TABLE

SYS_TEMP_FBT                   TABLE

7 rows selected.

SQL> drop table my_emp;

Table dropped.

SQL>

(4)刪除(DROP)表後的資料字典

SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID

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

BIN$POiMOEfPgU3gQAB/AQASlg==$0 TABLE

BONUS                          TABLE

DEPT                           TABLE

EMP                            TABLE

EMP2                           TABLE

SALGRADE                       TABLE

SYS_TEMP_FBT                   TABLE

7 rows selected.


需要說明的是,當MY_EMP表被刪除以後,在資料庫回收站裡變成了BIN$POiMOEfPgU3gQAB/ AQASlg==$0,version是0。


(5)檢視user_recyclebin回收站,可以看到刪除的表對應的記錄:

SQL> col object_name for a30;

SQL> col original_name for a20;

SQL> select object_name,original_name from user_recyclebin;

OBJECT_NAME                    ORIGINAL_NAME

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

BIN$POiMOEfPgU3gQAB/AQASlg==$0 MY_EMP

SQL>


(6)利用user_recyclebin中的記錄,使用FLASHBACK從回收站恢復表MY_EMP:

SQL> flashback table my_emp to before drop;

Flashback complete.


SQL> select count(*) from my_emp;

  COUNT(*)

----------

   14

以上是恢復完成後的查詢結果。


回收站與空間利用

回收站是丟棄物件的邏輯儲存容器,它以表空間中現有的已經分配的空間為基礎,這意味著系統並沒有給回收站預留空間。這使回收站空間依賴於現有表空間中的可用空間(也就是說丟棄表佔據的空間仍然需要計入表空間配額)。因此並不能總是保證丟棄物件在回收站中的最小時間。

如果不對回收站進行清除操作,丟棄物件會一直儲存在回收站內,一直到丟棄物件所屬的表空間無法再分配新的儲存區域,這種狀態稱之為空間壓力。有時,使用者的表空間限額也會導致空間壓力狀態的出現,即使表空間中仍然存在自由空間。

當空間壓力出現時,Oracle會覆蓋些回收站物件從而自動回收表空間。Oracle根據先進先出的原則來選擇丟棄物件進行刪除,所以最先被丟棄的物件也最先被清除。而物件的清除僅僅是為了解決產生的空間壓力問題,所以會盡可能清除少的物件來滿足空間壓力的要求。這樣處理,既最大限度地保證了物件在回收站中的可用時間,又減少了Oracle在事物處理時的效能影響。

DBA需要關注回收站的空間利用情況,掌握清除回收站物件從而釋放空間的辦法,這可用PURGE命令來完成。PURGE命令可從回收站中刪除表或索引,並釋放有關表和索引所佔用的空間;用PURGE命令也可清除整個回收站或清除被刪除的表空間的所有部分。

值得一提的是,當用PURGE命令清除掉被刪除的物件後,該物件確實是被完全清除掉而不能再重建了。


要清除回收站中的物件,釋放空間,有以下幾種方式。

(1)使用PURGE TABLE original_table_name。

這裡的original_table_name表示表在drop以前的名稱(源名稱),使用該操作可以從回收站中永久地刪除物件並釋放空間。

(2)使用PURGE TABLE recyclebin_object_name。

這裡的recyclebin_object_name表示回收站中的物件名稱,使用該操作可以從回收站中永久地刪除物件並釋放空間。

(3)使用PURGE TABLESPACE tablespace_name從回收站清除一個特定表空間的所有物件。

該命令從指定的表空間中清除所有的丟棄物件及相依物件。因為相依物件(比如LOB、巢狀表、索引和分割槽等)未必與基表儲存在同一個表空間,該命令會將相依物件從其所在的表空間中進行清除。

(4)使用PURGE TABLESPACE tablespace_name USER user_name,會從回收站中清除屬於某個特定使用者的所有丟棄物件(當然也包括基表的相依物件)。

(5)使用命令DROP USER user_name CASCADE直接刪除指定使用者及其所屬的全部物件。

也就是說DROP USER命令會繞過回收站直接進行刪除。同時,如果回收站中也有該使用者的所屬物件,

則也會從回收站中清除掉。

(6)使用PURGE RECYCLEBIN 命令可以清除使用者自己的回收站。

該命令從使用者回收站中清除所有的物件並釋放與這些物件關聯的空間。

(7)PURGE DBA_RECYCLEBIN從所有使用者的回收站清除所有物件。

該命令能高效地完全清空回收站,當然執行該命令必須具有SYSDBA系統管理許可權才可以。

示例:查詢當前使用者回收站中的內容,再用PURGE清除。

SQL> show user;

USER is "SCOTT"

SQL> create table orcltest as select  *  from emp;

Table created.

SQL> select * from tab;

TNAME                          TABTYPE  CLUSTERID

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

BONUS                          TABLE

DEPT                           TABLE

EMP                            TABLE

EMP2                           TABLE

MY_EMP                         TABLE

ORCLTEST                       TABLE

SALGRADE                       TABLE

SYS_TEMP_FBT                   TABLE

8 rows selected.


SQL> drop table orcltest;

Table dropped.


SQL> select object_name,original_name from user_recyclebin;

OBJECT_NAME                    ORIGINAL_NAME

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

BIN$POiMOEfQgU3gQAB/AQASlg==$0 ORCLTEST


SQL> select object_name,original_name from user_recyclebin;

OBJECT_NAME                    ORIGINAL_NAME

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

BIN$POiMOEfQgU3gQAB/AQASlg==$0 ORCLTEST


SQL> purge table orcltest;

Table purged.


SQL> select object_name,original_name from user_recyclebin;

no rows selected


==============

恢復drop的表

==============


方法一:

SQL> select * from t3;


        ID         QQ

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

         1          1

         2          2


SQL> drop table t3;


Table dropped.


SQL> select original_name,operation,droptime from recyclebin;


ORIGINAL_NAME                    OPERATION DROPTIME

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

T3                               DROP      2014-08-24:01:21:23


SQL> flashback table t3 to before drop;


Flashback complete.


SQL> select * from t3;


        ID         QQ

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

         1          1

         2          2

方法二:

SQL> drop table t3;


Table dropped.


SQL> select * from tab;


TNAME                          TABTYPE  CLUSTERID

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

BIN$AU/tyVw+qJzgUKjAtQFG6g==$0 TABLE

SYS_TEMP_FBT                   TABLE

T2                             TABLE


SQL> select object_name,ORIGINAL_NAME from user_recyclebin;


OBJECT_NAME                    ORIGINAL_NAME

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

BIN$AU/tyVw+qJzgUKjAtQFG6g==$0 T3


SQL> create table t4 as select * from "BIN$AU/tyVw+qJzgUKjAtQFG6g==$0";


Table created.


SQL> select * from t4;


        ID         QQ

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

         1          1

         2          2


  假如刪除一個表且不放到回收站中不能進行恢復,在drop語句中可以利用purge選項。


Oracle在10g可以在DROP表之後透過簡單的命令將表恢復到刪除以前的狀態。這個命令就是FLASHBACK TABLE。這個功能和WINDOWS的回收站功能很想,而對應的清除回收站的功能就是PURGE。

也就是說FLASHBACK語句會還原最後放入回收站的表,而PURGE語句會清除最早進入回收站的表。

當回收站中存在同名物件的時候,可以用回收站中的名字進行清除和還原。另外FLASHBACK還有RENAME TO語句,可以在還原的時候對錶進行重新命名,避免和當前使用者下已經存在的表衝突。


前兩天偶然發現,雖然使用者內的表名不能重複,但是由於回收站中給刪除表重新起了名字,因此回收站可以包括多個同名表的刪除結果。而清空回收站所使用的命令PURGE TABLE TABLENAME,其中TABLENAME是原來的表名,那麼當出現重名時,將會清除或還原哪張表?


SQL> show user

USER is "CHEN"


SQL> create table t(id number);


Table created.


SQL> drop table t;


Table dropped.


SQL> create table t(name varchar2(30));


Table created.


SQL> drop table t;


Table dropped.


SQL> col original_name for a8


SQL> select object_name,original_name,droptime from recyclebin;

OBJECT_NAME                    ORIGINAL DROPTIME

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

BIN$AU/tyVw+qJzgUKjAtQFG6g==$0 T3       2014-08-24:01:26:14

BIN$AU/tyVxAqJzgUKjAtQFG6g==$0 T        2014-08-24:01:52:05

BIN$AU/tyVw/qJzgUKjAtQFG6g==$0 T        2014-08-24:01:51:24


SQL> desc t

ERROR:

ORA-04043: object t does not exist



SQL> flashback table t to before drop;


Flashback complete.


SQL> desc t

 Name                                      Null?    Type

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

 NAME                                               VARCHAR2(30)


結論:也就是說FLASHBACK語句會還原最後放入回收站的表,而PURGE語句會清除最早進入回收站的表。


SQL> flashback table "BIN$AU/tyVw/qJzgUKjAtQFG6g==$0" to before drop rename to tt;


Flashback complete.


SQL> desc tt

 Name                                      Null?    Type

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

 ID                                                 NUMBER


 


3 閃回版本查詢


在 Oracle9i Database 中,我們看到它推出了以閃回查詢形式表示的“時間機器”。該特性允許 DBA 看到特定時間的列值,只要在還原段中提供該資料塊此前映象的複製即可。但是,閃回查詢只提供某時刻資料的固定快照,而不是在兩個時間點之間被更改資料的執行狀態表示。某些應用程式,如涉及到外幣管理的應用程式,可能需要了解一段時期內數值資料的變化,而不僅僅是兩個時間點的數值。由於閃回版本查詢特性,Oracle Database 10g 能夠更方便高效地執行該任務。


在 Oracle9i Database 中,我們看到它推出了以閃回查詢形式表示的“時間機器”。該特性允許 DBA 看到特定時間的列值,只要在還原段中提供該資料塊此前映象的複製即可。但是,閃回查詢只提供某時刻資料的固定快照,而不是在兩個時間點之間被更改資料的執行狀態表示。某些應用程式,如涉及到外幣管理的應用程式,可能需要了解一段時期內數值資料的變化,而不僅僅是兩個時間點的數值。由於閃回版本查詢特性,Oracle Database 10g 能夠更方便高效地執行該任務。


查詢對錶的更改


在本示例中,我使用了一個銀行外幣管理應用程式。其資料庫含有一個名稱為 RATES 的表,用於記錄特定時間的匯率。


SQL> desc rates

Name Null?Type

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

CURRENCY VARCHAR2(4)

RATE NUMBER(15,10)


該表顯示 US$ 與各種其他貨幣的匯率,在 CURRENCY 列中顯示。在金融服務行業中,匯率不但在變更時進行更新,而且被記錄在歷史中。需要這種方式的原因是銀行交易可能在“過去時間”生效,以便適應由於匯款而耗費的時間。例如,對於一項在上午 10:12 發生但在上午 9:12 生效的交易,其有效匯率是上午 9:12 的匯率,而不是現在的匯率。


直到現在,唯一的選擇是建立一個匯率歷史表來儲存匯率的變更,然後查詢該表是否提供歷史記錄。另一種選擇是在 RATES 表本身中記錄特定匯率適用性的開始和結束時間。當發生變更時,現有行中的 END_TIME 列被更新為 SYSDATE,並插入一個具有新匯率的新行,其 END_TIME 為 NULL。


但是在 Oracle Database 10g 中,閃回版本查詢特性不需要維護歷史表或儲存開始和結束時間。使用該特性,您不必進行額外的設定,即可獲得某行在過去特定時間的值。


例如,假定該 DBA 在正常業務過程中數次更新匯率 — 甚至刪除了某行並重新插入該行:


insert into rates values ('EURO',1.1012);

commit;

update rates set rate = 1.1014;

commit;

update rates set rate = 1.1013;

commit;

delete rates;

commit;

insert into rates values ('EURO',1.1016);

commit;

update rates set rate = 1.1011;

commit;


在進行了這一系列操作後,DBA 將透過以下命令獲得 RATE 列的當前提交值


SQL> select * from rates;


CURR RATE

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

EURO 1.1011


此輸出顯示 RATE 的當前值,沒有顯示從第一次建立該行以來發生的所有變更。這時使用閃回查詢,您可以找出給定時間點的值;但我們對構建變更的審計線索更感興趣 — 有些類似於透過行動式攝像機來記錄變更,而不只是在特定點拍攝一系列快照。


以下查詢顯示了對錶所做的更改:


select versions_starttime, versions_endtime, versions_xid,

versions_operation, rate

from rates versions between timestamp minvalue and maxvalue

order by VERSIONS_STARTTIME

/


VERSIONS_STARTTIME VERSIONS_ENDTIME VERSIONS_XID V RATE

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

01-DEC-03 03.57.12 PM 01-DEC-03 03.57.30 PM 0002002800000C61 I 1.1012

01-DEC-03 03.57.30 PM 01-DEC-03 03.57.39 PM 000A000A00000029 U 1.1014

01-DEC-03 03.57.39 PM 01-DEC-03 03.57.55 PM 000A000B00000029 U 1.1013

01-DEC-03 03.57.55 PM 000A000C00000029 D 1.1013

01-DEC-03 03.58.07 PM 01-DEC-03 03.58.17 PM 000A000D00000029 I 1.1016

01-DEC-03 03.58.17 PM 000A000E00000029 U 1.1011




注意,此處顯示了對該行所作的所有更改,甚至包括該行被刪除和重新插入的情況。VERSION_OPERATION 列顯示對該行執行了什麼操作 (Insert/Update/Delete)。所做的這些工作不需要歷史表或額外的列。


在上述查詢中,列 versions_starttime、versions_endtime、versions_xid、versions_operation 是偽列,與 ROWNUM、LEVEL 等其他熟悉的偽列相類似。其他偽列 — 如 VERSIONS_STARTSCN 和 VERSIONS_ENDSCN — 顯示了該時刻的系統更改號。列 versions_xid 顯示了更改該行的事務識別符號。有關該事務的更多詳細資訊可在檢視FLASHBACK_TRANSACTION_QUERY 中找到,其中列 XID 顯示事務 id。例如,使用上述的 VERSIONS_XID 值 000A000D00000029,UNDO_SQL 值顯示了實際的語句。



注: versions_starttime : 這個資料開始生效的時間

VERSIONS_ENDTIME :這個資料失效的時間--一般就是下面一條記錄開始的時間

versions_xid : 顯示了更改該行的事務識別符號。

VERSION_OPERATION :這條記錄執行的操作(Insert/Update/Delete)



SELECT UNDO_SQL

FROM FLASHBACK_TRANSACTION_QUERY

WHERE XID = '000A000D00000029';


UNDO_SQL

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

insert into "ANANDA"."RATES"("CURRENCY","RATE") values ('EURO','1.1013');


除了實際語句之外,該檢視還顯示提交操作的時間標記和 SCN、查詢開始時的 SCN 和時間標記以及其他資訊。


找出一段時期中的變更


現在,讓我們來看如何有效地使用這些資訊。假設我們需要找出下午 3:57:54 時 RATE 列的值。我們可以執行:


select rate, versions_starttime, versions_endtime

from rates versions

between timestamp

to_date('12/1/2003 15:57:54','mm/dd/yyyy hh24:mi:ss')

and to_date('12/1/2003 16:57:55','mm/dd/yyyy hh24:mi:ss')

/


RATE VERSIONS_STARTTIME VERSIONS_ENDTIME

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

1.1011


此查詢與閃回查詢類似。在以上的示例中,開始和結束時間為空,表示匯率在該時間段中沒有更改,而是包含一個時間段。還可以使用 SCN 來找出過去的版本值。可以從偽列 VERSIONS_STARTSCN 和 VERSIONS_ENDSCN 中獲得 SCN 號。以下是一個示例:


select rate, versions_starttime, versions_endtime

from rates versions

between scn 1000 and 1001

/


使用關鍵詞 MINVALUE 和 MAXVALUE,可以顯示還原段中提供的所有變更。您甚至可以提供一個特定的日期或 SCN 值作為範圍的一個端點,而另一個端點是文字 MAXVALUE 或 MINVALUE。例如,以下查詢提供那些只從下午 3:57:52 開始的變更,而不是全部範圍的變更:


select versions_starttime, versions_endtime, versions_xid,

versions_operation, rate

from rates versions between timestamp

to_date('12/11/2003 15:57:52', 'mm/dd/yyyy hh24:mi:ss')

and maxvalue

order by VERSIONS_STARTTIME

/


VERSIONS_STARTTIME VERSIONS_ENDTIME VERSIONS_XID V RATE

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

01-DEC-03 03.57.55 PM 000A000C00000029 D 1.1013

01-DEC-03 03.58.07 PM 01-DEC-03 03.58.17 PM 000A000D00000029 I 1.1016

01-DEC-03 03.58.17 PM 000A000E00000029 U 1.1011



最終的分析


閃回版本查詢隨取隨用地複製表變更的短期易變數值審計。這一優點使得 DBA 能夠獲得過去時間段中的所有變更而不是特定值,只要還原段中


提供資料,就可以盡情使用。因此,最大的可用版本依賴於 UNDO_RETENTION 引數。



注: 暫未大規模使用過,不知道該操作對效能以及磁碟的開銷影響有多大?


 

4 閃回事務查詢


閃回事務查詢有別於閃回查詢的特點有以下3個:


(1)其正常工作不但需要利用撤銷資料,還需要事先啟用最小補充日誌。


(2)返回的結果不是以前的“舊”資料,而是能夠將當前資料修改為以前的樣子的撤銷SQL(Undo SQL)語句。


(3)集中地在名為flashback_transaction_query表上查詢,而不是在各個表上透過“as of”或“versions between”子句查詢。


瞭解了以上特點之後,使用閃回事務查詢就沒有任何困難了,首先開啟 最小補充日誌


SQL> alter database add supplemental log data;


Database altered.


從此以後,只要在閃回查詢的查詢視窗內,管理員就可以透過flashback_transaction _query表獲得相關事務的撤銷SQL。下面列舉一個典型的閃回事務查詢的使用方法。


場景:使用者在一個事務中分別使用insert和update命令修改了hr.departments和hr.employees表,命令細節如下所示:


SQL> insert into hr.departments

  2  (department_id,department_name,manager_id,location_id)

  3  values (999,'SETI',100,1700);


1 row created.


SQL> update hr.employees set department_id=999

  2  where employee_id=200;


1 row updated.


SQL> commit;


Commit complete.


該事務建立了一個新的999號部門,並且將200號員工指派入該新部門,該員工在此之前在10號部門上班。可惜這個事務是人為錯誤!且看如何利用閃回事務查詢恢復原始狀態。首先透過閃回版本查詢獲得該事務的XID,比如從錯誤的999號部門入手:


SQL> select

  2  versions_xid,versions_startscn,department_id,department_name

  3  from hr.departments

  4  versions between timestamp minvalue and maxvalue

  5  where department_id=999

  6  order by 2 nulls first;


VERSIONS_XID     VERSIONS_STARTSCN DEPARTMENT_ID DEPARTMENT_NAME

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

090010002B030000           1037789           999 SETI


然後使用結果中的事務號090010002B030000查詢flashback_transaction_query表以獲得撤銷SQL:


SQL> select undo_sql

  2  from flashback_transaction_query

  3  where xid='090010002B030000';


UNDO_SQL

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

update "HR"."EMPLOYEES" set "DEPARTMENT_ID" = '10'

where ROWID = 'AAAR5pAAFAAAADLAAC';


delete from "HR"."DEPARTMENTS"

where ROWID = 'AAAR5kAAFAAAACtAAA';


2 rows selected.


結果得到了兩句dml命令,如果遵循給出的ROWID不難發現撤銷SQL試圖將hr.employees表中200號員工的部門從999修改為10:


SQL> select employee_id,department_id

  2  from hr.employees where rowid='AAAR5pAAFAAAADLAAC';


EMPLOYEE_ID DEPARTMENT_ID

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

        200           999


並且試圖刪除999號部門:


SQL> select * from hr.departments where ROWID = 'AAAR5kAAFAAAACtAAA';


DEPARTMENT_ID DEPARTMENT_NAME           MANAGER_ID    LOCATION_ID

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

          999 SETI                                  100              1700


如果根據撤銷SQL的手段處理,那不是正好將一開始的新部門建立及修改200號員工部門的insert和update命令抵消。筆者利用一個簡單的PL/SQL匿名塊來執行undo_sql:


SQL> begin

  2  for rec in

  3   (select undo_sql

  4    from flashback_transaction_query

  5    where xid='090010002B030000')

  6  loop

  7  if rec.undo_sql is not null then

  8   execute immediate substr(rec.undo_sql,1,length(rec.undo_sql)-1);

  9  end if;

 10  end loop;

 11  commit;

 12  end;

 13  /


PL/SQL procedure successfully completed.


檢查一下效果,應該發現200號員工不在999號部門了:


SQL> select department_id from hr.employees where employee_id=200;


DEPARTMENT_ID

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

           10


並且999號部門也不存在了:


SQL> select department_name from hr.departments where department_id=999;


no rows selected


閃回事務查詢可以將同一事務的所有撤銷SQL列出,這是閃回查詢做不到的,如有必要,管理員還能夠執行對應一個事務的部分撤銷SQL以一種破壞事務原子性的方式恢復一部分資料,如此行事正確與否完全取決於應用的邏輯。


最後,因為ddl命令的撤銷SQL包括對資料字典表的DML操作,並且人為地直接修改資料字典表是非常危險的,況且某些DDL操作不僅僅是對資料字典的DML操作,它們還涉及撤銷SQL無法影響到的領域,所以不要指望透過直接執行撤銷SQL恢復錯誤的ddl命令造成的影響。

 

 

5 閃回表(Flashback Table),閃回查詢

一: 閃回查詢 Falshback query ,恢復delete刪除資料

  Oracle Flashback Table特性利用Flashback Table語句,確保閃回到表的前一個時間點。與Oracle 9i中的Flashback Query相似,利用回滾段資訊來恢復一個或一些表到以前的一個時間點(一個快照)。要注重的是,Flashback Table不等於Flashback Query,Flashback Query僅僅是查詢以前的一個快照點而已,並不改變當前表的狀態,而Flashback Table將改變當前表及附屬物件一起回到以前的時間點。

 


SQL> grant flashback any table to chen;


SQL> select log_mode,open_mode,flashback_on from v$database;


LOG_MODE     OPEN_MODE            FLASHBACK_ON

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

ARCHIVELOG   READ WRITE                NO  -------------- 不需要開啟閃回功能


SQL> select * from t2;


        ID         QQ

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

         1          1

         2          2


SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;


TO_CHAR(SYSDATE,'YY

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

2014-08-24 00:13:29


SQL> delete t2;


2 rows deleted.


SQL> commit;


Commit complete.


SQL> select * from t2;


no rows selected


1 閃回查詢

SQL> select * from t2 as of timestamp to_timestamp('2014-08-24 00:13:59', 'yyyy-mm-dd hh24:mi:ss');


        ID         QQ

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

         1          1

         2          2



2 恢復delete刪除的資料

方法一:

SQL> create table t3 as  select * from t2 as of timestamp to_timestamp('2014-08-24 00:13:59', 'yyyy-mm-dd hh24:mi:ss');


Table created.


SQL> select * from t3;


        ID         QQ

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

         1          1

         2          2


方法二:

SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;


TO_CHAR(SYSDATE,'YY

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

2014-08-24 01:04:13


SQL> delete t3 where id=2;


1 row deleted.


SQL> commit;


Commit complete.

SQL> select * from t3;


        ID         QQ

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

         1          1


SQL> alter table chen.t3 enable row movement;


Table altered.

----------------- 被flashback回來rowid發生了變化,這也是為什麼flashback table 需要enable row movement的原因,正常情況表中 資料的rowid是不絕對不可以改變的;


SQL> flashback table chen.t3 to timestamp to_timestamp('2014-08-24 01:04:13','yyyy-mm-dd hh24:mi:ss');


Flashback complete.


SQL> select * from t3;


        ID         QQ

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

         1          1

         2          2


注:推薦使用scn,由於oracle9i中,因為scn與時間點的同步需要5分鐘,如果最近5分鐘之內的資料需要Falshback query查詢,可能會查詢丟失,而scn則不存在這個問題。Oracle10g中這個問題已修正(scn與時間點的大致關係,可以透過logmnr分析歸檔日誌獲得)。

 

方法三:

SQL> select current_scn from v$database;

CURRENT_SCN

-----------

    1078776

SQL> delete t4;

3 rows deleted.

SQL> select * from t4;

no rows selected


SQL> alter table chen.t4 enable row movement;

Table altered.

SQL> flashback table chen.t4 to scn 1078706;

Flashback complete.

SQL> select * from t4;

        ID         QQ

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

         1          1

         2          2

         3          3


注:推薦使用scn,由於oracle9i中,因為scn與時間點的同步需要5分鐘,如果最近5分鐘之內的資料需要Falshback query查詢,可能會查詢丟失,而scn則不存在這個問題。Oracle10g中這個問題已修正(scn與時間點的大致關係,可以透過logmnr分析歸檔日誌獲得)。


Falshback query查詢的侷限:

1. 不能Falshback到5天以前的資料。

2. 閃回查詢無法恢復到表結構改變之前,因為閃回查詢使用的是當前的資料字典。

3. 受到undo_retention引數的影響,對於undo_retention之前的資料,Flashback不保證能Flashback成功。

4. 對drop,truncate等不記錄回滾的操作,不能恢復。

5. 普通使用者使用dbms_flashback包,必須透過管理員授權。命令如下:

SQL>grant execute on dbms_flashback to scott;

 



6 閃回資料的歸檔  11g

從Oracle Database 11g開始,Oracle 提供了一個這樣的功能: 閃回資料歸檔(Flashback Data Archive)。透過這一功能Oracle資料庫可以將UNDO資料進行歸檔,從而提供全面的歷史資料查詢,也因此 Oracle 引入一個新的概念Oracle Total Recall也即Oracle全面回憶功能。閃回資料歸檔可以和我們一直熟悉的日誌歸檔類比,日誌歸檔記錄的是Redo的歷史狀態,用於保證恢復的連續性;而閃迴歸檔記錄的是UNDO的歷史狀態,可以用於對資料進行閃回追溯查詢;後臺程式LGWR用於將Redo資訊寫出到日誌檔案,ARCH程式負責進行日誌歸檔;在Oracle 11g中,新增的後臺程式FBDA(Flashback Data Archiver Process)則用於對閃回資料進行歸檔寫出:

[oracle@sp3: ~]$ps -ef | grep fbda | grep -v grep 
oracle    3251     1  0 Jan07 ?        00:00:11 ora_fbda_ccdb

閃迴歸檔資料甚至可以以年為單位進行儲存,Oracle可以透過內部分割槽和壓縮演算法減少空間耗用,這一特性對於需要審計以及歷史資料分割槽的環境尤其有用,但是注意,對於繁忙的資料庫環境,閃回資料儲存顯然要耗用更多的儲存空間。當然,使用者可以根據需要,對部分表進行閃回資料歸檔,從而滿足特定的業務需求。

因為閃回資料歸檔需要獨立的儲存,所以在使用該特性之前需要建立獨立的ASSM(自動段空間管理)表空間:

sys@TQGZS11G> create tablespace fbda datafile '/oracle/oradata/tqgzs11g/FBDA.dbf' size 200M segment space management auto;
Tablespace created.

然後可以基於該表空間建立閃回資料歸檔區, FLASHBACK ARCHIVE ADMINISTER系統許可權是建立閃回資料存檔所必需的,此處使用SYS使用者進行:

sys@TQGZS11G> create flashback archive fda tablespace fbda retention 1 month;
Flashback archive created.

此後就可以使用該歸檔區來記錄資料表的閃回資料量。為了測試方便,先將UNDO表空間更改為較小,以使得UNDO資料能夠儘快老化:

sys@TQGZS11G> create undo tablespace UNDOTBS2_SMALL datafile '/oracle/oradata/tqgzs11g/UNDOTBS2_SMALL.dbf' size 20M autoextend off;
Tablespace created.
sys@TQGZS11G> alter system set undo_tablespace= UNDOTBS2_SMALL;
System altered.
sys@TQGZS11G> show parameter undo
NAME                                 TYPE                           VALUE
------------------------------------ ------------------------------ ------------------------------
undo_management                      string                         AUTO
undo_retention                       integer                        900
undo_tablespace                      string                         UNDOTBS2_SMALL

接下來使用測試使用者連線,對測試表執行閃迴歸檔設定, FLASHBACK ARCHIVE物件許可權是啟用歷史資料跟蹤所必需的:

 歡迎關注我的微信公眾號"IT小Chen",共同學習,共同成長!!!

oracke閃回技術總結

oracke閃回技術總結



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

相關文章