Flashback家族 | Flashback Log |
Tablespace Recycle Bin |
UNDO | 作用 |
Flashback Database |
Yes | 回滚数据库 | ||
Flashback Drop |
Yes | 恢复误删除的表 | ||
Flashback Version Query |
Yes | 恢复误操作的数据 | ||
Flashback Transaction Query |
Yes | 同上 | ||
Flashback Table |
Yes | 同上 |
alter session set nls_date_format='yyyy-mm-dd:hh24:mi:ss'; select sysdate from dual; SYSDATE ------------------- 2011-12-16:02:51:16假设test表里有如下一条数据:
select * from test; ID ---------- 1现在把该数据删除:
delete from test; commit;此时test表中已经没有数据了,但我们依然 可以通过Flashback Query查询之前被删除的数据:
select * from test as of timestamp to_timestamp('2011-12-16:02:51:16','yyyy-mm-dd:hh24:mi:ss'); ID ---------- 1必要时还可以恢复 数据:
insert into test select * from test as of timestamp to_timestamp('2011-12-16:02:51:16','yyyy-mm-dd:hh24:mi:ss'); commit;
create table test (id number, name varchar(10)); insert into test values (1,'first'); commit; update test set name='second' where id=1; commit; update test set name='third' where id=1; commit;如上所示,我们创建了一个测试表test,插入一条数据,并对该数据进行两次更新,下面看如何用Version Query获得数据的演变历史:
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从下往上看,正好对应着我们之前对该数据的操作历史。
insert into test values (1); update test set id=11 where id=1; commit;开始第二个事务:
insert into test values (2); update test set id=22 where id=2; commit;查看flashback_transaction_query视图获得事务的演变历史:
select XID,OPERATION,COMMIT_SCN,UNDO_SQL from flashback_transaction_query where xid in (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
SQL> create table test as select * from dba_objects; SQL> drop table test; SQL> show recyclebin; ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TEST BIN$S5L+aNpzQmOScn8VfpJBAA==$0 TABLE 2011-12-15:22:38:30 SQL> create table test as select * from dba_objects where 2=1; SQL> drop table test; SQL> show recyclebin; ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME ---------------- ------------------------------ ------------ ------------------- TEST BIN$XHwrz1OaQaSeq/NQIE85hw==$0 TABLE 2011-12-15:22:39:34 TEST BIN$S5L+aNpzQmOScn8VfpJBAA==$0 TABLE 2011-12-15:22:38:30此时recyclebin里有两个test表,查看中两个表的数据个数:
SQL> select count(*) from "BIN$XHwrz1OaQaSeq/NQIE85hw==$0"; COUNT(*) ---------- 0 SQL> select count(*) from "BIN$S5L+aNpzQmOScn8VfpJBAA==$0"; COUNT(*) ---------- 1000000下面试着恢复后一张表:
SQL> flashback table "BIN$S5L+aNpzQmOScn8VfpJBAA==$0" to before drop; Flashback complete. SQL> select count(*) from test; COUNT(*) ---------- 1000000下面还要恢复前一张表,并重新命名为test2:
SQL> flashback table "BIN$XHwrz1OaQaSeq/NQIE85hw==$0" to before drop rename to test2; Flashback complete. SQL> select count(*) from test2; COUNT(*) ---------- 0
SQL> select name,flashback_on from v$database; NAME FLASHBACK_ON --------- ------------------ O01DMS0 NO2)配置Flash recovery area:
SQL> alter system set db_recovery_file_dest_size=2G scope=both; SQL> alter system set db_recovery_file_dest='H:\flashback' scope=both;3)启用Flashback Database 功能:
SQL> shutdown immediate SQL> startup mount SQL> alter database flashback on; SQL> select name,flashback_on from v$database; NAME FLASHBACK_ON --------- ------------------ O01DMS0 YES4)设置db_flashback_retention_target:
SQL> alter system set db_flashback_retention_target=1440 scope=both;5)打开数据库 :
SQL> alter database open;2. Flashback Database 操作
SQL> create table test as select * from dba_objects; Table created. SQL> select count(*) from test; COUNT(*) ---------- 10318 SQL> truncate table test; Table truncated. SQL> select count(*) from test; COUNT(*) ---------- 0
SQL> select to_char(OLDEST_FLASHBACK_TIME,'yyyy-mm-dd hh24:mi:ss') from v$flashback_database_log; TO_CHAR(OLDEST_FLAS ------------------- 2011-12-15 02:41:48
SQL> shutdown immediate; SQL> startup mount; SQL> flashback database to timestamp to_timestamp('2011-12-15 02:43:00','yyyy-mm-dd hh24:mi:ss'); Flashback complete.恢复成功后,最好先以readonly的方式打开数据库,以确认恢复达到预期,如果没有达到预期,还可以再进行恢复:
SQL> alter database open read only; Database altered. SQL> select count(*) from test; select count(*) from test * ERROR at line 1: ORA-00942: table or view does not exist SQL> shutdown immediate; SQL> startup mount; SQL> flashback database to timestamp to_timestamp('2011-12-15 02:49:00','yyyy-mm-dd hh24:mi:ss'); Flashback complete. SQL> alter database open read only; Database altered. SQL> select count(*) from test; COUNT(*) ---------- 103184)打开数据库
SQL> shutdown immediate; SQL> startup mount SQL> alter database open resetlogs;