程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle教程 >> Oracle學習(15)【DBA向】:閃回

Oracle學習(15)【DBA向】:閃回

編輯:Oracle教程

Oracle學習(15)【DBA向】:閃回


閃回Flashback

什麼是閃回

l在Oracle的操作工程中,會不可避免地出現操作失誤或者用戶失誤,例如不小心刪除了一個表等,這些失誤和錯誤可能會造成重要數 據的丟失,最終導致Oracle數據庫停止。
l在傳統意義上,當發生數據丟失、數據錯誤問題時,解決的主要辦法是數據的導入導出、備份恢復技術,這些方法都需要在發生錯誤 前,有一個正確的備份才能進行恢復。
l為了減少這方面的損失,Oracle提供了閃回技術。有了閃回技術,就可以實現數據的快速恢復,而且不需要數據備份。

閃回的好處

恢復中,閃回技術是革命性的進步 傳統的恢復技術緩慢: ?它是整個數據庫或者一個文件恢復,不只恢復損壞的數據 ?在數據庫日志中每個修改都必須被檢查 閃回速度快: ?通過行和事務把改變編入索引 ?僅僅改變了的數據會被恢復 閃回命令很容易: ?沒有復雜棘手的多步程序



閃回的類型


l閃回表(flashback table) 將表回退到過去的某個時間上,該時間在某個操作之前 l閃回刪除(flashback drop) 使用Oracle的回收站 l閃回版本查詢(flashback version query) select l閃回事務查詢(flashback transaction query) select ---> undo_sql
分別針對四種問題: 1. 錯誤地刪除了一條數據,並且commit 2. 錯誤地刪除了表 3. 如何查詢表上的歷史記錄 4. 如何撤銷一個已經提交了的事務

閃回表

閃回表,實際上是將表中的數據快速恢復到過去的一個是焦點或者系統改變號SCN上。實現表的閃回,需要使用到與撤銷表空間相關的undo信息,通過show parameter undo命令可以了解這些信息。
用戶對表數據的修改操作,都記錄在撤銷表空間中,這為表的閃回提供了數據恢復的基礎。例如,某個修改操作在提交後被記錄在撤銷表空間中,保留時間為900秒,用戶可以在這900秒的時間內對表進行閃回操作,從而將表中的數據恢復到修改之前的狀態。
執行表的閃回,需要有flashback any table的權限

閃回表的語法

FLASHBACK TABLE [schema.]<table_name>

TO

{[BEFORE DROP [RENAME TO table]]

[SCN|TIMESTAMP]expr

[ENABLE|DISABLE]TRIGGERS}


schema:模式名,一般為用戶名。 TO TIMESTAMP:系統郵戳,包含年、月、日、時、分、秒。 TO SCN:系統更改號, ENABLE TRIGGERS:表示觸發器恢復以後為enable狀態,而默認為disable狀態。 TO BEFORE DROP:表示恢復到刪除之前。 RENAME TO table:表示更換表名。

********************************************************** 注意:閃回表需要將表的行移動功能打開 ?alter table <table_name> enable row movement; **********************************************************

閃回表舉例

查詢某時間對應的SCN號: select to_char(sysdate,'yyyy-mm-dd hh24:mi:mm') 時間,timestamp_to_scn(sysdate) SCN from dual;


時間 SCN
------------------- ----------
2012-03-29 10:26:03 1066202

************************************************************************* 創建表,進行刪除操作,並閃 回完整示例:

create table flashback_table
2 (fid number,fname varchar2(20));


表已創建。


SQL> insert into flashback_table values(1,'Tom');


已創建 1 行。


SQL> insert into flashback_table values(2,'Mary');


已創建 1 行。


SQL> insert into flashback_table values(3,'Mike');


已創建 1 行。


SQL> commit;


提交完成。


SQL> select * from flashback_table;


FID FNAME
---------- --------------------
1 Tom
2 Mary
3 Mike


SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:mm') 時間,timestamp_to_scn(sysdate) SCN
2 from dual;


時間 SCN
------------------- ----------
2012-03-29 10:32:03 1066413


SQL> delete from flashback_table where fid=2;


已刪除 1 行。


SQL> commit;


提交完成。


SQL> select * from flashback_table;


FID FNAME
---------- --------------------
1 Tom
3 Mike


SQL> --授權:grant flashback any table to scott;
SQL> flashback table flashback_table to SCN 1066413;
flashback table flashback_table to SCN 1066413
*
第 1 行出現錯誤:
ORA-08189: 因為未啟用行移動功能, 不能閃回表




SQL> --開啟表的行移動
SQL> alter table flashback_table enable row movement;


表已更改。


SQL>
SQL> flashback table flashback_table to SCN 1066413;


閃回完成。


SQL> select * from flashback_table;


FID FNAME
---------- --------------------
1 Tom
2 Mary
3 Mike


閃回表需要考慮的事情

FLASHBACK TABLE命令作為單一的事務執行,會得到一個單一的DML鎖 表的統計數據不會被閃回 當前的索引和從屬的對象會被維持 閃回表操作: ?系統表不能被閃回 ?不能跨越DDL操作 ?會被寫入警告日志 ?產生撤銷和重做的數據

閃回刪除

閃回刪除,實際上從系統的回收站中將已刪除的對象,恢復到刪除之前的狀態。
系統的回收站只對普通用戶有作用。

閃回刪除:回收站(recyclebin)簡介


l回收站是所有被刪除對象及其相依對象的邏輯存儲容器,例如當一個表被刪除(drop)時,該表及其相依對象並不會馬上被數據庫徹底刪除,而是被保存到回收站中。 l l回收站將用戶執行的drop操作記錄在一個系統表中,也就是將被刪除的對象寫到一個數據字典中。如果確定不再需要該對象,可以使用purge命令對回收站進行清空。 l l被刪除的對象的名字可能是相同的,例如用戶創建了一個test表,使用drop命令刪除該表後,又創建了一個test表,這時,如果再次刪除該表就會導致向回收站中添加了兩個相同的表。

Oracle回收站舉例。

SQL> --閃回刪除(drop): oracle回收站
SQL> select * from tab;


TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
DEPT TABLE
EMP TABLE
BONUS TABLE
SALGRADE TABLE
EMP10 TABLE
EMP20 TABLE
TESTSAVEPOINT TABLE
TESTDELETE TABLE
BIN$91xa7gtoQfiGlzbFlex5HQ==$0 TABLE
TEST3 TABLE
MYPERSON TABLE


TNAME TABTYPE CLUSTERID
------------------------------ ------- ----------
EMPINCOMEVIEW VIEW
TESTSEQ TABLE
HREMP SYNONYM
MSG1 TABLE
TEST1 TABLE
PM_CI TABLE
PM_STU TABLE
FLASHBACK_TABLE TABLE
SYS_TEMP_FBT TABLE


已選擇20行。


SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
EMPINCOME BIN$91xa7gtoQfiGlzbFlex5HQ==$0 TABLE 2012-03-27:15:34:39
SQL> purge recyclebin;


回收站已清空。


SQL> drop table testseq purge; (不經回收站直接徹底刪除)


表已刪除。

閃回刪除:回收站中對象的命名規則

為了確保添加到回收站中的對象的名稱都是唯一的,系統會對這些保存到回收站中的對象進行重命名,重命名的格式如下:

BIN$globalUID$version


?其中: BIN表示RECYCLEBIN;globalUID是一個全局唯一的、24個字非長的對象,該標識與原對象名沒有任何關系;version指數據庫分配的版本號。

閃回刪除舉例

閃回使用drop命令刪除的表 ?使用表名閃回
SQL> select * from test3;


TID TNAME GEND
---------- -------------------- ----
1 Tom 男


SQL> drop table test3;


表已刪除。


SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST3 BIN$vORkLd1GQKKsPs9PO/H8oQ==$0 TABLE 2012-03-29:10:46:20
SQL> flashback table test3 to before drop;


閃回完成。


SQL> show recyclebin
SQL> select * from test3;


TID TNAME GEND
---------- -------------------- ----
1 Tom 男



?使用recyclebin name閃回
SQL> drop table test3;


表已刪除。


SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST3 BIN$V2swGcDdROGeCxvlh9SA3A==$0 TABLE 2012-03-29:10:51:45
SQL> flashback table "BIN$V2swGcDdROGeCxvlh9SA3A==$0" to before drop;


閃回完成。



閃回重名的表
SQL> drop table test3;


表已刪除。


SQL> create table test3(tid number);


表已創建。


SQL> drop table test3;


表已刪除。


SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST3 BIN$R5hrMHspQ1GmHWOXKJX1Ig==$0 TABLE 2012-03-29:10:49:03
TEST3 BIN$WO/lCOgSTo6kuIJ/thjM/A==$0 TABLE 2012-03-29:10:48:44
SQL> flashback table test3 to before drop;


閃回完成。


SQL> show recyclebin
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TEST3 BIN$WO/lCOgSTo6kuIJ/thjM/A==$0 TABLE 2012-03-29:10:48:44
SQL> flashback table test3 to before drop;
flashback table test3 to before drop
*
第 1 行出現錯誤:
ORA-38312: 原始名稱已被現有對象使用




SQL> select * from test3;


未選定行


SQL> flashback table test3 to before drop rename to test3new;


閃回完成。


SQL> select * from test3new;


TID TNAME GEND
---------- -------------------- ----
1 Tom 男

閃回刪除: 需要考慮的事情


1. Oracle的回收站:管理員沒有回收站
2. 執行閃回刪除: 一般的閃回刪除,閃回重名的表,通過回收站中的名字執行閃回(加雙引號)

3.閃回刪除對下列表無效: ?在SYSTEM 表空間內的表 ?用精細審計的數據庫或 虛擬的私人數據庫 ?屬於字典管理的表空間 ?由於空間不足已經被手動或自動刪除的表 4.以下依賴不被保護: ?位圖索引 ?表之前刪掉的索引




閃回版本查詢

語法

閃回版本查詢,提供了一個審計行改變的查詢功能,通過它可以查找到所有已經提交了的行記錄。其語法格式如下:

select column_name[,column_name,...]

from table_name

versionsbetween [SCN|TIMESTAMP] [expr|MINVALUE]

and [epxr|MAXVALUE] as of [SCN|TIMESTAMP] expr;


?其中:column_name列名;table_name表名;between...and時間段;SCN系統改變號;TIMESTAMP時間戳;AS OF表示恢復單個版本;MAXVALUE最大值;MINVALUE最小值;expr指定一個值或者表達式。

閃回版本查詢舉例


--閃回版本查詢

SQL> create table versions_table
2 (vid number,vname varchar2(20));


表已創建。


SQL> --第一天
SQL> insert into versions_table values(1,'Tom');


已創建 1 行。


SQL> commit;


提交完成。


SQL> --第二天
SQL> insert into versions_table values(2,'Mary');


已創建 1 行。


SQL> commit;


提交完成。


SQL> --第三天
SQL> insert into versions_table values(3,'Mike');


已創建 1 行。


SQL> commit
2 ;


提交完成。


SQL> --第四天
SQL> update versions_table set vname='Mary123' where vid=2;


已更新 1 行。


SQL> commit;


提交完成。


SQL> select * from versions_table;


VID VNAME
---------- --------------------
1 Tom
2 Mary123
3 Mike


SQL> --執行閃回版本查詢
SQL> select vid,vname
2 from versions_table
3 versions between timestamp minvalue and maxvalue;


VID VNAME
---------- --------------------
2 Mary123
3 Mike
2 Mary
1 Tom



SQL> select vid,vname,versions_operation,versions_starttime,versions_endtime
2 from versions_table
3 versions between timestamp minvalue and maxvalue
4 order by 1,4;

VID VNAME V VERSIONS_STARTTIME VERSIONS_ENDTIME
--- --------- - ---------------------------------------- ---------------------------------------------------------------------------
1 Tom I 29-3月 -12 11.07.26 上午
2 Mary I 29-3月 -12 11.07.41 上午 29-3月 -12 11.08.26 上午
2 Mary123 U 29-3月 -12 11.08.26 上午
3 Mike I 29-3月 -12 11.07.53 上午



閃回事務查詢

l閃回事務查詢實際上閃回版本查詢的一個擴充,通過它可以審計某個事務甚至撤銷一個已經提交的事務。
l實現閃回事務查詢,需要先了解flashback_transaction_query視圖,從該視圖中可以獲取事務的歷史操作記錄以及撤銷語句(UNDO_SQL)。
l使用閃回事務查詢,可以了解某個表的歷史操作記錄,這個操作記錄對應一個撤銷SQL語句,如果想要撤銷這個操作,就可以執行這個SQL語句。

Flashback_transaction_query

名稱 類型 說明

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

XID RAW(8) 事務編號

START_SCN NUMBER 事務的開始的系統改變號

START_TIMESTAMP DATE 事務的開始時間

COMMIT_SCN NUMBER 事務提交時的系統改變號

COMMIT_TIMESTAMP DATE 事務提交時的時間

LOGON_USER VARCHAR2(30) 對應的用戶

UNDO_CHANGE# NUMBER 撤銷操作對應的編號

OPERATION VARCHAR2(32) 操作

TABLE_NAME VARCHAR2(256) 表

TABLE_OWNER VARCHAR2(32) 所有者

ROW_ID VARCHAR2(19) 行號

UNDO_SQL VARCHAR2(4000) 撤銷事務的SQL語句



注意

l注意,要查詢flashback_transaction_query視圖的信息,需要有select any transaction的權限。


閃回事務查詢舉例

步驟:

l從閃回版本查詢中,獲取xid號。
l基於xid號,在flashback_transaction_query視圖中獲取相應事務的信息。
l利用UNDO_SQL撤銷事務操作。

代碼:

SQL> --閃回事務查詢
SQL> create table transaction_table
2 (tid number,tname varchar2(20));


表已創建。


SQL> --第一個事務
SQL> insert into transaction_table values(1,'Tom');


已創建 1 行。


SQL> insert into transaction_table values(2,'Mary');


已創建 1 行。


SQL> commit;


提交完成。


SQL> --第二個事務
SQL> insert into transaction_table values(3,'Mike');


已創建 1 行。


SQL> update transaction_table set tname='Mary123' where tid=2;


已更新 1 行。


SQL> commit;


提交完成。


SQL> --如何撤銷第二個事務??
SQL> desc flashback_transaction_query
名稱 是否為空? 類型
----------------------------------------------------------------------------------- -------- --------------------------------------------------------
XID RAW(8)
START_SCN NUMBER
START_TIMESTAMP DATE
COMMIT_SCN NUMBER
COMMIT_TIMESTAMP DATE
LOGON_USER VARCHAR2(30)
UNDO_CHANGE# NUMBER
OPERATION VARCHAR2(32)
TABLE_NAME VARCHAR2(256)
TABLE_OWNER VARCHAR2(32)
ROW_ID VARCHAR2(19)
UNDO_SQL VARCHAR2(4000)


SQL> --授權:grant select any transaction to scott;
SQL> select tid,tname,versions_operation,versions_starttime,versions_endtime,versions_xid
2 from transaction_table
3 versions between timestamp minvalue and maxvalue
4 order by 1,4;


TID TNAME V VERSIONS_STARTTIME VERSIONS_ENDTIME VERSIONS_XID
---------- -------------------- - ---------------------------------------- ---------------------------------------- ----------------
1 Tom I 29-3月 -12 11.22.00 上午 06001F00B9010000
2 Mary I 29-3月 -12 11.22.00 上午 29-3月 -12 11.22.36 上午 06001F00B9010000
2 Mary123 U 29-3月 -12 11.22.36 上午 08000F00B8010000
3 Mike I 29-3月 -12 11.22.36 上午 08000F00B8010000


SQL> select operation,undo_sql
2 from flashback_transaction_query
3 where xid='08000F00B8010000';


SQL> set linesize 150
SQL> col UNDO_SQL for a60
SQL> /


OPERATIO UNDO_SQL
-------- ------------------------------------------------------------
UPDATE update "SCOTT"."TRANSACTION_TABLE" set "TNAME" = 'Mary' wher
e ROWID = 'AAAM6vAAEAAAALtAAB';

INSERT delete from "SCOTT"."TRANSACTION_TABLE" where ROWID = 'AAAM6
vAAEAAAALtAAC';

BEGIN


SQL> update "SCOTT"."TRANSACTION_TABLE" set "TNAME" = 'Mary' where ROWID = 'AAAM6vAAEAAAALtAAB';


已更新 1 行。


SQL> delete from "SCOTT"."TRANSACTION_TABLE" where ROWID = 'AAAM6vAAEAAAALtAAC';


已刪除 1 行。


SQL> commit;


提交完成。


SQL> select * from TRANSACTION_TABLE;


TID TNAME
---------- --------------------
1 Tom
2 Mary

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved