閃回版本查詢Flashback Version Query
“忘記備份”是幾年前看一位行業前輩的經驗談中讓筆者記憶深刻的工作軍規。對DBA而言,備份通常指的是“Media Backup”,在Oracle世界中就是各種冷備份檔案、備份組合和歸檔日誌。
工作時間越長,膽子其實就是越小。很多很多時候,有備份並不意味著可以高枕無憂。這種論斷主要是基於兩方面的因素,其一是備份的有效性,雖然有各種工具系統介質負責備份工作,但是備份是不是有效一直是營運工程師心中的噩夢。第二個因素是恢復,大部分的Media Recovery都需要停機停服務,這對於7*24小時的高可用應用是不能允許的。另一方面,在現代企業層級資料中心環境下,如果存在正當的管理流程和方法,大規模資料恢複、回退的情況是比較少見的。
相應的,小規模資料恢複,如資料表一行資料被莫名誤修改、資料表誤刪除等需要恢複的需求卻不斷增加。在傳統的恢複技術中,這樣粒度的恢複操作一般是不能支援的。
從10g開始,Oracle開始大面積引入“Flashback”技術,或者成為Flashback技術工具集合,來提供多層級多粒度的“邏輯恢複”。經過若干年的發展,Flashback家族已經有諸多的分支技術,依託不同的技術技術,來實現多粒度的資料恢複。在筆者之前的文章中,已經陸續介紹了一些Flashback技術和應用,本篇繼續介紹Flashback Version Query。
1、環境介紹
筆者選擇Oracle 11g進行測試,具體版本為11.2.0.4。
SQL> select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 – Production
Flashback Version Query的配置基礎和Flashback Query相同,都需要啟用Automatic Undo Management,通過Undo_Retention進行控制時間長短。
SQL> show parameter undo
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
為了實驗方便,調整undo_retention到1800。
SQL> alter system set undo_retention=1800 scope=both;
System altered
SQL> show parameter undo_re
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
undo_retention integer 1800
建立實驗資料表。
SQL> create table test as select empno, ename, sal from scott.emp where rownum<3;
Table created
SQL> commit;
Commit complete
SQL> select * from test;
EMPNO ENAME SAL
----- ---------- ---------
7369 SMITH 800.00
7499 ALLEN 1600.00
2、Flashback Version Query
Flashback Version Query和Flashback Query從技術基礎上,都是相似的,也就是藉助Oracle的Undo機制。作為一款成功的資料庫產品,Undo和Redo機制是Oracle最核心的技術。Undo記錄的是資料DML操作的前鏡像,經典的Oracle事務模型中,一旦事務被commit,理論上之後SCN啟動的讀操作都不能讀到之前的鏡像資料。
Oracle於是利用Undo的機制,提供了短時間內的資料表舊版本查詢。通過as of {timestamp | scn}指定時間點,就可以進行查詢。當然,這箇舊版本時間並不是無限長度,這就涉及到undo_retention這個爭議參數。
很多朋友都不是很理解undo_retention,這個以秒為單位的參數經常讓人很抓狂。官方理解是:設定undo_retention之後,可以支援設定秒數的閃回資料查詢。但是在實際工作中,卻發現很多時候超過這個時間的資料也能檢索到,但是有的時候沒有到這個時間間隔舊版本資料,也不能找到。
其實,Undo_retention參數其實是使用者建議Oracle資料庫的一個“建議理想值”。試想一下,Undo資料是一個不斷迴圈覆蓋使用的空間,舊Undo前鏡像一定會被新Undo前鏡像覆蓋。事務負載不同的系統,對Undo的使用方式也是不同的。
如果Undo_Retention保留的時間比較長,而恰恰資料庫系統是一個事務操作頻繁的系統,那麼Oracle如果想要堅持undo_retention,就必須維持一個比較大可拓展的Undo Tablespace。這時候,如果恰恰Undo Tablespace的檔案被設定為不可拓展的,那麼Oracle也就不能保證undo_retention的理想值了。
參數retention grantee是設定在undo tablespace的參數設定。如果設定了這個參數,就表示Oracle一定要保證undo_retention的理想設定值,即使不能完成事務過程。
Flashback Query和Flashback Version Query,都是依賴Undo到期資料的來構建前鏡像的操作。
與Flashback Query不同的是,Flashback Version Query引入了一些資料表“偽列”,可以提供對資料版本的操作和檢索。下面通過一個SQL來查看。
SQL> select versions_xid xid, versions_startscn start_scn, versions_endscn endscn, versions_operation operation, empno from test versions between scn minvalue and maxvalue;
XID START_SCN ENDSCN OPERATION EMPNO
---------------- ---------- ---------- --------- -----
7369
7499
資料表test,顯然沒有諸多的列定義。從這個情況看,flashback query提供了一種資料行層級的版本查詢操作。先來看一下引入的資料偽列含義,本是從Oracle 11g官方文檔中提取出的。
ü Versions_Startxxx表示資料行的最開始出現時間,可以使用SCN或者timestamp表示,如果這個欄位為null,表示該資料從undo資料中沒有找到對應的版本記錄;
ü Versions_Endxxx表示資料行的截止時間,如果為空白,表示資料為目前記錄或者已經經過delete操作;
ü Versions_xid為事務對應的唯一標識,表示該資料行的變化是被哪個事務操作的;
ü Versions_operation:操作內容;
3、操作實驗
下面經過一系列實驗,來確定Flashback Version Query使用。未經處理資料情況如下:
SQL> select * from test;
EMPNO ENAME SAL
----- ---------- ---------
7369 SMITH 800.00
7499 ALLEN 1600.00
進行資料增加操作。
SQL> select versions_xid xid, versions_startscn start_scn, versions_endscn endscn, versions_operation operation, empno from test versions between scn minvalue and maxvalue;
XID START_SCN ENDSCN OPERATION EMPNO
---------------- ---------- ---------- --------- -----
7369
7499
0A001B00D3870100 24306083 I 1000
versions_operation表示“I”,為新增加的資料。start_scn為資料插入的SCN記錄,xid為事務的標示。
SQL> update test set sal=200 where empno=7369;
1 row updated
SQL> commit;
Commit complete
SQL> select versions_xid xid, versions_startscn start_scn, versions_endscn endscn, versions_operation operation, empno, sal from test versions between scn minvalue and maxvalue;
XID START_SCN ENDSCN OPERATION EMPNO SAL
---------------- ---------- ---------- --------- ----- ---------
0200110020160000 24306146 U 7369 200.00
24306146 7369 800.00
7499 1600.00
0A001B00D3870100 24306083 I 1000 200.00
U表示資料修改後的版本資料。如果刪除資料,如下操作:
SQL> delete test where empno=7499;
1 row deleted
SQL> commit;
Commit complete
SQL> select versions_xid xid, versions_startscn start_scn, versions_endscn endscn, versions_operation operation, empno, rowid from test versions between scn minvalue and maxvalue;
XID START_SCN ENDSCN OPERATION EMPNO ROWID
---------------- ---------- ---------- --------- ----- ------------------
0A001100D3870100 24306188 D 7499 AAAtPCAABAAAeu5AAB
0200110020160000 24306146 U 7369 AAAtPCAABAAAeu5AAA
24306146 7369 AAAtPCAABAAAeu5AAA
24306188 7499 AAAtPCAABAAAeu5AAB
0A001B00D3870100 24306083 I 1000 AAAtPCAABAAAeu6AAA
通過上面的資料,是可以做到跟蹤整個Undo_retention中資料變化的情況。下面監控一下事務標記資訊。
SQL> delete test;
2 rows deleted
SQL> select xid from v$transaction;
XID
----------------
0A000300C3870100
SQL> commit;
Commit complete
SQL> select versions_xid xid, versions_startscn start_scn, versions_endscn endscn, versions_operation operation, empno, rowid from test versions between scn minvalue and maxvalue;
XID START_SCN ENDSCN OPERATION EMPNO ROWID
---------------- ---------- ---------- --------- ----- ------------------
0A000300C3870100 24306249 D 7369 AAAtPCAABAAAeu5AAA
0A001100D3870100 24306188 D 7499 AAAtPCAABAAAeu5AAB
0200110020160000 24306146 24306249 U 7369 AAAtPCAABAAAeu5AAA
24306146 7369 AAAtPCAABAAAeu5AAA
24306188 7499 AAAtPCAABAAAeu5AAB
0A000300C3870100 24306249 D 1000 AAAtPCAABAAAeu6AAA
0A001B00D3870100 24306083 24306249 I 1000 AAAtPCAABAAAeu6AAA
7 rows selected
從v$transaction中擷取到的資料XID,可以在其中對應上。
4、結論
Flashback Version Query是Oracle Flashback系列的一個技術。雖然基於的Undo到期資料時間上是有限制的,結合Flashback Transaction Query,可以做到很好的事務層級資料恢複。