1. 程式人生 > >Oracle 六大閃回技術,flashback

Oracle 六大閃回技術,flashback

Flashback 技術是以Undo segment中的內容為基礎的, 因此受限於UNDO_RETENTON引數。
要使用flashback 的特性,必須啟用自動撤銷管理表空間。
在Oracle 11g裡又出了一個新特性:Oracle Flashback Data Archive.
FDA通過將變化資料另外儲存到建立的閃迴歸檔區(Flashback Archive)中,以和undo區別開來,
這樣就可以為閃迴歸檔區單獨設定儲存策略,使之可以閃回到指定時間之前的舊資料而不影響undo策略。

在Oracle 10g中, Flash back家族分為以下成員:
Flashback Database,
Flashback Drop,
Flashback Query(分Flashback Query,Flashback Version Query,
Flashback Transaction Query 三種)
和Flashback Table。

Oracle 11g中閃回新特性 :閃迴歸檔

 

1 閃回恢復區(Flashback Recovery Area)
在oracle 9i中引入flashback查詢,以便能在需要的時候查到過去某個時刻的一致性資料,
依賴於undo表空間儲存的資訊來閃回查詢以前的版本,當然這個受限於undo表空間的大小,
以及保留策略。如果undo 被覆蓋了就不能進行查詢。

oracle10g中增強了閃回查詢的功能,並且提供了將整個資料庫回退到過去某個時刻的能力,
這是通過引入一種新的flashback log實現的。flashback log有點類似redo log,
只不過redo log將資料庫往前滾,flashback log則將資料庫往後滾。
為了儲存管理和備份恢復相關的檔案,oracle10g提供了一個叫做閃回恢復區(Flashback recovery area),
這個區域預設建立在oracle_base目錄下。 可以將所有恢復相關的檔案,
比如flashback log,archive log,backup set等,放到這個區域集中管理。

1.1 設定閃回恢復區
閃回恢復區主要通過3個初始化引數來設定和管理:
    db_recovery_file_dest:指定閃回恢復區的位置
    db_recovery_file_dest_size:指定閃回恢復區的可用空間大小
    db_flashback_retention_target:指定資料庫可以回退的時間,單位為分鐘,
     預設1440分鐘,也就是一天。當然,實際上可回退的時間還決定於閃回恢復區的大小,
     因為裡面儲存了回退所需要的flash log。
     所以這個引數要和db_recovery_file_dest_size配合修改。

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

System altered.

SQL> ALTER SYSTEM SET db_recovery_file_dest=' D:/app/Administrator/flash_recovery_area ' SCOPE=BOTH;

System altered.

SQL> show parameter db_recovery_file_dest

NAME                            TYPE                 VALUE
---------------------------    -----------           ------------------------------
db_recovery_file_dest           string               D:/app/Administrator/flash_recovery_area
db_recovery_file_dest_size      big integer          3852M
SQL> show parameter db_flashback

NAME                            TYPE         VALUE
----------------------------    --------     ------------------------------
db_flashback_retention_target   integer      1440

我們看到db_flashback_retention_target 預設是1440分鐘,即24 小時,
需要注意的是該引數雖然未直接指定flash recovery area大小,但卻受其制約,
舉個例子假如資料庫每天有10%左右的資料變動的話,如果該初始化引數值設定為1440,
則flash recovery area 的大小至少要是當前資料庫實際容量的10%,
如果該初始化引數設定為2880,則flash recovery area 的大小就至少是資料庫所佔容量的20%。

修改該引數:

SQL>alter system set db_flashback_retention_target=2880 scope=both;

1.2  取消閃回恢復區
將db_recovery_file_dest引數設定為空,可以停用閃回恢復區。
如果已經啟用flashback database,則不能取消閃回恢復區。

SQL> alter system set db_recovery_file_dest='';

 alter system set db_recovery_file_dest=''

*

第 1 行出現錯誤:
ORA-02097: 無法修改引數, 因為指定的值無效
ORA-38775: 無法禁用恢復區 - 閃回資料庫已啟用
SQL> shutdown immediate

資料庫已經關閉。

已經解除安裝資料庫。

ORACLE 例程已經關閉。

SQL> startup mount;

ORACLE 例程已經啟動。
Total System Global Area  849530880 bytes
Fixed Size                  1377896 bytes
Variable Size             637536664 bytes
Database Buffers          205520896 bytes
Redo Buffers                5095424 bytes
資料庫裝載完畢。

SQL> alter database flashback off;

資料庫已更改。

SQL> alter database open;

資料庫已更改。

SQL> alter system set db_recovery_file_dest='';

系統已更改。

SQL> show parameter db_recovery_file_dest

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string
db_recovery_file_dest_size           big integer 3852M

SQL>


注意:
(1)DB_RECOVERY_FILE_DEST_SIZE 只有在 DB_RECOVERY_FILE_DEST 清空之後才可以清空。
(2)初始化引數 db_recovery_file_dest_size 的設定有一點點需要注意的地方:
     檔案的第0塊和作業系統資料塊頭的空間大小不包含在內,該引數並不代表實際佔用的空間大小。
     如果空間被壓縮、映象、RAID 的話,該引數的值意義是不一樣的

1.3  閃回恢復區的內容
所有和恢復相關的檔案都可以存放到閃回恢復區
[email protected]> select file_type from v$flash_recovery_area_usage;

FILE_TYPE
--------------------
CONTROL FILE
REDO LOG
ARCHIVED LOG
BACKUP PIECE
IMAGE COPY
FLASHBACK LOG
FOREIGN ARCHIVED LOG

7 rows selected.


 
上面檢視中查詢的結果列出的所有型別的檔案,都可以利用閃回恢復區來存放、管理。
在一些 10g 的動態視圖裡( V$CONTROLFILE, V$LOGFILE, V$ARCHIVED_LOG, V$DATAFILE_COPY 等 )
的新的列 IS_RECOVERY_DEST_FILE ,指明相關的檔案是否在恢復區內。

[email protected]> col is_recovery_dest_file for a25
[email protected]> SELECT   recid, blocks, is_recovery_dest_file
  FROM   v$archived_log
 WHERE   recid < 5; 

     RECID     BLOCKS IS_RECOVERY_DEST_FILE
---------- ---------- -------------------------
         1      61856 YES
         2          1 YES
         3          1 YES
         4      87577 YES

1.4  閃回恢復區的一些限制
如果設定了閃回恢復區,則log_archive_dest和log_archive_duplex_dest將不可用。
SQL> alter system set log_archive_dest='e:/' ;

alter system set log_archive_dest='e:/'

*

第 1 行出現錯誤:
ORA-02097: 無法修改引數, 因為指定的值無效
ORA-16018: 無法將 LOG_ARCHIVE_DEST 與 LOG_ARCHIVE_DEST_n 或
DB_RECOVERY_FILE_DEST 一起使用

SQL> alter system set log_archive_duplex_dest='e:/';

alter system set log_archive_duplex_dest='e:/'

*

第 1 行出現錯誤:
ORA-02097: 無法修改引數, 因為指定的值無效
ORA-16018: 無法將 LOG_ARCHIVE_DUPLEX_DEST 與 LOG_ARCHIVE_DEST_n 或
DB_RECOVERY_FILE_DEST 一起使用


說明:
設定閃回恢復區後,如果沒有設定過log_archive_dest_n引數,則歸檔日誌預設是儲存到該區域的。
實際上,oracle是通過隱式的設定log_archive_dest_10='location=USE_DB_RECOVERY_FILE_DEST'
來實現的。所以,如果修改過log_archive_dest_n將歸檔日誌儲存到其他位置,
也可以修改該引數繼續使用閃回恢復區。

多個數據庫的閃回恢復區可以指定到同一個位置,但是db_name不能一樣,或者db_unique_name不一樣。
RAC的閃回恢復區必須位於共享磁碟上,能被所有例項訪問。
上述說明適用於單節點上有多個數據庫時的情況。

1.5  閃回恢復區的空間管理
閃回恢復區中新增或刪除檔案等變化都將記錄在資料庫的 alert 日誌中,
Oracle 10g 也針對該新特性提供了一個新的檢視, DBA_OUTSTANDING_ALERTS,
通過該檢視可以得到相關的資訊。
[email protected]> desc dba_outstanding_alerts;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 SEQUENCE_ID                                        NUMBER
 REASON_ID                                 NOT NULL NUMBER
 OWNER                                              VARCHAR2(30)
 OBJECT_NAME                                        VARCHAR2(513)
 SUBOBJECT_NAME                                     VARCHAR2(30)
 OBJECT_TYPE                                        VARCHAR2(64)
 REASON                                             VARCHAR2(4000)
 TIME_SUGGESTED                                     TIMESTAMP(6) WITH TIME ZONE
 CREATION_TIME                                      TIMESTAMP(6) WITH TIME ZONE
 SUGGESTED_ACTION                                   VARCHAR2(4000)
 ADVISOR_NAME                                       VARCHAR2(30)
 METRIC_VALUE                                       NUMBER
 MESSAGE_TYPE                                       VARCHAR2(12)
 MESSAGE_GROUP                                      VARCHAR2(64)
 MESSAGE_LEVEL                                      NUMBER
 HOSTING_CLIENT_ID                                  VARCHAR2(64)
 MODULE_ID                                          VARCHAR2(64)
 PROCESS_ID                                         VARCHAR2(128)
 HOST_ID                                            VARCHAR2(256)
 HOST_NW_ADDR                                       VARCHAR2(256)
 INSTANCE_NAME                                      VARCHAR2(16)
 INSTANCE_NUMBER                                    NUMBER
 USER_ID                                            VARCHAR2(30)
 EXECUTION_CONTEXT_ID                               VARCHAR2(128)
 ERROR_INSTANCE_ID                                  VARCHAR2(142)

在閃回恢復區中的空間使用超過 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:
SQL> select reason,object_type,suggested_action from dba_outstanding_alerts;

REASON                         OBJECT_TYPE          SUGGESTED_ACTION
------------------------------ -------------------- ----------------------------------------
db_recovery_file_dest_size of  RECOVERY AREA        Add disk space and increase db_recovery_
1258291200 bytes is 88.20% use                      file_dest_size, backup files to tertiary
d and has 148509184 remaining                        device, delete files from recovery area
bytes available.                                     using RMAN, consider changing RMAN rete
                                                    ntion policy or consider changing RMAN a
                                                    rchivelog deletion policy.


同時,oracle在alert中還會給出解決該問題的建議
************************************************************************
You have following choices to free up space from flash recovery area:
1. Consider changing RMAN RETENTION POLICY. If you are using Data Guard,
   then consider changing RMAN ARCHIVELOG DELETION POLICY.
2. Back up files to tertiary device such as tape using RMANB ACKUP RECOVERY AREA
   command.
3. Add disk space and increase db_recovery_file_dest_size parameter to reflect
   the new space.
4. Delete unnecessary files using RMAN DELETE command. If an operating system
   command was used to delete files, then use RMAN CROSSCHECK
   and DELETE EXPIRED commands.
************************************************************************

V$RECOVERY_FILE_DEST檢視 包含閃回恢復區的相關資訊:
[email protected]> desc v$recovery_file_dest;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 NAME                                               VARCHAR2(513)
 SPACE_LIMIT                                        NUMBER
 SPACE_USED                                         NUMBER
 SPACE_RECLAIMABLE                                  NUMBER
 NUMBER_OF_FILES                                    NUMBER

[email protected]> col name for a5
[email protected]> select * from v$recovery_file_dest;

NAME  SPACE_LIMIT SPACE_USED SPACE_RECLAIMABLE NUMBER_OF_FILES
----- ----------- ---------- ----------------- ---------------
+FRA   4621074432  620756992                 0              33

通過查詢檢視v$flash_recovery_area_usage,可以獲得當前閃回恢復區的空間使用情況,
並且可以知道是哪些檔案佔中了空間,據此可以做出相應的處理,或者加大閃回恢復區,
或者移走相應的檔案。
[email protected]> select * from v$flash_recovery_area_usage;

FILE_TYPE            PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE
-------------------- ------------------ -------------------------
NUMBER_OF_FILES
---------------
CONTROL FILE                        .41                         0
              1

REDO LOG                           4.63                         0
              4

ARCHIVED LOG                       3.72                         0
             24


FILE_TYPE            PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE
-------------------- ------------------ -------------------------
NUMBER_OF_FILES
---------------
BACKUP PIECE                          0                         0
              0

IMAGE COPY                            0                         0
              0

FLASHBACK LOG                      4.63                         0
              4


FILE_TYPE            PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE
-------------------- ------------------ -------------------------
NUMBER_OF_FILES
---------------
FOREIGN ARCHIVED LOG                  0                         0
              0


7 rows selected.


如果閃回恢復區空間耗盡,且歸檔路徑設定到了閃回恢復區中,則由於日誌無法歸檔,
資料庫會hang住。所以,對於生產庫,如果將歸檔放到閃回恢復區中,
需要密切關注閃回恢復區的空間使用情況,否則一旦閃回恢復區的空間用盡,
將導致資料庫無法提供服務。
因此,應該將閃回區的使用情況列入dba日常巡檢工作中。
 

1.6  Flash Recovery Area空間不足導致DB不能開啟或hang住處理方法
在上面講到,當歸檔目錄設定在閃回恢復區,並且閃回恢復區又滿了的情況下,
 DB 就會無法歸檔而hang住或者無法開啟。


這種情況下開啟資料庫會遇到如下錯誤資訊:
SQL> select status from v$instance;

STATUS
------------
MOUNTED

SQL> alter database open;

alter database open

*

第 1 行出現錯誤:

ORA-16014: 日誌 2 的序列號 27 未歸檔, 沒有可用的目的地
ORA-00312: 聯機日誌 2 執行緒 1:
'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/REDO02.LOG'


SQL> show parameter db_recovery_file

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest    string      D:/oracle/product/10.2.0/flash_recovery_area
db_recovery_file_dest_size        big integer 2G

SQL> alter system archive log current;

alter system archive log current

*

第 1 行出現錯誤:
ORA-01109: 資料庫未開啟
 

SQL> alter system switch logfile;

alter system switch logfile

*

第 1 行出現錯誤:
ORA-01109: 資料庫未開啟

SQL> shutdown immediate;

ORA-01109: 資料庫未開啟

已經解除安裝資料庫。
ORACLE 例程已經關閉。

SQL> startup
ORACLE 例程已經啟動。
Total System Global Area  201326592 bytes
Fixed Size                  1248092 bytes
Variable Size              88081572 bytes
Database Buffers          109051904 bytes
Redo Buffers               2945024 bytes
資料庫裝載完畢。

ORA-16038: 日誌 2 序列號 27 無法歸檔
ORA-19809: 超出了恢復檔案數的限制
ORA-00312: 聯機日誌 2 執行緒 1:
'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/REDO02.LOG'

SQL> alter database open;

alter database open

*

第 1 行出現錯誤:
ORA-16014: 日誌 2 的序列號 27 未歸檔, 沒有可用的目的地
ORA-00312: 聯機日誌 2 執行緒 1:
'D:/ORACLE/PRODUCT/10.2.0/ORADATA/ORCL/REDO02.LOG'


通過增加閃回恢復區大小,我們可以正常開啟資料庫

SQL> show parameter db_recovery

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest                string      D:/oracle/product/10.2.0/flash_recovery_area
db_recovery_file_dest_size           big integer 2G

SQL> alter system set db_recovery_file_dest_size=3G scope=both;

系統已更改。

SQL> alter database open;

資料庫已更改。

檢查一下flash recovery area的使用情況:

SQL> select * from v$flash_recovery_area_usage;

FILE_TYPE    PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE NUMBER_OF_FILES
------------ ------------------ ------------------------- ---------------
CONTROLFILE          0                         0               0
ONLINELOG           0                         0               0
ARCHIVELOG        6.36                         0               4
BACKUPPIECE       .22                         0               1
IMAGECOPY        63.68                         0               5
FLASHBACKLOG     .51                       .25               2

已選擇6行。

SQL>


計算flash recovery area已經佔用的空間:

SQL> select sum(percent_space_used)*3/100 from v$flash_recovery_area_usage;

SUM(PERCENT_SPACE_USED)*3/100
-----------------------------
                       2.1231                     
--在11.2以後,v$flash_recovery_area_usage已經被v$recovery_area_usage取代。

可以看到,這裡已經有2.1231G使用了,這說明我們剛開始設定的db_recovery_file_dest_size=2G不足,
導致online redo log無法歸檔,在這裡,我們通過設定db_recovery_file_dest_size引數,
增大了flash recovery area來解決這個問題。
增加Flash recovery area 是一種解決方法,也可以將歸檔指定到其他的目錄來解決這個問題。
或者刪除備份中的obsolete備份,都可以解決問題。


1.7  Flash Recovery Area 的備份
備份命令是Flash recovery Area,該命令是Oracle 10g以後才有的。
10g引進了flash recovery area,同時在rman備份中支援對該區域的備份。

在9i中oracle引入flashback查詢,依賴於undo表空間儲存的資訊來閃回查詢以前的版本,
當然這個受限於undo表空間的大小,以及保留策略。

在10g中oracle又引入了新的flashback功能,使用了flash recovery area來儲存flashback 1og等等。
這個區域預設建立在oracle_base目錄下。
在其中可以存放備份集、映象拷貝、歸檔日誌、自動備份的控制檔案以及spfile和flashback logs。
存放位置和大小由引數db_recovery_file_dest和db_recovery_file_dest_size決定。

預設情況資料庫的flashback database是關閉,可以在mount exclusive狀態下開啟。


看一下Oracle 官方文件上的幾段文字:
To free space in the FRA we could do take a backup of the Flash Recovery Area using the
command BACKUP RECOVERY AREA.This command will take the backup of all the files in the
FRA to tape only. After this the space occupied by the files in the FRA will be
marked as reclaimable。

the larger the fast recovery area, the more useful it is. Ideally, the fast recovery
area should be large enough for copies of the data files, control files, online
redo log files, and archived redo log files needed to recover the database,
and also the copies of these backup files that are kept based on the retention policy.

The Flash Recovery Area is a unified storage location for all recovery-related files
and activities in an Oracle Database. It includes Control File, Archived Log Files,
Flashback Logs, Control File Autobackups, Data Files, and RMAN files.


從上面的幾段話,我們可以得到一下資訊:
(1)    BACKUP RECOVERY AREA 命令只能備份到磁帶上。
         在磁碟上備份會報如下錯誤:
RMAN> BACKUP RECOVERY AREA;

啟動 backup 於 12-8月 -10
使用目標資料庫控制檔案替代恢復目錄
分配的通道: ORA_DISK_1
通道 ORA_DISK_1: SID=15 裝置型別=DISK
說明與資料檔案庫中的任何歸檔日誌都不匹配
說明與資料檔案庫中的任何資料檔案副本都不匹配

RMAN-00571: ===========================================================
RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS ===============
RMAN-00571: ===========================================================
RMAN-03002: backup 命令 (在 08/12/2010 13:50:10 上) 失敗
RMAN-06603: 必須在磁碟裝置上使用 RECOVERY AREA, RECOVERY FILES 或 DB_RECOVERY_FILE_DEST 指定 TO DESTINATION 選項


(2)    Flash recovery area 包含內容:控制檔案,歸檔檔案,flashback logs, 控制檔案,
自動備份的控制檔案,資料檔案,資料檔案拷貝,RMAN 檔案(包括備份集,映象備份)。

(3) BACKUP RECOVERY AREA 將備份所有Flash recovery area中的內容。

2 Flashback Database
2.1 Flashback Database 說明
            Flashback Database 功能非常類似與RMAN的不完全恢復,
            它可以把整個資料庫回退到過去的某個時點的狀態,
            這個功能依賴於Flashback log 日誌。 比RMAN更快速和高效。
             因此Flashback Database 可以看作是不完全恢復的替代技術。
             但它也有某些限制:
            (1)Flashback Database 不能解決Media Failure, 這種錯誤RMAN恢復仍是唯一選擇。
            (2)如果刪除了資料檔案或者利用Shrink技術縮小資料檔案大小,
                 這時不能用Flashback Database技術回退到改變之前的狀態,
                 這時候就必須先利用RMAN把刪除之前或者縮小之前的檔案備份restore 出來,
                 然後利用Flashback Database 執行剩下的Flashback Datbase。
            (3)如果控制檔案是從備份中恢復出來的,或者是重建的控制檔案,
                 也不能使用Flashback Database。
            (4)使用Flashback Database鎖能恢復到的最早的SCN,
                 取決於Flashback Log中記錄的最早SCN。

2.2 Flashback Database 架構
Flashback Database 整個架構包括一個程序Recover Writer(RVWR)後臺程序,
Flashback Database Log日誌 和Flash Recovery Area。
一旦資料庫啟用了Flashback Database, 則RVWR程序會啟動,
該程序會向Flash Recovery Area中寫入Flashback Database Log,
這些日誌包括的是資料塊的 " 前映象(before image)",
 這也是Flashback Database 技術不完全恢復塊的原因。

[[email protected] ~]$ ps -ef|grep rvwr
oracle    6326     1  0 10:36 ?        00:00:00 ora_rvwr_orcl1

[[email protected] ~]$ ps -ef|grep rvwr
oracle    6474     1  0 10:36 ?        00:00:00 ora_rvwr_orcl2

2.3 啟用Flashback Database 步驟
資料庫的Flashback Database功能預設是關閉的,要想啟用這個功能,就需要做如下配置。

2.3.1 配置Flash Recovery Area
這個參考1.1 節的配置。

2.3.2 啟動flashback database
預設情況資料庫的flashback database是關閉,
可以在mount exclusive狀態下開啟。在設定了閃回恢復區後,可以啟動閃回資料庫功能。
[email protected]> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     12
Next log sequence to archive   13
Current log sequence           13
[email protected]> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
[email protected]> startup mount'
SP2-0714: invalid combination of STARTUP options
[email protected]> startup mount;
ORACLE instance started.

Total System Global Area  835104768 bytes
Fixed Size                  2257840 bytes
Variable Size             603982928 bytes
Database Buffers          226492416 bytes
Redo Buffers                2371584 bytes
Database mounted.
SQL> alter database flashback on;

資料庫已更改。

[email protected]> alter database open;

Database altered.

[email protected]> select flashback_on from v$database;

FLASHBACK_ON
------------------
YES


2.4 Flashback Database操作示例

做操作前先備份資料庫:
RMAN> backup database;
2.4.1 檢查是否啟動了flash recovery area
SQL> show parameter db_recovery_file

NAME                    TYPE        VALUE
------------------------------------  ----------- ------------------------------
db_recovery_file_dest       tring       D:/oracle/flash_recovery_area
db_recovery_file_dest_size  big integer 1G

2.4.2 檢查是否啟用了歸檔
SQL> archive log list;
資料庫日誌模式      存檔模式
自動存檔            啟用
存檔終點           USE_DB_RECOVERY_FILE_DEST
最早的聯機日誌序列  9
下一個存檔日誌序列  11
當前日誌序列        11

 
2.4.3 檢查是否啟用了flashback database
SQL> select flashback_on from v$database;

FLASHBACK_ON    
------------------
YES              

2.4.4 查詢當前的scn
SQL> SELECT CURRENT_SCN FROM V$DATABASE;

CURRENT_SCN
-----------
947921

2.4.5 查詢當前的時間
SQL> select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual;

TIME
-----------------
09-10-14 14:37:05

2.4.6 刪除表A
SQL> select * from A;

ID  NAME
---------- ----------
1  tianlesoftware
2  dave

SQL> drop table A;

表已刪除。

SQL> commit;


2.4.7 重啟DB 到mount
Flashback Database 實際是對資料庫的一個不完全恢復操作,
因為需要關閉資料庫重啟到mount狀態
SQL> shutdown immediate
資料庫已經關閉。
已經解除安裝資料庫。
ORACLE 例程已經關閉。
SQL> startup mount
ORACLE 例程已經啟動。
Total System Global Area  209715200 bytes
Fixed Size                  1248116 bytes
Variable Size              79692940 bytes
Database Buffers          121634816 bytes
Redo Buffers                7139328 bytes

資料庫裝載完畢。

2.4.8 執行恢復:分timestamp 或者SCN兩種
SQL> Flashback database to timestamp to_timestamp('09-10-14 14:37:05','yy-mm-dd hh24:mi:ss');

閃回完成。

或者:

SQL> Flashback database to scn 947921;

閃回完成。

2.4.9 開啟資料庫
在執行完flashback database 命令之後,oracle 提供了兩種方式讓你修復資料庫:
1). 直接alter database open resetlogs 開啟資料庫,當然,指定scn 或者timestamp 時間點之後
    產生的資料統統丟失。
2). 先執行alter database open read only 命令,以read-only 模式開啟資料庫,
    然後立刻通過邏輯匯出的方式將誤操作涉及表的資料匯出,再執行recover database
    命令以重新應用資料庫產生的redo,將資料庫修復到flashback database 操作前的狀態,
    然後再通過邏輯匯入的方式,將之前誤操作的表重新匯入,這樣的話對現有資料的影響最小,
    不會有資料丟失。

這裡演示,就以resetlogs方式開啟:

SQL> alter database open resetlogs;

資料庫已更改。

驗證資料:

SQL> select * from A;

        ID NAME

---------- ----------
         1 tianlesoftware
         2 dave

2.5 和Flashback Database 相關的3個檢視
2.5.1 V$database
 這個檢視可以檢視是否啟用了Flashback database功能

SQL> select flashback_on from v$database;

FLASHBACK_ON
------------------
YES

2.5.2 V$flashback_database_log
Flashback Database 所能回退到的最早時間,取決與保留的Flashback Database Log 的多少,
該檢視就可以檢視許多有用的資訊。
Oldest_flashback_scn / Oldest_flashback_time : 這兩列用來記錄可以恢復到最早的時點
Flashback_size: 記錄了當前使用的Flash Recovery Area 空間的大小
Retention_target: 系統定義的策略
Estimated_flashback_size: 根據策略對需要的空間大小的估計值

SQL> select oldest_flashback_scn os, to_char(oldest_flashback_time,'yy-mm-dd hh24:mi:ss') ot, retention_target rt,flashback_size fs, estimated_flashback_size es
 from v$flashback_database_log;

        OS OT                        RT         FS         ES
---------- ----------------- ---------- ---------- ----------
   1150657 14-07-01 10:18:39       1440  209715200          0


2.5.3 V$flashback_database_stat
這個檢視用來對Flashback log 空間情況進行更細粒度的記錄和估計。
這個檢視以小時為單位記錄單位時間內資料庫的活動量:
            Flashback_Data 代表Flashback log產生數量,
            DB_Date 代表資料改變數量,
            Redo_Date代表日誌數量,
通過這3個數量可以反映出資料的活動特點,更準確的預計Flash Recovery Area的空間需求

SQL> alter session set nls_date_format='hh24:mi:ss';

會話已更改。

SQL> select *from v$flashback_database_stat;

BEGIN_TI END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
-------- -------- -------------- ---------- ---------- ------------------------
14:43:10 15:15:28        6455296   29310976    3898368              0

 
3 Flashback Drop
Flashback Drop 是從Oracle 10g 開始出現的,用於恢復使用者誤刪除的物件(包括表,索引等),
這個技術依賴於Tablespace Recycle Bin(表空間回收站),這個功能和windows的回收站非常類似。
Flashback 不支援sys使用者. system表空間下的物件,也不能從回收站裡拿到。
故使用SYS 或者SYSTEM使用者登陸時, show recyclebin 為空。
Flashback Drop 是基於Tablespace RecycleBin 來實現恢復的。
它只支援閃回與table 相關連的物件,比如表,索引,約束,觸發器等。
如果是函式或者儲存過程等,就需要使用Flashback Query來實現。

3.1 Tablespace Recycle Bin
從Oracle 10g 開始, 每個表空間都會有一個叫作回收站的邏輯區域,當用戶執行drop命令時,
被刪除的表和表的關聯物件( 包括索引, 約束,觸發器,LOB段,LOB index 段) 不會被物理刪除,
這些物件先轉移到回收站中,這就給使用者提供了一個恢復的可能。
When you drop a table, the database does not immediately remove the space associated
with the table. The database renames the table and places it and any associated
objects in a recycle bin, where, in case the table was dropped in error,
it can be recovered at a later time. This feature is called Flashback Drop,
and the FLASHBACK TABLE statement is used to restore the table. Before discussing
the use of the FLASHBACK TABLE statement for this purpose, it is important to
understand how the recycle bin works, and how you manage its contents.
The recycle bin is actually a data dictionary table containing information about
dropped objects. Dropped tables and any associated objects such as indexes,
constraints, nested tables, and the likes are not removed and still occupy space.
They continue to count against user space quotas, until specifically purged from
the recycle bin or the unlikely situation where they must be purged by the
database because of tablespace space constraints.

 
初始化引數recyclebin 用於控制是否啟用recyclebin功能,預設是ON, 可以使用OFF關閉。
[email protected]> show parameter recycle;

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle                  string
db_recycle_cache_size                big integer 0
recyclebin                           string      on


禁用該功能:

SQL> alter system set recyclebin=off;
SQL> alter system set recyclebin=on;

SQL> alter session set recyclebin=off;
SQL> alter session set recyclebin=on;

禁用後刪除的物件將直接刪除,不會寫到Recycle中,當然在刪除時,指定purge 引數,
表也將直接刪除,不會寫到recyclebin中。

SQL> drop table name purge;
檢視recyclebin中的物件列表:

SQL> select * from A;

        ID

        ----------

         1

         2

         3

SQL> drop table A;

表已刪除。

SQL> show recyclebin

ORIGINAL NAME    RECYCLEBIN NAME       OBJECT TYPE  DROP TIME
----------------      -----------------------------          ------------      
A   BIN$RWXQQcTPRde0ws4h9ewJcg==$0  TABLE     2009-10-15:12:44:33

檢視recyclebin中物件:

SQL> select original_name,object_name from recyclebin;

ORIGINAL_NAME       OBJECT_NAME
-------------------------------- ------------------------------
A                      BIN$RWXQQcTPRde0ws4h9ewJcg==$0

檢視recyblebin物件裡的內容:

SQL> select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";

        ID
       ----------
         1
         2
         3

 
表空間的Recycle Bin 區域只是一個邏輯區域,而不是從表空間上物理的劃出一塊區域固定用於回收站,
因此Recycle Bin是和普通物件共用表空間的儲存區域,
或者說是Recycle Bin的物件要和普通物件搶奪儲存空間。
當發生空間不夠時,Oracle會按照先入先出的順序覆蓋Recycle Bin中的物件。
如果表空間的資料檔案打開了自動擴充套件,則在資料檔案擴充套件之前,不會清除recyclebin中的內容。
每次擴充套件的時候,Oracle實際上是執行了alter database datafile resize命令。
 
也可以手動的刪除Recycle Bin佔用的空間:
            1). Purge tablespace tablespace_name:
                用於清空表空間的Recycle Bin
            2). Purge tablespace tablespace_name user user_name:
                清空指定表空間的Recycle Bin中指定使用者的物件
            3). Purge recyclebin:
                刪除當前使用者的Recycle Bin中的物件
            4). Purge dba_recyclebin:
                刪除所有使用者的Recycle Bin中的物件,該命令要sysdba許可權
            5). Drop table table_name purge: 
                刪除物件並且不放在Recycle Bin中,
                即永久的刪除,不能用Flashback恢復。
            6). Purge index recycle_bin_object_name:
                當想釋放Recycle bin的空間,
                又想能恢復表時,可以通過釋放該物件的index所佔用的空間來緩解空間壓力。
                因為索引是可以重建的。

3.2 Flashback Drop 例項操作
SQL> select original_name,object_name from recyclebin;

ORIGINAL_NAME         OBJECT_NAME
-------------------------------- ------------------------------
A                       BIN$RWXQQcTPRde0ws4h9ewJcg==$0

SQL> flashback table a to before drop;

閃回完成。

SQL> select * from a;

        ID
         ----------
         1
         2
         3

當我們刪除表A後,在新建表A,這時在恢復的時候就會報錯,此時我們在閃回時,
對錶重新命名就可以了:

SQL> drop table a;

表已刪除。

SQL> create table a

  2  (id number(1));

表已建立。

SQL> flashback table a to before drop ;

flashback table a to before drop

*

第 1 行出現錯誤:

ORA-38312: 原始名稱已被現有物件使用

SQL> flashback table a to before drop rename to B;

閃回完成。

SQL> select * from B;

        ID
        ----------
         1
         2
         3

當我們刪除表A,在新建表A,在刪除它,這是在Recycle Bin中就會有2個相同的表名,
此時恢復我們就要指定object_name才行.

SQL> select * from B;

        ID
        ----------
         1
         2
         3

SQL> drop table B;

表已刪除。

SQL> create table B(name varchar(20));

表已建立。

SQL> drop table B;

表已刪除。

SQL> select original_name,object_name from recyclebin;

ORIGINAL_NAME                    OBJECT_NAME
--------------------------------            ------------------------------
B                                BIN$vYuv+g9fTi2exYP9X2048Q==$0
B                                BIN$geQ9+NekSjuRvzG+TqDVWw==$0

SQL> flashback table "BIN$vYuv+g9fTi2exYP9X2048Q==$0" to before drop;

閃回完成。

SQL> select * from B;

        ID
       ----------
         1
         2
         3

 
一旦完成閃回恢復,Recycle Bin中的物件就消失了.
如果表上索引或者約束等資訊,這些資訊也會被恢復,但是這些物件會使用Oracle 自動的命名。
我們需要檢視這些物件,然後對這些物件重新命名:如:
SQL>select index_name from user_indexes where table_name = 'job_history';

INDEX_NAME
------------------------------
BIN$DBo9UChwZSbgQFeMiAdCcQ==$0
BIN$DBo9UChtZSbgQFeMiAdCcQ==$0
BIN$DBo9UChuZSbgQFeMiAdCcQ==$0
BIN$DBo9UChvZSbgQFeMiAdCcQ==$0

重新命名:

SQL>alter index "bin$dbo9uchtzsbgqfemiadccq==$0" rename to jhist_job_ix;


Flashback Drop 需要注意的地方:
1). 只能用於非系統表空間和本地管理的表空間
2). 物件的參考約束不會被恢復,指向該物件的外來鍵約束需要重建。
3). 物件能否恢復成功,取決與物件空間是否被覆蓋重用。
4). 當刪除表時,信賴於該表的物化檢視也會同時刪除,但是由於物化檢視並不會被放入recycle bin,
    因此當你執行flashback table to before drop 時,也不能恢復依賴其的物化檢視,
    需要dba 手工介入重新建立。
5). 對於Recycle Bin中的物件,只支援查詢.

4 Flashback Query
Flashback 是ORACLE 自9i 就開始提供的一項特性,在9i 中利用oracle 查詢多版本一致的特點,
實現從回滾段中讀取表一定時間內操作過的資料,可用來進行資料比對,
或者修正意外提交造成的錯誤資料,該項特性也被稱為Flashback Query。
Flashback Query分
Flashback Query,
Flashback Version Query,
Flashback Transaction Query 三種。

4.1  Flashback Query
Flashback Query 是利用多版本讀一致性的特性從UNDO 表空間讀取操作前的記錄資料。
flashback query 對v$tables,x$tables 等動態效能檢視無效,
不過對於dba_*,all_*,user_*等資料字典是有效的。
該特性也完全支援訪問遠端資料庫,比如select * from [email protected] as of scn 3600;的形式。

4.1.1  多版本讀一致性
不同的事務在寫資料時,會將資料的前映像寫入undo 表空間,這樣如果同時有其它事務查詢該表資料,
則可以通過undo 表空間中資料的前映像來構造所需的完整記錄集,
而不需要等待寫入的事務提交或回滾。
Flashback query 有多種方式構建查詢記錄集,記錄集的選擇範圍可以基於時間或基於scn,
甚至可以同時查詢出記錄在undo 表空間中不同事務時的前映象。        
用法與標準查詢非常類似,要通過flashback query 查詢undo 中的撤銷資料,
最簡單的方式只需要在標準查詢語句的表名後面跟上as of timestamp(基於時間)或as of scn
(基於scn)即可。
as of timestamp|scn 的語法是自9iR2 後才開始提供支援。

4.1.2  As  of  timestamp 的示例:
SQL>  alter session set nls_date_format='YYYY-MM-DD hh24:mi:ss';

會話已更改。

SQL> select sysdate from dual;

SYSDATE
-------------------
2009-10-15 19:04:16

SQL> select * from A;

        ID
        ----------
         2
         1
         3
         4

模擬使用者誤操作,刪除資料

SQL> delete from A;

已刪除4行。

SQL> commit;

提交完成。

SQL> select * from A;

未選定行

檢視刪除之前的狀態:假設當前距離刪除資料已經有5 分鐘左右的話:

SQL> select * from A as of timestamp sysdate-5/1440;

        ID
        ----------
         2
         1
         3
         4

或者:

SQL>select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');

        ID
        ----------
         2
         1
         3
         4

用Flashback Query恢復之前的資料:

SQL>Insert into A select * from A as of timestamp to_timestamp('2009-10-15 19:04:16','YYYY-MM-DD hh24:mi:ss');

已建立4行。

SQL> COMMIT;

提交完成。

SQL> select * from A;

        ID
        ----------
         2
         1
         3
         4

如上述示例中所表示的,as of timestamp 的確非常易用,但是在某些情況下,
我們建議使用as of scn 的方式執行flashback query,
比如需要對多個相互有主外來鍵約束的表進行恢復時,如果使用as of timestamp 的方式,
可能會由於時間點不統一的緣故造成資料選擇或插入失敗,通過scn 方式則能夠確保記錄的約束一致性。

4.1.3 As of scn 示例
檢視SCN:
SQL>SELECT dbms_flashback.get_system_change_number FROM dual;

SQL> SELECT CURRENT_SCN FROM V$DATABASE;

CURRENT_SCN
-----------
1095782

刪除資料:

SQL> delete from A;

已刪除4行。

SQL> commit;

提交完成。

檢視刪除之前的狀態:

SQL> select * from A as of scn 1095782;

        ID
     ----------
         2
         1
         3
         4

用Flashback Query恢復之前的資料:

SQL> insert into A select * from A as of scn 1095782;

已建立4行。

SQL> commit;

提交完成。

SQL> select * from A;

        ID
        ----------
         2
         1
         3
         4

4.1.4  SCN 與 timestamp 關係
Oracle 在內部都是使用scn,即使你指定的是as of timestamp,oracle 也會將其轉換成scn,
系統時間標記與scn 之間存在一張表,即SYS 下的SMON_SCN_TIME
[email protected]> desc sys.smon_scn_time;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 THREAD                                             NUMBER
 TIME_MP                                            NUMBER
 TIME_DP                                            DATE
 SCN_WRP                                            NUMBER
 SCN_BAS                                            NUMBER
 NUM_MAPPINGS                                       NUMBER
 TIM_SCN_MAP                                        RAW(1200)
 SCN                                                NUMBER
 ORIG_THREAD                                        NUMBER


每隔5 分鐘,系統產生一次系統時間標記與scn 的匹配並存入sys.smon_scn_time 表,
該表中記錄了最近1440個系統時間標記與scn 的匹配記錄,由於該表只維護了最近的1440 條記錄,
因此如果使用as of timestamp 的方式則只能flashback 最近5 天內的資料(假設系統是在持續不斷
執行並無中斷或關機重啟之類操作的話)。
注意理解系統時間標記與scn 的每5 分鐘匹配一次這句話,舉個例子,
比如scn:339988,339989 分別匹配08-05-3013:52:00 和2008-13:57:00,
則當你通過as of timestamp 查詢08-05-30 13:52:00 或08-05-30 13:56:59 這段時間點內的時間時,
oracle 都會將其匹配為scn:339988 到undo 表空間中查詢,
也就說在這個時間內,不管你指定的時間點是什麼,
查詢返回的都將是08-05-30 13:52:00 這個時刻的資料。

檢視SCN 和 timestamp 之間的對應關係:
[email protected]> select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;

       SCN TO_CHAR(TIME_DP,'YY
---------- -------------------
    999115 2014-06-28 07:22:51
   1020280 2014-06-28 07:29:04
   1133573 2014-07-01 00:42:16
   1135161 2014-07-01 00:47:14
   1137299 2014-07-01 00:51:50
   1137910 2014-07-01 00:52:28
   1138324 2014-07-01 00:57:29
   1138782 2014-07-01 01:00:59

以下省略。

4.1.5  Flashback Query 函式,儲存過程,包,觸發器等物件
Flashback Drop 可以閃回與表相關聯的物件, 如果是其他的物件,
比如function,procedure,trigger等。 這時候,
就需要使用到ALL_SOURCE 表來進行Flashback Query。

先看聯機文件對該表的說明:
ALL_SOURCE describes the text source of the stored objects accessible to the current user.

Related Views
DBA_SOURCE  describes the text source of all stored objects in the database.
USER_SOURCE describes the text source of the stored objects owned by the current user.
            This view does not display the OWNER column.

Column Datatype      NULL     Description
OWNER   VARCHAR2(30)  NOT NULL Owner of the object
NAME   VARCHAR2(30)  NOT NULL Name of the object
TYPE   VARCHAR2(12)           Type of object: FUNCTION, JAVA SOURCE, PACKAGE,
                                PACKAGE BODY, PROCEDURE, TRIGGER, TYPE, TYPE BODY
LINE   NUMBER        NOT NULL Line number of this line of source
TEXT   VARCHAR2(4000)         Text source of the stored object
--可參見Oracle Database Reference 11g Release 2 (11.2)中ALL_SOURCE。

如果我們誤刪除了某些物件,如procedure,就可以使用all_source 表進行恢復。
[email protected]> desc dba_source;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 OWNER                                              VARCHAR2(30)
 NAME                                               VARCHAR2(30)
 TYPE                                               VARCHAR2(12)
 LINE                                               NUMBER
 TEXT                                               VARCHAR2(4000)

檢視dba_source 的所有type
[email protected]> select type from dba_source group by type;

TYPE
------------
PROCEDURE
PACKAGE
PACKAGE BODY
LIBRARY
TYPE BODY
TRIGGER
FUNCTION
JAVA SOURCE
TYPE

9 rows selected.


基於timestamp恢復的語句
SQL>SELECT text
    FROM dba_source
         AS OF TIMESTAMP TO_TIMESTAMP ('XXXXX', 'YYYY-MM-DD HH24:MI:SS')
   WHERE owner = 'XXXX' AND name = '你刪除的物件名'
   ORDER BY line;

示例:
建立函式:

SQL>
CREATE OR REPLACE function getdate return date
as
   v_date date;
begin
   select  sysdate into v_date from dual;
   return v_date;
end;
/

Function created.

查詢函式:
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';

Session altered.

SQL> select getdate() from dual;

GETDATE()
-------------------
2011-04-07 21:02:09

查詢dba_source 表:

SQL> select text from dba_source where name='GETDATE' order by line;

TEXT
--------------------------------------------------------------------------------
function getdate return date
as
   v_date date;
begin
   select  sysdate into v_date from dual;
   return v_date;
end;

7 rows selected.

 
drop 函式,再查詢,記錄不存在

SQL> drop function getdate;

Function dropped.

SQL> select text from dba_source where name='GETDATE' order by line;

no rows selected

使用我們的Flashback Query 查詢:

SQL> select text from dba_source as of timestamp to_timestamp('2011-04-07 21:02:09','yyyy-mm-dd hh24:mi:ss') where name='GETDATE' order by line;

TEXT
--------------------------------------------------------------------------------
function getdate return date
as
  v_date date;
begin
   select  sysdate into v_date from dual;
   return v_date;
end;

7 rows selected.

這時候,又檢視到了函式的程式碼,只需要把這些程式碼重新執行一下就ok了。 其他物件和這個類似。
這裡就不演示了。

4.2  Flashback version Query
相對於Flashback Query 只能看到某一點的物件狀態,
Oracle 10g引入的Flashback Version Query可以看到過去某個時間段內,
記錄是如何發生變化的。 根據這個歷史,DBA就可以快速的判斷資料是在什麼時點發生了錯誤,
進而恢復到之前的狀態。
先看一個偽列 ORA_ROWSCN.  所謂的偽列,就是假的,不存在的資料列,使用者建立表時雖然沒有指定,
但是Oracle為了維護而新增的一些內部欄位,這些欄位可以像普通檔案那樣的使用。
最熟悉的偽列就是 ROWID, 它相當於一個指標,指向記錄在磁碟上的位置。
ORA_ROWSCN 是Oracle 10g 新增的,暫且把它看作是記錄最後一次被修改時的SCN。
Flashback Version Query 就是通過這個偽列來跟蹤出記錄的變化歷史。

舉個例子:
SQL> select * from A;

        ID
        ----------
         2
         1
         3
         4

SQL> insert into A values(5);

已建立 1 行。

SQL> select * from A;

        ID
        ----------
         2
         1
         3
         4
         5

SQL> commit;

提交完成。

SQL> select ora_rowscn, id from A;

ORA_ROWSCN       ID
----------             ----------
   1098443          2
   1098443          1
   1098443          3
   1098443          4
   1098443          5

獲取更多的歷史資訊
SQL>Select versions_xid,versions_startscn,versions_endscn,  
           DECODE(versions_operation,
                  'I','Insert',
                  'U','Update',
                  'D','Delete', 'Original') "Operation",
           id
    from A versions between scn minvalue and maxvalue;

或者
SQL>select xid,commit_scn,commit_timestamp,operation,undo_sql
    from flashback_transaction_query q
    where q.xid in(select versions_xid
                   from B versions between scn 413946 and 413959);
                  
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio    ID
---------------- ----------------- --------------- -------- ----------
05001A0054020000           1099482               Update            3
05001A0054020000           1099482               Delete            3
05001A0054020000           1099482               Delete            2
05001A0054020000           1099482               Delete            1
0400150005020000           1098443                Insert           5

下面我們來講下偽列, Flashback Version Query 技術其實有很多偽列,
但是ORA_ROWSCN是最重要。它記錄的是最後一次被修改時的SCN, 注意是被提交的修改。
如果沒有提交,這個偽列不會發生變化。
ORA_ROWSCN 預設是資料塊級別的,也就是一個數據塊內的所有記錄都是一個ORA_ROWSCN,
資料塊內任意一條記錄被修改,這個資料庫塊內的所有記錄的ORA_ROWSCN都會同時改變。
上例的查詢結果以證明。
不過我們可以在建表時使用關鍵字 rowdependencies, 可以改變這種預設行為,
使用這個關鍵字後,每條記錄都有自己的ORA_ROWSCN。

舉例:

SQL> create table B (id number(2)) rowdependencies;

表已建立。

SQL> insert into B values(1);

已建立 1 行。

SQL> insert into B values(2);

已建立 1 行

SQL> insert int