[Oracle]Flashback闪回机制
Flashback的目的
在有Flashback之前,如果你对数据误操作,并已提交,这时想回退该误操作,将会是很件麻烦的事情。有人可能会说可以用备份恢复到误操作之前,但正确的操作数据也一起没了。唯一可能的办法就是日志挖掘,但日志挖掘非常繁琐,很难定位。
因此,Oracle推出了Flashback技术,主要目的就是为了恢复误操作。
Flashback家族介绍
数据库级别:Flashback Database
表级别:Flashback Drop和Flashback Table,Flashback Data Archive
记录级别:Flashback Version Query和Flashback Transaction Query
Flashback家族 Flashback Log
Tablespace Recycle Bin
UNDO 作用
Flashback Database
Yes 回滚数据库
Flashback Drop
Yes 恢复误删除的表
Flashback Version Query
Yes 恢复误操作的数据
Flashback Transaction Query
Yes 同上
Flashback Table
Yes 同上
Flashback 技术发展历程
Flashback Version/Transaction Query 和 Flashback Table
Flashback Query和Flashback Table都是利用undo实现回退功能,当需要闪回到过去某一时刻时,先利用Flashback Query查询,确认闪回的SCN或Timestamp,然后再利用Flashback Table真正实现闪回。
1. 9i 的 Flashback Query
9i的Flashback Query可以查询过去某个时间点对象的状态,测试如下:
系统当前时间为:
A105024@O02DMS1>alter session set nls_date_format='yyyy-mm-dd:hh24:mi:ss';
A105024@O02DMS1>select sysdate from dual;
SYSDATE
-------------------
2011-12-16:02:51:16
test表里有一条数据:
A105024@O02DMS1>select * from test;
ID
----------
1
现把该数据删除:
A105024@O02DMS1>delete from test;
A105024@O02DMS1>commit;
此时test表中无数据:
A105024@O02DMS1>select * from test;
no rows selected
但是可以通过Flashback Query查询删除之前的数据:
A105024@O02DMS1>select * from test as of timestamp to_timestamp('2011-12-16:02:51:16','yyyy-mm-dd:hh24:mi:ss');
ID
----------
1
必要时还可以恢复数据:
A105024@O02DMS1>insert into test select * from test as of timestamp to_timestamp('2011-12-16:02:51:16','yyyy-mm-dd:hh24:mi:ss');
A105024@O02DMS1>commit;
2. Flashback Version Query
10g新引入的Version Query可以看到过去某个时间段内,数据是如何变化的,也就是数据的演变历史,为此,10g还引入了一个新的伪列ORA_ROWSCN:记录该数据最后一次修改时的SCN。
A105024@O02DMS1>create table test (id number, name varchar(10));
A105024@O02DMS1>insert into test values (1,'first');
A105024@O02DMS1>commit;
A105024@O02DMS1>update test set name='second' where id=1;
A105024@O02DMS1>commit;
A105024@O02DMS1>update test set name='third' where id=1;
A105024@O02DMS1>commit;
我们创建了一个测试表,插入一条数据,并对该数据进行两次更新,下面看如何用Version Query获得数据的演变历史:
A105024@O02DMS1>select versions_xid,versions_startscn,versions_endscn,versions_operation,id,name from test versions between scn minvalue and maxvalue where id=1;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN VERSIONS_OPERATION ID NAME
---------------- ----------------- --------------- -------------------- ---------- ----------
12000900D0720000 6629455993 U 1 third
0C0018003D720000 6629455988 6629455993 U 1 second
0D002A00AD6E0000 6629455888 6629455988 I 1 first
从下往上看,正好对应着我们之前对该数据的操作历史。
从上面加黑这行可以看出,在SCN 6629455888和6629455993 这段期间,数据的状态为(1,second),对应的操作为update。
3. Flashback Transaction Query
Transaction Query可以查看事务的演变历史,使用这个功能需要访问flashback_transaction_query视图。
A105024@O02DMS1>create table test (id number);
开始第一个事务:
A105024@O02DMS1>insert into test values (1);
A105024@O02DMS1>update test set id=11 where id=1;
A105024@O02DMS1>commit;
开始第二个事务:
A105024@O02DMS1>insert into test values (2);
A105024@O02DMS1>update test set id=22 where id=2;
A105024@O02DMS1>commit;
查看flashback_transaction_query视图获得事务的演变历史:
A105024@O02DMS1>select XID,OPERATION,COMMIT_SCN,UNDO_SQL from flashback_transaction_query where xid in
2 (select versions_xid from test versions between scn minvalue and maxvalue);
XID OPERATION COMMIT_SCN UNDO_SQL
---------------- ---------- ---------- ------------------------------------------------------------
10000D000C720000 UPDATE 6629456273 update "A105024"."TEST" set "ID" = '2' where ROWID = 'AACsnzAAEAAABSnAAB';
10000D000C720000 INSERT 6629456273 delete from "A105024"."TEST" where ROWID = 'AACsnzAAEAAABSnAAB';
10000D000C720000 BEGIN 6629456273
0C0002002A720000 UPDATE 6629456260 update "A105024"."TEST" set "ID" = '1' where ROWID = 'AACsnzAAEAAABSnAAA';
0C0002002A720000 INSERT 6629456260 delete from "A105024"."TEST" where ROWID = 'AACsnzAAEAAABSnAAA';
0C0002002A720000 BEGIN 6629456260
4. Flashback Table
根据Flashback Query的演变历史,就可以确定需要回退的时间点,然后再利用Flashback Table功能真正实现回退,注意:在真正回退之前,必须启用row movement。
Flashback Drop
Flashback drop是从Oracle 10g开始才有的功能,原理是每个表空间都会有严格回收站的逻辑区域,当drop时,被删除的表及其关联对象不会被物理删除,只是转移到回收站中,给用户提供一个恢复的可能。
使用Flashback drop需要注意以下几点:
1. 对system表空间无效
2. sqlplus的版本不能低于10g,否则很多命令无法使用
下面做个测试:
SQL> create table test as select * from dba_objects;
SQL> drop table test;
SQL> show recyclebin;
ORIGINAL NAME RECYCLEBIN NAME OBJECT