閃回資料庫(flashback database)知識分享

hd_system發表於2016-11-10
閃回資料庫(flashback database)——依賴的是閃回日誌:
1.  一旦啟用了閃回資料庫,修改的塊的前映像會不時地從資料庫緩衝區的快取中複製到SGA內的一個新的儲存區域中,即閃回緩衝區。透過一個新的後臺程式——恢復寫入器(RVWR)把此閃回緩衝區重新整理到磁碟和閃回日誌。這沒有改變向日志緩衝區寫入更改的常規程式,LGWR(日誌寫入器)然後將日誌緩衝區重新整理到磁碟;閃回日誌記錄是此操作的附屬物。不同於重做日誌,不能多路複用和歸檔閃回日誌,閃回日誌是自動建立和管理的。
閃回日誌在哪裡?
SQL> show parameter recovery
NAME                  TYPE   VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest             string /orcldata/fast_recovery_area
db_recovery_file_dest_size        big integer 4182M
recovery_parallelism          integer    0
SQL> !
[william@orcl ~]$ cd /orcldata/fast_recovery_area/
ORCL
[william@orcl fast_recovery_area]$ cd ORCL/flashback/
[william@orcl flashback]$ pwd
/orcldata/fast_recovery_area/ORCL/flashback  #這裡就是閃回日誌所在的位置
[william@orcl flashback]$ ls
o1_mf_b1htdog9_.flb  o1_mf_b1htdt8x_.flb
恢復寫入器是哪個?
[william@orcl ~]$ ps -ef|grep "william"
william   3128     1  0 09:11 ?        00:00:00 /opt/app/william/product/11.2.0/dbhome_1/bin/tnslsnr LISTENER -inherit
william   3221     1  0 09:11 ?        00:00:00 ora_pmon_orcl
william   3223     1  0 09:11 ?        00:00:00 ora_psp0_orcl
william   3225     1  0 09:11 ?        00:00:08 ora_vktm_orcl
william   3229     1  0 09:11 ?        00:00:00 ora_gen0_orcl
william   3231     1  0 09:11 ?        00:00:00 ora_diag_orcl
william   3233     1  0 09:11 ?        00:00:00 ora_dbrm_orcl
william   3235     1  0 09:11 ?        00:00:01 ora_dia0_orcl
william   3237     1  0 09:11 ?        00:00:00 ora_mman_orcl
william   3239     1  0 09:11 ?        00:00:00 ora_dbw0_orcl
william   3241     1  0 09:11 ?        00:00:00 ora_lgwr_orcl
william   3243     1  0 09:11 ?        00:00:00 ora_ckpt_orcl
william   3245     1  0 09:11 ?        00:00:00 ora_smon_orcl
william   3247     1  0 09:11 ?        00:00:00 ora_reco_orcl
william   3249     1  0 09:11 ?        00:00:01 ora_mmon_orcl
william   3251     1  0 09:11 ?        00:00:00 ora_mmnl_orcl
william   3253     1  0 09:11 ?        00:00:00 ora_d000_orcl
william   3255     1  0 09:11 ?        00:00:00 ora_s000_orcl
william   3262     1  0 09:11 ?        00:00:00 ora_rvwr_orcl  #這個就是恢復寫入器
william   3265     1  0 09:11 ?        00:00:00 ora_arc0_orcl
william   3267     1  0 09:11 ?        00:00:00 ora_arc1_orcl
william   3269     1  0 09:11 ?        00:00:00 ora_arc2_orcl
william   3271     1  0 09:11 ?        00:00:00 ora_arc3_orcl
william   3273     1  0 09:11 ?        00:00:00 ora_fbda_orcl
william   3275     1  0 09:11 ?        00:00:00 ora_qmnc_orcl
william   3289     1  0 09:11 ?        00:00:00 ora_cjq0_orcl
william   3435     1  0 09:11 ?        00:00:00 ora_q000_orcl
william   3437     1  0 09:11 ?        00:00:00 ora_q001_orcl
william   3500     1  0 09:16 ?        00:00:00 ora_smco_orcl
william   4285     1  0 10:36 ?        00:00:00 oracleorcl (LOCAL=NO)
william   4287     1  0 10:36 ?        00:00:00 oracleorcl (LOCAL=NO)
root      4292  2817  0 10:38 ?        00:00:00 sshd: william [priv]
william   4294  4292  0 10:38 ?        00:00:00 sshd: william@pts/0
william   4295  4294  0 10:38 pts/0    00:00:00 -bash
william   4377     1  0 10:46 ?        00:00:00 ora_w000_orcl
william   4460  4295  0 10:56 pts/0    00:00:00 ps -ef
william   4461  4295  0 10:56 pts/0    00:00:00 grep william
2.  與閃回資料庫有關的初始化引數:
undo_management              string AUTO                      #只有在自動回滾段管理的情況下才能使用閃回資料庫?
undo_tablespace                  string UNDOTBS1                  #預設的回滾表空間
db_recovery_file_dest            string /orcldata/fast_recovery_area   #指定閃回日誌儲存位置
db_recovery_file_dest_size       big integer 4182M                    #指定db_recovery_file_dest的上限,與db_flashback_retention_target組合作用
db_flashback_retention_target   integer    1440                       #指定閃回日誌支援的回滾時間的上限(單位min),與db_recovery_file_dest_size組合作用
3.  預定義的條件:
u  啟用歸檔模式。
因為Oracle並不是把所有變化都複製到閃回緩衝區,只是這些變化的一個子集。如果把全部塊的所有變化複製到緩衝區,就記憶體使用和把緩衝區重新整理到磁碟所需的額外I/O壓力來說,這些開銷會削弱資料庫效能。Oracle內部演算法限制把哪些塊的哪些版本複製到閃回緩衝區,以便限制閃回緩衝區以及寫入磁碟的大小和頻率。這些演算法的初衷是在啟用閃回資料庫時確保不會對效能造成負面影響,保證即使很繁忙的塊的記錄頻率也很低。
當執行資料庫閃回時,Oracle會讀取閃回日誌以提取每個改變的資料庫塊的版本,並將這些版本複製回資料檔案。因為這些變化是按照逆時間的順序應用到當前資料庫的,這樣做的效果是透過反轉DBWn程式執行的寫入操作及時回退資料庫。
由於不是把每個變化的塊的所有版本都複製到閃回緩衝區和隨後的閃回日誌中,因此不可能閃回到某個精確的時間點。閃回操作將盡可能接近期望的時間(不晚於該時間)回退每個更改的塊。因此閃回資料庫構造一個恰好在希望的時間點之前的資料庫檔案版本。資料檔案的這種版本可能完全不一致。要完成閃回過程,Oracle需要使用重做日誌,把所有的塊嚴格恢復到請求的時間,因而把所有資料檔案同步到相同的SCN上。最後一個階段是回滾在那個時間點還未提交的任何事務——與不完整恢復的最後一個階段所做的操作相同。
因此,閃回資料庫實際上是多個程式和資料結構的組合。首先,必須在SGA中分配一些記憶體(自動的,無法控制閃回緩衝區的大小)並在磁碟上分配一些空間來儲存閃回資料,同時啟動RVWR程式來支援閃回日誌記錄。當執行閃回時,Oracle會使用閃回日誌將資料庫及時回退到期望的時間之前的某個時間點,然後按照不完整恢復中的常規方式應用重做日誌(歸檔或聯機的重做日誌),以便將資料檔案前滾到希望的確切時間。然後可以按照與普通的不完整恢復採用的相同方式,open resetlogs開啟資料庫。
4.  配置閃回資料庫
SQL> archive log list;
Database log mode          Archive Mode
Automatic archival         Enabled
Archive destination        /orcldata/archivelog
Oldest online log sequence     3
Next log sequence to archive   5
Current log sequence          5
SQL> alter system set db_recovery_file_dest='/orcldata/fast_recovery_area';
System altered.
SQL> alter system set db_recovery_file_dest_size=4182M;
System altered.
SQL> alter system set db_flashback_retention_target=1440;
System altered.
SQL> show parameter undo_management
        NAME                     TYPE   VALUE
------------------------------------ ----------- ------------------------------
undo_management              string AUTO
SQL> alter database flashback on;
Database altered.
5.  監視閃回資料庫
閃回保留時間只是一個目標時間——實際上並不保證能閃回到其內的某個時間。相反,甚至可能閃回到該目標時間之外。可獲得的閃回期限是每秒鐘生成的閃回日誌資訊量和在使用更新的資料重寫它們之前可供儲存這些資訊的空間量的一個函式。
最基本的層次是確認確實啟用了閃回資料庫:
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
在Unix/Linux上可以看到RVWR程式是一個作業系統程式;在Windows上它將是ORACLE.EXE內的另一個執行緒。
為了監視當前的閃回能力並估計為滿足目標時間閃回日誌所需的空間,可以查詢V$FLASHBACK_DATABASE_LOG檢視。V$FLASHBACK_DATABSE_STAT提供了一個有關資料檔案、聯機重做日誌檔案盒閃回日誌檔案所佔磁碟I/O比例的歷史檢視。
SQL> select retention_target,flashback_size,to_char(oldest_flashback_time,'yyyy-mm-dd hh24:mi:ss') from v$flashback_database_log;
RETENTION_TARGET FLASHBACK_SIZE TO_CHAR(OLDEST_FLAS
---------------- -------------- -------------------
1440      209715200 2014-09-17 11:29:10
RETENTION_TARGET:閃回日誌保留目標時間(1440min)
FLASHBACK_SIZE:閃回日誌檔案佔用的實際空間(209715200位元組)
oldest_flashback_time:可以把資料庫回退到的確切時間(2014-09-17 11:29:10)
SQL> select to_char(end_time,'yyyy-mm-dd hh24:mi:ss') end_time,flashback_data,db_data,redo_data from v$flashback_database_stat;
END_TIME        FLASHBACK_DATA    DB_DATA  REDO_DATA
------------------- -------------- ---------- ----------
2014-09-17 12:52:49     278528     188416     112128
2014-09-17 12:44:35    4767744    7028736   2294784
顯示為了啟用閃回資料庫而付出的代價,計量單位是每小時必需的I/O位元組數。首行總是顯示到當前時間為止。
Flashback_data:每小時產生的閃回日誌大小
Db_data:每小時產生的資料檔案大小
Redo_data:每小時產生的重做日誌大小
SQL> select * from v$sgastat where name='flashback generation buff';
POOL         NAME                BYTES
------------ -------------------------- ----------
shared pool  flashback generation buff    15937344   #≈15M
閃回緩衝區的大小不受DBA控制,但是要檢視其當前大小,查詢V$SGASTAT檢視。
6.  使用閃回資料庫
SQL> conn hr/hr
Connected.
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2014-09-17 11:32:19
SQL> desc employees
Name                      Null?    Type
----------------------------------------- -------- ----------------------------
EMPLOYEE_ID                   NOT NULL NUMBER(6)
FIRST_NAME                     VARCHAR2(20)
LAST_NAME                 NOT NULL VARCHAR2(25)
EMAIL                     NOT NULL VARCHAR2(25)
PHONE_NUMBER                       VARCHAR2(20)
HIRE_DATE                 NOT NULL DATE
JOB_ID                    NOT NULL VARCHAR2(10)
SALARY                         NUMBER(8,2)
COMMISSION_PCT                     NUMBER(2,2)
MANAGER_ID                     NUMBER(6)
DEPARTMENT_ID                      NUMBER(4)
SQL> update employees set last_name='WENG' where employee_id=199;
1 row updated.
SQL> commit;
Commit complete.
SQL> conn / as sysdba
Connected.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 1653518336 bytes
Fixed Size          2253784 bytes
Variable Size       1023413288 bytes
Database Buffers      620756992 bytes
Redo Buffers            7094272 bytes
Database mounted.
SQL> flashback database to timestamp to_timestamp('2014-09-17 11:32:19','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01589: must use RESETLOGS or NORESETLOGS option for database open
SQL> alter database open resetlogs;
Database altered.
SQL> conn hr/hr
Connected.
SQL> select * from employees where employee_id=199;
EMPLOYEE_ID FIRST_NAME      LAST_NAME         EMAIL             PHONE_NUMBER     HIRE_DATE    JOB_ID          SALARY COMMISSION_PCT MANAGER_ID DEPARTMENT_ID
----------- -------------------- ------------------------- ------------------------- -------------------- ------------ ---------- ---------- -------------- ---------- -------------
    199 Douglas     Grant             DGRANT            650.507.9844     13-JAN-08    SH_CLERK     2600               124        50
7.  限制生成的閃回資料量
啟用閃回資料庫可能對聯機效能造成影響。Oracle用來限制寫到閃回日誌中的資料量的演算法是精心設計的,以便儘量減小對效能的影響,但是(尤其是在有I/O限制的系統上)可能希望進一步降低其影響。在一些環境中,還可能發現滿足目標時間生成的閃回資料量過大,可以在閃回日誌中不記錄表空間,但是這樣恢復過程稍微複雜些。
預設情況下,如果啟用了閃回資料庫,那麼會記錄所有表空間的閃回資料。使用如下命令關閉表空間閃回屬性:
alter tablespace flashback off;
可以在任何時候執行上面或在資料庫處於mounted模式時執行下面的命令:
alter tablespace flashback on;
V$TABLESPACE檢視提供了flashback_on列標記是否為表空間啟用閃回:
SQL> select name, flashback_on from v$tablespace;
NAME                   FLA
------------------------------ ---
SYSTEM                 YES
SYSAUX                 YES
UNDOTBS1               YES
USERS                  YES
TEMP                   YES
EXAMPLE                YES
FBDA                   YES
對於那些與資料庫的其餘部分相比可以容忍較長停機時間的表空間、只要願意可以隨時刪除的表空間或可以快速還原和恢復的表空間來說,可以考慮不執行閃回操作。
如果一個或多個表空間不生成閃回資料,那麼在執行閃回操作之前必須使構成表空間的檔案離線。然後閃回(包括隱式的恢復)可以正常進行。要記住RECOVER將忽略離線資料檔案——這與FLASHBACK是相同的。
在刪除了構成離線表空間的資料檔案或將他們還原和恢復到與閃回相同的時間點之前,不能開啟資料庫(使用或不使用REDETLOGS)。刪除它們是極端的做法 ,但是,如果它是一個能夠適時刪除和重新建立的表空間,並且可以重新例項化表空間內的物件,那麼這樣做可以最小化停機時間。否則在閃回操作後使構成表空間的資料檔案聯機。然後,還原它們並執行不完整恢復,一直到閃回的時間點。這樣做將同步所有資料檔案,並且隨後可以使用RESETLOGS開啟它們。
閃回資料歸檔——依賴歸檔的閃回資料
1.  閃回資料庫、閃回刪除和各種形式的閃回查詢很有用,但是它們的閃回能力都有限。可以配置閃回資料歸檔保證將表閃回到過去任何時間——可能是多年之前的某個時間。閃回資料歸檔還能保證資料過期時予以刪除。
2.  從體系結構上看,閃回資料歸檔要求一個或多個表空間、用於每個受保護的表的各種段以及一個新的後臺程式:FBDA程式,DBA必須建立表空間和其內部的歸檔,為每個歸檔指定保留期限並指定由歸檔保護的表。將會自動建立必需的段並且會根據要求啟動FBDA。就DML來說,使用者和應用不會意識到任何變化。一些DDL命令(eg.DROP和TRUCNCATE)不適用於受保護的表,因為它們將從資料字典中刪除解釋歸檔中的資訊所必需的一些資訊。可以在保護表的歸檔指定的時間段內,對錶的各種版本成功執行閃回查詢命令(如有AS OF子句的SELECT命令)。
3.  為了使用閃回資料歸檔實現的Total Recall功能,首先建立一個表空間。然後建立歸檔、指定表空間、保留時間和一個可選的配額。例如:
create flashback archive default hrarch tablespace fbda quota 10g retention 5 year;
該命令包括default關鍵字,意味著除非另行說明,它將用作所有表的歸檔。另外,也可以稍後設定預設的歸檔:
alter flashback archive hrarch set default;
quota子句顯示歸檔在表空間中佔用的空間。如果歸檔失敗,就可以在原有的表空間或另一個表空間新增更多的空間。例如,下面的命令將歸檔擴充套件到另一個表空間中:
alter flashback archive hrarch add tablespace fbda2 quota 10g;
也可以調整保留時間:
alter flashback archive hrarch modify retention 7 year;
一旦資料超過了指定的保留期限,將有FBDA後臺程式自動從歸檔中刪除。但是在資料過期之前也可以手工刪除,例如:
alter flashback archive hrarch purge before timestamp to_timestamp('01-01-2009','dd-mm-yyy');
由於管理歸檔的權力往往牽涉到法律問題,因此透過設定許可權來保護它。FLASHBACK ARCHIVE ADMINISTER系統許可權能夠建立、修改或刪除歸檔以及控制歸檔的保留和清除。因此,必須授予使用者歸檔的FLASHBACK ARCHIVE許可權以便能夠對錶進行歸檔:
grant flashback archive administer to fbdaadmin;
grant flashback archive on hrarch to hr;
最後,為了啟用表的歸檔保護,使用如下命令:
alter table hr.employees flashback archive hrarch;
4.  有三個資料字典檢視來記錄閃回資料歸檔配置:
DBA_FLASHBACK_ARCHIVE描述配置的歸檔。
DBA_FLASHBACK_ARCHIVE_TS顯示每個表空間的每個歸檔分配的配額。
DBA_FLASHBACK_ARCHIVE_TABLES列出了啟用了歸檔的表。
5.  使用閃回資料歸檔:
(1) 建立一個供閃回資料歸檔使用的表空間:
create tablespace fbda datafile 'fbda01.dbf’ size 2g;
(2) 在上述表空間建立一個保留時間20天的閃回資料歸檔:
create flashback archive fbdaarch tablespace fbda retention 20 day;
(3) 建立用於練習的模式,並授予它DBA角色:
grant dba to fbdauser identified by fbdauser;
(4) 授予使用者操作歸檔的必要許可權:
grant flashback archive on fbdaarch to fbdauser;
(5) 作為fbdauser連線。建立一個表併為此表啟用閃回資料歸檔:
connect fbdauser/fbdauser
create table t1 as select * from all_users;
alter table t1 flashback archive fbdaarch;
(6) 執行下列查詢確定歸檔建立的物件。可能必須等待幾分鐘,因為物件不是立即建立的。
select object_name,object_type from user_objects;
select segment_name,segment_type from dba_segments where tablespace_name='FBDA';
(7) 對保護的表執行一些DML:
delete from t1;
commit;
(8) 使用標準的閃回查詢語法對保護的表執行閃回查詢,然後查詢歸檔中的歷史表。歷史表的名稱將顯示在步驟6中。
Select * from t1 as of timestamp(sysdate – 20/1440);
(9) 嘗試對保護的表執行一些DDL命令:
alter table t1 drop column created;
truncate table t1;
drop table t1;
作為SYSDBA連線,並嘗試執行如下命令:
drop user fbdauser cascade;
drop tablespace fbda including contents and datafiles;
注意,這些命令將會生成與歸檔和保護的表的存在有關的錯誤。
(10) 刪除表的歸檔保護:
alter table fbdauser.t1 no flashback archive;
(11) 刪除閃回資料歸檔:
drop flashback archive fbdaarch;
(12) 重新執行步驟(9)中的所有命令。
閃回刪除——flashback dop,針對drop掉的段,依賴於回收站recyclebin(回收站實際上仍舊是表空間的一部分儲存空間,需要重用時,要釋放出來)
1.  閃回刪除允許將之前刪除的表(非截斷)恢復到剛好刪除它之前的狀態,同時還會恢復所有索引以及任何觸發器和許可權。唯一的主鍵和非空約束也會被恢復——但不包括外來鍵約束。
flashback drop命令僅適用於表,但是也會恢復所有相關的物件——外來鍵約束除外。
2.  閃回刪除的實現:
直到(包括)9i版本的Oracle資料庫為止,刪除一個表時,到該表的所有引用都會從資料字典中刪除。過去的DROP TABLE命令的原始碼實際上是在定義了表及其空間佔用的SYS模式中的一系列針對各種表的DELETE命令,後面跟著一個COMMIT命令。實際上並沒有將資料從磁碟上清除,但是刪除的表佔用的空間被標記為未使用,因而空間可以重用。儘管表的資料塊仍存在,但是無法找到它們,因為資料字典沒有記錄哪些塊屬於刪除的表。恢復刪除的標的唯一方法是執行時間點恢復,還原在刪除表之前資料字典仍瞭解該表狀態時的一個資料庫版本。
從10g版本開始,DROP TABLE命令的實現方法完全不一樣了。在這些版本的資料庫中根本沒有刪除表,而只是重新命名它們。已經在內部將DROP TABLE命令對映到RENAME命令,它將作用於表及其所有相關的索引、觸發器和約束,但不包括外來鍵約束(它將被刪除)。必須物理地刪除外來鍵約束,如果要維護它們,即使採用不同的名稱,未刪除的父表上的DML將會受刪除的表的內容約束,這將很荒誕。
表的授權沒有名稱,因此無法重新命名它們。當授予一個物件許可權時,透過名稱指定物件並且底層儲存的授權透過它的物件號來引用該物件。由於RENAME操作並沒有改變物件號,因此授權仍然是有效的。
就常規的SELECT和DML語句而言,刪除的表肯定是被刪除了。對於任何其他命令來說也是一樣,並且所有軟體都假定刪除的表確實是消失了。但既然DROP實際上是RENAME,就有可能撤銷刪除——透過將表重新命名回它原先的名稱。但是,並不能保證這樣做總能成功。因為刪除的表佔用的空間有可能被重用,並且還會出現更復雜的情況,比如在此期間建立了另一個表,並且重用了與刪除的表相同的名稱。
透過檢視回收站獲取它們的新名稱可以查詢刪除的物件。這裡列出了已刪除的所有物件,並將原始的表和索引名稱對映到刪除物件的系統生成的名稱。每個使用者都有一個回收站,可以在USER_RECYCLEBIN資料字典檢視中看到它,若要了解全域性檢視,可以查詢DBA_RECYCLEBIN。當表空間的空間不足時,可以自動重用回收物件佔用的空間(此後不能恢復物件),或者可以手動強制Oracle使用PURGE命令真正刪除物件。
使用flashback drop不能保證成功執行,但是很可能會生效。越早執行該命令,成功的可能性就越大。
3.  使用閃回刪除
Drop命令將表重新命名為系統生成的名稱,閃回刪除可以恢復它。
   真正刪除表
drop table <table_name> purge;
purge關鍵字指示Oracle資料庫恢復DROP的原始含義:刪除到該表的所有引用並且永遠無法恢復。
   閃回表並重新命名(有時重新命名時必須的,以防在刪除和閃回期間建立了另一個與刪除的表具有相同名稱的表)
flashback table <table_name> to before drop rename to <new_name>;
注意,儘管在閃回期間可以對錶重新命名,但不能更改模式:所有閃回操作出現在物件所屬的模式內。和表一同閃回的索引、觸發器和約束都保持它們的回收站名稱。如果希望恢復它們原先的名稱,則可以在閃回操作後手動重新命名。必須要強調兩點。第一,flashback drop只能恢復drop命令,而不能恢復truncate命令。第二,如果刪除了一個使用者,使用閃回無法恢復任何該使用者的表。刪除模式意味著Oracle根本無法維護物件(即使在回收站內),因為沒有可供物件連線的使用者。
4.  SQL*Plus命令show recyclebin將顯示刪除的物件,連同它們原始的名稱和回收站名稱。DBA_RECYCLEBIN檢視提供了相同(甚至更多)的資訊。
如果刪除了表,然後建立了具有相同名稱的另一個表,並且隨後也刪除了它,那麼在回收站中將有兩個表。它們具有不同的回收站名稱,但是原始名稱相同。預設情況下,flashback drop命令總是恢復最新版本的表,但是,如果這不是您想要的版本,則可以指定您希望恢復的版本的回收站名稱,而不是原先的名稱。例如:
SCOTT@orcl>drop table bonus;
Table dropped.
SCOTT@orcl>show recyclebin
ORIGINAL NAME   RECYCLEBIN NAME        OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
BONUS       BIN$A6Kgm8gMEePgUwEAAH++3A==$0 TABLE        2014-09-22:14:37:16
SCOTT@orcl>flashback table "BIN$A6Kgm8gMEePgUwEAAH++3A==$0" to before drop;
Flashback complete.
SCOTT@orcl>desc bonus
Name                      Null?    Type
----------------------------------------- -------- ----------------------------
ENAME                          VARCHAR2(10)
JOB                            VARCHAR2(9)
SAL                            NUMBER
COMM                           NUMBER
5.  管理回收站
回收站是表示刪除的物件使用的儲存空間的一個術語。可以完全忽略回收站——它的管理是自動的,無論是在刪除物件時將它們轉移到回收站,還是在活動物件的表空間需要空間時,都將它們永久清除。但是有些情況下需要了解回收站的內容以及它們佔用的空間大小。
可以使用例項引數RECYCLEBIN禁用回收站,預設值是ON,意味著所有模式都有一個回收站。該引數是動態的,可以為某個會話或整個系統將其設定為OFF。
查詢回收站
SCOTT@orcl>show recyclebin
ORIGINAL NAME    RECYCLEBIN NAME        OBJECT TYPE  DROP TIME
---------------- ------------------------------ ------------ -------------------
BONUS        BIN$A6Kgm8gMEePgUwEAAH++3A==$0 TABLE        2014-09-22:14:37:16
若要了解更詳細的資訊,查詢資料字典檢視USER_RECYCLEBIN或DBA_RECYCLEBIN:
select owner,original_name,type,droptime,can_undrop,space from dba_recyclebin;
關鍵的列是can_undrop。Oracle並不負責儲存刪除的表或索引:flashback drop完全是Oracle提供的一個便利功能,並不屬於關聯式資料庫標準。如果Oracle需要刪除的物件佔用的空間以便為活動物件分配更多的空間,它可以重用該空間——但是從那以後使用flashback drop將無法恢復刪除的物件,並且將從檢視中清除它。Space列(單位是資料檔案塊)顯示刪除的物件佔用的空間量。
6.  回收回收站的空間
刪除的物件佔用的空間處於不明確的狀態:雖然將它分配給物件,但是Oracle可以任意重寫它。有關空間使用的正常診斷程式會忽略回收站佔用的空間,這意味著在活動物件佔用的空間達到警告和臨界空間使用級別之前,不會觸發“表空間比例已滿”的警報。此外,如果啟用了資料檔案的autoextend特性,Oracle實際上不會自動擴充套件資料檔案,直到重新分配了刪除的物件佔用的所有空間:它將優先重寫回收站以增加資料檔案大小。
如果一個新資料段的表空間需要空間,那麼可以佔用它——但是此後將無法在保留刪除的表。如果在回收站中有許多刪除的物件,Oracle將會首先重寫在回收站中留存時間最長的物件。這種先進先出演算法假定最近刪除的物件最有可能充當閃回的候選物件。
可以使用各種形式的PURGE命令永久性地清除刪掉的物件:
dop table <table_name> purge;_除表並且不將它轉移到回收站。
prge table <table_name>;——從回收站中清除表。
如果存在多個具有相同原始名稱的物件,那麼將清除時間最久的物件。也可以透過指定回收站名稱來避免混淆。
purge index <index_name>;——從回收站中清除索引,同樣可以指定原始名稱或回收站名稱。
purge tablespace <tablespace_name>;——從表空間中清除所有刪除的物件。
purge tablespace <tablespace_name> user <user_name>;——從表空間中清除屬於一個使用者的所有刪除的物件。
purge user_recyclebin;——清除刪除的所有物件。
purge dba_recyclebin;——清除資料庫上被刪除的所有物件,需要DBA許可權。
***********************************************************************************************
閃回查詢——依賴的是回滾段
自從Oracle9i釋出以來就提供了基本形式的閃回查詢:可以查詢過去某個時間的資料庫狀況。工作原理是將查詢制定的時間對映到一個系統變更號和SCN,每當查詢找到自該SCN以來更改的一個快,它將轉到撤銷段以提取回滾此更改所需的撤銷資料。嚴格上說這種回滾是臨時性的,並且僅對執行閃回查詢的會話可見。顯然,為了成功執行閃回查詢,撤銷資料必須是可用的。

在後續版本的資料庫中,大大增強了閃回查詢功能,現在它可以用來檢索一個行的所有版本,反轉各個事務,或反轉某個時間以來對錶做出的所有更改。當然,也可以保證閃回成功執行——但是做到這一點要付出代價:它可能會引起事務失敗。

所有形式的閃回查詢依賴撤銷資料來重構它在過去某個時間點的資料。

1.  基本的閃回查詢

任何select語句可以針對以前某個版本的表。

select * from regions as of timestamp to_timestamp('2014-09-22 15:27:31', 'yyyy-mm-dd hh24:mi:ss');

儘管針對過去某個時間點的資料執行查詢是有用的,但有時也希望完成一系列選擇。透過使用DBMS_FLASHBACK程式包可以將整個回話回退到過去某個時間:

execute dbms_flashback.enable_at time( to_timestamp('2014-09-22 15:36:37', 'yyyy-mm-dd hh24:mi:ss'));

從此以後,所有的查詢將看到資料庫在指定的時間的狀態。其他所有會話將看到實時資料——但是在取消閃回之前這個會話將看到一個凍結版本的資料庫。

execute dbms_flashback.disable;

處於閃回模式時,無法執行DML命令。如果這樣做會丟擲錯誤,只能執行SELECT語句。

閃回查詢(透過一個查詢或使用dbms_flashback)可以回退到多久以前取決於撤銷段的內容。如果構造過時的結果集所需的撤銷資料不可用,那麼查詢將會失敗並給出一個ORA-08180錯誤訊息"No snapshot found based on specified time"。

啟用閃回查詢的語法接收時間戳或SCN。如果使用SCN,那麼閃迴轉到的時間點是精確的,如果指定某個時間,那麼它將對映到一個SCN上並且精度是3秒。

可以查詢以前某個時間點的資料庫,但是永遠不能對過去版本的資料執行DML。

2.  閃回表查詢

從概念上來說,表閃回很簡單。Oracle將會查詢撤銷段以提取已更改的所有行,然後構造並執行將會取消更改的語句。閃回操作是一個單獨的事務,如果可能,它就會抵消以前所有事務的效果。資料庫仍然保持聯機並且正常的執行不受影響,除非行鎖定成為一個問題。這不是回滾提交的工作,而是一個新事務用來取消已提交工作的影響。維護所有的索引並強制執行約束:表閃回只是另一種事務,通常的規則仍適用。不同於正常處理的唯一之處是,表上的觸發器對閃回操作預設是禁用的。

表閃回經常涉及一個存在外來鍵關係的表。這種情況下,幾乎不可避免的是閃回操作會因為違反約束而失敗。為了避免此問題,語法支援用一條命令閃回多個表,這將作為單位事務來執行,並且在最後檢查約束。

啟用表閃回的第一步是在表上支援行移動。這在資料字典中是設定標誌來通知Oracle可能改變了行ID。行ID實際上永遠不會改變——但是閃回操作可能使它看起來好像改變了。舉例來說,在刪除了一行的情況下閃回操作會將它重新插入到表中:它將具有相同的主鍵值,但是不同的行ID。

在下面的示例中有兩個表:EMP和DEPT。這兩個表存在外來鍵關係,就是說EMP表中的每個員工必定是DEPT表中某個部門的一個成員。

首先,插入一個新的部門並在該部門中插入一個員工,同時記錄時間:

insert into dept values(50, 'SUPPORT', 'LONDON');

insert into emp values (8000, 'WASTON', 'ANALYST',7566, '27-DEC-08',3000,null,50);

commit;

select sysdate from dual;

接下來刪除該部門和員工,要注意首先刪除員工以避免違反約束:

delete from emp where empno=8000;

delete from dept where deptno=50;

commit;

現在嘗試將表閃回到該部門和員工存在的時刻:

flashback table emp to timestamp ti_timestamp('27-12-08 18:30:11', 'dd-mm-yy hh24:mi:ss');

該操作會失敗,因為預設情況下沒有為任何表啟用行移動(作為表閃回的前提條件)——因此要為這兩個表啟用它:

alter table emp enable row movement;

alter table dept enable row movement;

現在重新嘗試閃回:

flashback table emp to timestamp to_timestamp('27-12-08 18:30:11', 'dd-mm-yy hh24:mi:ss');

這一次造成閃回失敗的原因更加微妙。閃回試圖透過插入此員工來取消對員工8000的刪除——但是員工8000屬於部門50,該部門已被刪除而不存在。因此,違反了外來鍵約束。解決方法是一起閃回這兩個表:

flashback table emp,dept to timestamp to_timestamp('27-12-08 18:30:11', 'dd-mm-yy hh24:mi:ss');

這樣閃回會成功,因為在一個事務中同時閃回了兩個表,並且僅在該事務的結尾檢查約束——到那個時候資料在邏輯上是一致的。

閃回也可能由於其他原因而失敗:

如果在刪除和閃回之間重用了鍵值,就會違反主鍵約束。

如果沒有足夠的撤銷資訊返回到請求的時間,就會引起一個錯誤ORA-08180,"No Snapshot found based on specified time"。

如果其他使用者鎖定閃回作用的任何行,則閃回會失敗並給出一條訊息ORA-00054: "Resource busy and acquire with NOWAIT specified"。

表定義在考察期間內不能改變——閃回不能跨越DDL。試圖這樣做會產生錯誤ORA-01466: "Unable to read data——table definition has changed"。

閃回不適用於處於SYS模式下的表,試著想象一下閃回部分資料字典的效果。

如果閃回由於任何原因而失敗,就會取消閃回操作:將回滾成功執行的任何一部分操作,並且表將處於閃回命令發出之前的狀態。

語法的變形允許閃回到一個系統變更號並在操作期間啟用DML觸發器:

flashback table emp,dept to scn 6539425 enable triggers;

3.  閃回版本查詢

一個行在它的生命週期內可能改變多次。閃回版本查詢(flashback version query)允許檢視一個行所有提交的版本(而不能檢視任何未提交的版本),包括建立和約束每個版本的時間戳。另外,還可以檢視建立了任何特定版本的行的事務的事務識別符號,然後可以將它用於閃回事務查詢。此資訊可以透過每個表可用的許多偽列來提供。與閃回相關的偽列包括:

versions_startscn:透過insert或update建立此版本的行的SCN

versions_starttime:建立此版本的行的時間戳

versions_endscn:由於delete或update使此版本的行失效的SCN

versions_endtime:此版本的行失效的時間戳

versions_xid:建立此版本的行的事務的唯一識別符號(這個xid可以用於閃回事務)

versions_operation:建立此版本的行的事務執行的操作,可以是insert、update或delete

為了檢視偽列,必須在查詢中包括versions between關鍵字。下面的查詢顯示了員工8000的行的所有版本:

select empno,ename,sal,versions_xid,versions_startscn,versions_endscn,versions_operation from emp versions between scn minvalue and maxvalue where empno=8000;

版本是按照存在時間的降序儲存的:必須自下而上讀取它們。

versions between子句使用兩個常量來表示SCN。minvalue指示Oracle檢索撤銷段中最早的資訊;maxvalue將作為當前的SCN。

查詢的語法也接受使用連個時間戳指定的時間範圍:

select empno,ename,sal,versions_xid,versions_startscn,versions_endscn,versions_operation from emp versions between timestamp (systimestamp-1/24) and systimestamp where empno=8000;

選在在最近一個小時記憶體在的員工編號為8000的行的所有版本。

閃回版本查詢不能用於外部表、臨時表或V$檢視。原因是這些物件都不生成撤銷資料。

4.  閃回事務查詢

閃回表和閃回版本查詢使用物件的撤銷資料。閃回事務查詢從一個不同的尺度來分析撤銷資料:它會檢索一個事務的所有撤銷資料,而不考慮它影響多少物件。關鍵的檢視是flashback_transaction_query。由於該檢視的資料比較敏感,透過設定許可權來保護它:在能夠查詢它之前必須授權select any transaction。在該檢視中撤銷資料仍儲存在撤銷段內的每個事務將對應一行或多行,並且每一行都會引用受該事務影響的一行。

一行SQL語句可能在flashback_transaction_query中生成許多行,這是因為SQL是一種集合型語言:一條語句可以影響多行。但是每個受影響的行在檢視中都有它自己的行,檢視會顯示提交的事務以及進行中的事務。對於活動事務來說,commit_scn和commit_timestamp列都是NULL,並且不顯示回滾的事務。

select operation,undo_sql from flashback_transaction_query where xid=hextoraw('06002600B0010000');

檢視flashback_transaction_query將構造撤銷語句來取消事務,但是對於大型事務而言,單個地執行它們是一項繁重的任務。這種情況下,可以使用dbms_flashback包:它含有取消事務的過程,但必須授予flashback any table許可權。

execute dbms_flashback.transaction_backout(numtxns=>2,xids=>sys,xid_array('0900010059100000', '02000700920F0000'),options=>dbms_flashback.cascade);

5.  閃回和撤銷資料

閃回查詢的各種形式完全取決於撤銷資料。查詢是否成功依賴於撤銷資料是否仍可用。

為了保證在給定的時間段閃回查詢總能成功,設定撤銷表空間的RETENTION GUARANTEE屬性以及UNDO_RETENTION例項引數。這將確保總能閃回指定的秒數——但付出的代價是,如果對於事務工作負荷來說撤銷表空間的大小設定的不夠大,那麼在執行DML時可能掛起資料庫。必須監視V$UNDOSTAT檢視來計算必需的撤銷表空間大小。

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

相關文章