继续聊聊Flashback家庭成员。Flashback Version Query、Flashback Query和本次介绍的Flashback Transaction Query相同,都是依赖于Undo表空间的过期数据。和Version Query和Query不同的是,Flashback Transaction Query将数据变化的粒度细化到了事务级别,而且支持用户进行Undo操作,准备好相关的SQL语句。
1、实验环境
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 Transaction有两个条件,一个是使用自动Automatic Undo Management,另一个不是必须,但是建议设置的是添加补充日志Supplemental Redo Log。
SQL> show parameter undo;
NAME? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? TYPE? ? ? ? VALUE
------------------------------------ ----------- ------------------------------
undo_management? ? ? ? ? ? ? ? ? ? ? string? ? ? AUTO
undo_retention? ? ? ? ? ? ? ? ? ? ? integer? ? 9000
undo_tablespace? ? ? ? ? ? ? ? ? ? ? string? ? ? UNDOTBS1
SQL> select SUPPLEMENTAL_LOG_DATA_MIN from v$database;
SUPPLEMENTAL_LOG_DATA_MIN
-------------------------
YES
默认的Undo_retention大小为900秒,为了实验方便设置为9000秒。
数据环境构建,创建简单数据表。
SQL> create table test as select empno, sal from scott.emp;
Table created
SQL> select * from test;
EMPNO? ? ? SAL
----- ---------
?7369? ? 800.00
?7499? 1600.00
?7521? 1250.00
(篇幅原因,有省略……)
?7934? 1300.00
14 rows selected
2、操作实验
Flashback Transaction Query的核心,就是将日志以事务+数据行的修改粒度在flashback_transaction_query中查询到。
Flashback_Transaction_Query视图是Oracle提供给用户进行操作日志查询的接口。在其中,可以看到对应一个数据表、数据行和事务进行的所有数据操作。
SQL> desc flashback_transaction_query;
Name? ? ? ? ? ? Type? ? ? ? ? Nullable Default Comments? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
---------------- -------------- -------- ------- -----------------------------------------?
XID? ? ? ? ? ? ? RAW(8)? ? ? ? Y? ? ? ? ? ? ? ? Transaction identifier? ? ? ? ? ? ? ? ? ?
START_SCN? ? ? ? NUMBER? ? ? ? Y? ? ? ? ? ? ? ? Transaction start SCN? ? ? ? ? ? ? ? ? ? ?
START_TIMESTAMP? DATE? ? ? ? ? Y? ? ? ? ? ? ? ? Transaction start timestamp? ? ? ? ? ? ? ?
COMMIT_SCN? ? ? NUMBER? ? ? ? Y? ? ? ? ? ? ? ? Transaction commit SCN? ? ? ? ? ? ? ? ? ?
COMMIT_TIMESTAMP DATE? ? ? ? ? Y? ? ? ? ? ? ? ? Transaction commit timestamp? ? ? ? ? ? ?
LOGON_USER? ? ? VARCHAR2(30)? Y? ? ? ? ? ? ? ? Logon user for transaction? ? ? ? ? ? ? ?
UNDO_CHANGE#? ? NUMBER? ? ? ? Y? ? ? ? ? ? ? ? 1-based undo change number? ? ? ? ? ? ? ?
OPERATION? ? ? ? VARCHAR2(32)? Y? ? ? ? ? ? ? ? forward operation for this undo? ? ? ? ? ?
TABLE_NAME? ? ? VARCHAR2(256)? Y? ? ? ? ? ? ? ? table name to which this undo applies? ? ?
TABLE_OWNER? ? ? VARCHAR2(32)? Y? ? ? ? ? ? ? ? owner of table to which this undo applies?
ROW_ID? ? ? ? ? VARCHAR2(19)? Y? ? ? ? ? ? ? ? rowid to which this undo applies? ? ? ? ?
UNDO_SQL? ? ? ? VARCHAR2(4000) Y? ? ? ? ? ? ? ? SQL corresponding to this undo? ? ? ? ? ?
下面进行简单的修改。
SQL> update test set sal=100 where empno=7369;
1 row updated
SQL> commit;
Commit complete
根据owner和table_name,可以找到数据记录。
SQL> select xid, start_scn, commit_scn, row_id, operation,undo_sql from flashback_transaction_query where table_owner='SYS' and table_name='TEST';
XID? ? ? ? ? ? ? START_SCN COMMIT_SCN ROW_ID? ? ? ? ? ? ? OPERATION? UNDO_SQL
---------------- ---------- ---------- ------------------- ------------------------------------------------------------------------------------
0900130035060000? ? 1939850? ? 1939857 AAAV4EAABAAARfpAAA? UPDATE? ? update "SYS"."TEST" set "SAL" = '800' where ROWID = 'AAAV4EAABAAARfpAAA';
在其中,可以看到对数据表test进行的操作事务信息,修改数据行rowid。最重要有意思的是Oracle还将逆转事务操作使用的SQL语句。
Undo_S