Oracle閃回特性
在利用閃回功能前需要確認:
1、用戶有對dbms_flashback包有執行權限!
2、進行閃回查詢必須設置自動回滾段管理,在init.ora設置參數UNDO_MANAGEMENT=AUTO,參數UNDO_RETENTION=n,決定了能往前閃回的最大時間,值越大就需要越多Undo空間。
Oracle 9i中閃回查詢操作實例
查看Oracle中Delete和Commit操作的流程分析
例:Oracle 9i的Flashback Query操作。
(1)創建閃回查詢用戶
SQL> create user test identified by test;
SQL> grant connect, resource to test;
SQL> grant execute on dbms_flashback to test;
SQL> connect test/test;
(2)創建測試表,插入測試記錄
SQL> create table test(id number(3));
SQL> insert into test values(1);
SQL> insert into test values(2);
SQL> commit;
注意:在執行步驟3或者步驟4之前,等待5分鐘。
(3)刪除記錄
SQL> delete from test where id=1;
SQL> commit;
通過以上的操作,我們插入了兩條記錄,並刪除了其中一條記錄。在以下的操作中,我們將通過flashback query找到刪除的記錄
(4)閃回查詢(分別通過timestamp和scn查詢)
SQL> select * from test as of timestamp sysdate - 5/1440;
ID
----
1
2
或
SQL> select * from test as of scn 8173800;
ID
----
1
2
可以看出,雖然刪除記錄並提交,但是通過閃回操作,仍能查詢到刪除前的兩條記錄。需要注意Oracle每5分鐘記錄一次SCN到SMON_SCN_TIME,並將SCN和對應時間的映射進行紀錄。如果原來插入的記錄到做閃回操作的時間在5分鐘之內,用基於時間的閃回查詢可能得不到記錄,因爲基於時間點的查詢實際上是轉化爲最近的一次SCN,然後從這個SCN開始進行恢復。因此,如果需要精確的查詢可以採用基於SCN的閃回查詢,可精確閃回到需要恢復的時間。可以通過DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER語句獲取SCN。
5、恢復被刪除的數據實例
SQL>insert into test select * from test as of scn 8173800 where id=1;
Oracle 10g中閃回查詢操作實例
與Oracle 9i相比Oracle 10g的Flashback有了非常大的改進,在Orcle 10g之前,SMON_SCN_TIME由SMON來獲取和記錄信息的,每5分鐘記錄一次,從Oracle 10g開始,LGWR首先會在SGA中記錄SCN與時間的映射關係(由於LGWR至少每3秒就會被激活一次,所以現在SMON_SCN_TIME能夠支持大於3秒的閃回),SMON則定期檢查SGA是否內存中的映射大於磁盤上的,如果有就刷新紀錄到磁盤, 而且從普通的Flashback Query發展到了多種形式,主要表現在如下幾方面新特性:
1、Flashback Database
Oracle Flashback Database特性允許通過SQL語句Flashback Database語句,讓數據庫前滾到當前的前一個時間點或者SCN,而不需要做時間點的恢復。閃回數據庫可以迅速將數據庫回到誤操作或人爲錯誤的前一個時間點,如Word中的"撤消"操作,可以不利用備份就快速的實現基於時間點的恢復。Oracle通過創建新的Flashback Logs(閃回日誌),記錄數據庫的閃回操作。
如果希望能閃回數據庫,需要設置如下參數:
DB_RECOVER_FILE_DEST --日誌的存放位置,
DB_RECOVER_FILE_DEST_SIZ --E恢復區的大小
在創建數據庫的時候,Oracle將自動創建恢復區,但默認是關閉的,需要執行alter database flashback on命令。
執行Flashback Database命令格式:
SQL>flashback database to time to_timestamp(xxx);
SQL>flashback database to scn xxx
數據庫的閃回狀態可以從V$database視圖中查詢得到:
SQL> select dbid,name,flashback_on,current_scn from v$database;
DBID NAME FLASHBACK_ON CURRENT_SCN
--------- ------- ---------------- ----------
1692001961 ACF NO 8175168
一個數據庫級閃回的例子:
SQL> shutdown immediate;
數據庫已經關閉。
已經卸載數據庫。
ORACLE 例程已經關閉。
SQL> startup mount
ORACLE 例程已經啓動。
Total System Global Area 1719664640 bytes
Fixed Size 1251896 bytes
Variable Size 293602760 bytes
Database Buffers 1417674752 bytes
Redo Buffers 7135232 bytes
數據庫裝載完畢。
SQL> alter database flashback on;
數據庫已更改。
SQL> alter database open;
數據庫已更改。
SQL> select dbid,name,flashback_on,current_scn from v$database;
DBID NAME FLASHBACK_ON CURRENT_SCN
--------- ------- ---------------- ----------
1692001961 ACF YES 8175890
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
8175973
SQL> delete from test where id=1;
1 row deleted
SQL> select * from test;
ID
----
2
SQL> shutdown immediate
數據庫已經關閉。
已經卸載數據庫。
ORACLE 例程已經關閉。
SQL> startup mount ORACLE 例程已經啓動。
Total System Global Area 1719664640 bytes
Fixed Size 1251896 bytes
Variable Size 301991368 bytes
Database Buffers 1409286144 bytes
Redo Buffers 7135232 bytes
數據庫裝載完畢。
SQL> flashback database to scn 8175973; 閃回完成。
SQL> alter database open resetlogs; 數據庫已更改。
SQL> select * from test;
ID
----
2
1 --可以看到,數據已經恢復成功
2、Flashback Table
Oracle Flashback Table特性允許利用Flashback Table語句,確保閃回到表的前一個時間點。與Oracle 9i中的Flashback Query相似,利用回滾段信息來恢復一個或一些表到以前的一個時間點(一個快照)。要注意的是,Flashback Table不等於Flashback Query,Flashback Query僅僅是查詢以前的一個快照點而已,並不改變當前表的狀態,而Flashback Table將改變當前表及附屬對象一起回到以前的時間點。
語法:
alter table table_name enable row movement;
flashback table tablename to timestamp xxx 或
flashback table tablename to scn xxx
注意:如果需要閃回一個表,需要以下條件:
- 需要有flashback any table的系統權限或者是該表的flashback對象權限;
- 需要有該表的select,insert,delete,alter權限;
- 必須保證該表row movement。
例:執行將test表閃回到2005年5月7日下午3點。
SQL>flashback table test to timestamp to_timestamp('2005-05-07 15:00:00','yyyy-mm-dd hh24:mi:ss');
一個完整的Flashback Table例子
SQL> select * from test;
ID
----
2
1
SQL> select dbms_flashback.get_system_change_number from dual;
GET_SYSTEM_CHANGE_NUMBER
------------------------
8178419
SQL> delete from test where id=1;
1 row deleted
SQL> select * from test;
ID
----
2
SQL> alter table test enable row movement;
Table altered
SQL> flashback table test to scn 8178419;
Done
SQL> select * from test;
ID
----
2
1
3、Flashback Drop
Oracle Flashback Drop特性提供一個類似回收站的功能,用來恢復不小心被刪除的表。當刪除表時,Oracle 10g並不立刻釋放被刪除的表所佔用的空間,而是將這個被刪除的表進行自動重命名(爲了避免同類對象名稱的重複)並放進回收站中。所謂的回收站類似於Windows系統中的回收站,是一個虛擬的容器,用於存放所有被刪除的對象,在回收站中被刪除的對象將佔用創建時的同樣的空間。如果這個被刪除的表需要進行恢復,就可利用Flashback Drop功能。
例:進行一個刪除表後恢復的簡單測試。
(1)顯示回收站信息(不要以Sysdba用戶查詢,否則會把錯)
SQL>show recyclebin;
可以看到,回收站中是沒有任何結果的,表示沒有任何表在回收站中。
(2)創建一個表,並刪除,再次顯示回收站信息
SQL>create table test_drop(name varchar2(10));
SQL>drop table test_drop;
SQL>show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
TEST_DROP BIN$b+XkkO1RS5K10uKo9BfmuA==$0 TABLE 2005-05-07:14:30:47
(3)對被刪除的表進行恢復
SQL>flashback table test_drop to before drop;或
SQL>flashback table "BIN$b+XkkO1RS5K10uKo9BfmuA==$0" to before drop;
(4)管理回收站
清除回收站中的單個表:purge table test_drop
清除整個回收站:purge recyclebin
清除不同的對象回收站:purge user_recyclebin或purge dba_recyclebin
注意:需要注意的是sysdba的drop操作不會被記錄,Oracle也從不推薦用戶使用sysdba身份創建用戶對象
(5)確認刪除一個表
SQL>drop table test_drop purge;
如果刪除一個表且不放到回收站中不能進行恢復,在drop語句中可以利用purge選項。
(6)可以通過參數禁用或啓用recyclebin這個特性
在Oracle 10gR1中,通過修改一個隱含_recyclebin爲False可以禁用這個特性,在Oracle 10gR2中,recyclebin變成了一個常規參數,可以在session/system級動態修改 :
SQL> show parameter recyclebin
NAME TYPE VALUE
----------------------------------- --------- -----
recyclebin string on
SQL> alter session set recyclebin=off;
會話已更改。
SQL> alter session set recyclebin=on;
會話已更改。
SQL> alter system set recyclebin=off;
系統已更改。
SQL> alter system set recyclebin=on;
系統已更改。
4、Flash Version Query
Oracle Flashback Version Query特性,利用保存的回滾信息,可以看到特定的表在時間段內的任何修改,如電影的回放一樣,可以瞭解表在該期間的任何變化。Flashback version query一樣依賴於AUM,提供了一個查看行改變的功能,能找到所有已經提交了的行的記錄,分析出過去時間都執行了什麼操作。
Flashback version query採用VERSIONS BETWEEN語句來進行查詢,常用的方法:
- VERSIONS_SCN - 系統改變號
- VERSIONS_TIMESTAMP - 時間
例如:在test表中,時間1插入一條記錄,時間2刪除了這條記錄,對於時間3執行select * from test當然查詢不到這條記錄,只能看到該表最後的提交記錄。這時如果利用Flash Table或者是Flash Query,只能看到過去的某一時間點的一個快照,而利用Flashback Version Query,能夠把時間1、時間2的操作給記錄下來,並詳細的查詢出對錶進行的任何操作。
SQL>select versions_starttime,versions_endtime, versions_xid,versions_operation,id
from test versions
between timestamp minvalue and maxvalue
order by versions_starttime;
在上述查詢中,列 versions_starttime、versions_endtime、versions_xid、versions_operation是僞列,還有一些僞列,如
versions_startscn和versions_endscn顯示了該時刻的系統更改號。列versions_xid顯示了更改該行的事務標識符。
當然,除了分析以上所有的變更之外,可以根據需要指定時間段,如顯示在2005-05-07時間在15:30到16:30之間test表的所有變更。
SQL>select id from test
versions between timestamp to_date('2005-05-07 15:30:00','yyyy-mm-dd hh24:mi:ss') and to_date('2005-05-07 16:30:00','
yyyy-mm-dd hh24:mi:ss')
5、Flashback Transaction Query
Oracle Flashback Transaction Query特性確保檢查數據庫的任何改變在一個事務級別,可以利用此功能進行診斷問題、性能分析和審計
事務。它其實是Flashback Version Query查詢的一個擴充,Flashback Version Query說明了可以審計一段時間內表的所有改變,但是也僅僅
是能發現問題,對於錯誤的事務,沒有好的處理辦法。而Flashback Transaction Query提供了從FLASHBACK_TRANSACTION_QUERY視圖中獲得事
務的歷史以及Undo_sql(回滾事務對應的sql語句),也就是說審計一個事務到底做了什麼,甚至可以回滾一個已經提交的事務。
例:Flashback Transaction Query的操作實例。
(1)在test表中刪除記錄,獲得事務的標識XID,然後提交。
SQL>delete from test where id=2;
SQL>select xid from v$transaction;
XID
----------------
04001200AE010000
SQL>commit;
在測試中方便起見,在事務沒有提交的時候,獲得事務的XID爲04001F0035000000。實際情況下,不可能去跟蹤每個事務,想要獲得已提交事務的XID,就必須通過上面的Flashback Version Query。
(2)進行Flashback Transaction Query
SQL>select * from FLASHBACK_TRANSACTION_QUERY
where xid='04001F0035000000';
UNDO_SQL
insert into "test"."TEST"("ID") values ('2');
注意:這個刪除語句對應的是1個Insert語句,如果想回滾這個事務,執行這個Insert語句即可。
可以看到,Flashback Transaction Query主要用於審計一個事務,並可以回滾一個已經提交的事務。如果確定出錯的事務是最後一個事務,我們利用Flashback Table或者Flashback Query就可以解決問題。但是,如果執行了一個錯誤的事務之後,又執行了一系列正確的事務,那麼上面的方法就無能爲力,利用Flashback Transaction Query可以查看或回滾這個錯誤的事務。