在ORACLE10G下使用Flashback Database,将数据库恢复到处方发药前的某一时间,这种方法对于当前只有你一个人在操作数据库是比较有用。如果恰好有其他人员也在使用这个数据库,小心了。
ORACLE11G中对 Flashback 引进了Flashback Transaction Backout ,也就是对事务进行Flashback。
使用这个特性,要求数据库处于归档模式,并且“add supplemental log data”例如:
startup mount;
alter database archivelog;
alter database open;
alter system archive log current;
alter database add supplemental log data;
假设有两个表t1 ,t2 ,并有触发器如下:
CREATE TABLE t1 (testcol VARCHAR2(3));
CREATE TABLE t2 (testcol VARCHAR2(3));
CREATE OR REPLACE TRIGGER row_level
BEFORE INSERT
ON t1
FOR EACH ROW
BEGIN
INSERT INTO t2
VALUES
(:NEW.testcol);
END row_level;
/
也就是说没插入一条t1记录,在t2中也插入一条记录。
执行如下操作填充数据:
BEGIN
INSERT INTO t1 VALUES ('ABC');
INSERT INTO t1 VALUES ('DEF');
COMMIT;
dbms_lock.sleep(50);
INSERT INTO t1 VALUES ('GHI');
INSERT INTO t1 VALUES ('JKL');
COMMIT;
dbms_lock.sleep(50);
INSERT INTO t1 VALUES ('MNO');
COMMIT;
dbms_lock.sleep(50);
END;
/
执行结束后,我们看看
SELECT versions_xid, versions_startscn, versions_endscn, versions_operation, testcol
FROM t1
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN V TES
---------------- ----------------- --------------- - ---
08001400CB020000 1145327 I MNO
0600140045020000 1145294 I JKL
0600140045020000 1145294 I GHI
03000F005C020000 1145249 I DEF
03000F005C020000 1145249 I ABC
SELECT versions_xid, versions_startscn, versions_endscn, versions_operation, testcol
FROM t2
VERSIONS BETWEEN SCN MINVALUE AND MAXVALUE;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN V TES
---------------- ----------------- --------------- - ---
08001400CB020000 1145327 I MNO
0600140045020000 1145294 I JKL
0600140045020000 1145294 I GHI
ABC
DEF
我对表t2 中”GHI’ 进行如下操作:
SQL> delete from t2 where testcol='GHI';
1 row deleted.
SQL> insert into t2 values ('PQR') ;
1 row created.
SQL> commit ;
Commit complete.
SQL> select * from t2 ;
TES
---
ABC
DEF
JKL
MNO
PQR
5 rows selected.
这个时候,我想回退将’GHI’和’JKL’插入到表t1的事务,如果成功的话,应该t2 也没有’GHI’和’JKL’ ,而且t2也应该没有’PQR’,因为插入’PQR’的操作是依赖于‘GHI’ 的存在。
我们看到插入’GHI’和’JKL’的事务的VERSIONS_XID是0600140045020000 ,因此执行:
SQL> DECLARE
xa sys.xid_array := sys.xid_array();
BEGIN
xa.extend;
dbms_output.put_line(xa.last);
xa(1) := '0600140045020000';
dbms_flashback.transaction_backout(1, xa , dbms_flashback.CASCADE);
END;
/
PL/SQL procedure successfully completed.
再查询一下:
SQL> select * from t1 ;
TES
---
ABC
DEF
MNO
3 rows selected.
SQL> select * from t2 ;
TES
---
ABC
DEF
MNO
一切正常。
Flashback使用的是UNDO的内容,如果时间过长,UNDO里没有需要的信息,可能需要使用Logmnr挖掘日志。 可以参考Oracle Database 11g: Flashback Transaction Backout (http://www.databasejournal.com/features/oracle/article.php/3792961/Oracle-Database-11g-Flashback-Transaction-Backout.htm).
另外也可以参考 11g FLASHBACK Compensating Transaction(http://www.dba-oracle.com/t_11g_new_flashback_compensating.htm)
本文的例子来自于Oracle DBMS_FLASHBACK(http://www.psoug.org/reference/dbms_flashback.html)。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9036/viewspace-524670/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9036/viewspace-524670/