Flashback 技术是以Undo segment中的内容为基础的,因此受限于UNDO_RETENTON参数。要使用flashback 的特性,必须启用自动撤销管理表空间。 在Oracle 10g中,Flash back家族分为以下成员:Flashback Database,Flashback Drop,Flashback Query(分Flashback Query,Flashback Version Query,Flashback Transaction Query三种) 和 Flashback Table。
1.Flashback Database
Flashback Database 功能非常类似于RMAN的不完全恢复,它可以把整个数据库回退到过去的某个时点的状态,这个功能依赖于Flashback log 日志。比RMAN更快速和高效。因此Flashback Database 可以看作是不完全恢复的替代技术。 但它也有某些限制:
1)Flashback Database 不能解决Media Failure, 这种错误RMAN恢复仍是唯一选择。
2)如果删除了数据文件或者利用Shrink技术缩小数据文件大小,这时不能用Flashback Database技术回退到改变之前的状态,这时候就必须先利用RMAN把删除之前或者缩小之前的文件备份restore 出来
, 然后利用Flashback Database 执行剩下的Flashback Datbase。
3)如果控制文件是从备份中恢复出来的,或者是重建的控制文件,也不能使用Flashback Database。
4)使用Flashback Database锁能恢复到的最早的SCN, 取决与Flashback Log中记录的最早SCN。
Flashback Database整个架构包括一个进程Recover Writer(RVWR)后台进程(待验证),Flashback Database Log日志和Flash Recovery Area。一旦数据库启用了Flashback Database,则RVWR进程会启动,该进程会向Flash Recovery Area中写入Flashback Database Log,这些日志包括了数据块的“前镜像(before image)”,这也是Flashback Database 技术恢复数据的依据。
配置Flash Recovery Area(大小和位置)
SQL> show parameter db_recover;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /u01/app/oracle/flash_recovery_area
db_recovery_file_dest_size big integer 2G
注意:数据库如果未指定归档路径,归档日志默认会放在db_recovery_file_dest目录下,也就是db_recovery_file_dest_size的限制,如上可看到是2G。如果超过这个大小,会导致两个问题:1.
归档无法完成;2如果此时重启数据库,那么数据库无法正常启动。因此为了避免这个问题,常规做法是:1.设置归档目录到其他目录下;2.根据数据库业务繁忙程度确定db_recovery_file_dest_size大小;另外,当db_recovery_file_dest_size剩余空间不足15%时,数据库会在alert日志中增加警告,提示空间不足,当空间完全耗尽时门数据库试图去删除过期的闪回数据、冗余文件或者备份过的文件,这些做完了还是没有空间的话,数据库将会hang住,所以根据业务量确定db_recovery_file_dest_size的大小、定时观察其使用率也十分必要。
查看Flashback空间的使用率:
SQL> show parameter db_recovery_file_dest_size;
SQL> select * from v$flash_recovery_area_usage;
启用flashback database功能:
SQL> startup mount;
SQL> select name, current_scn, flashback_on from v$database;
NAME CURRENT_SCN FLASHBACK_ON
--------- ----------- ------------------
ANN 0 NO
SQL> alter database flashback on;
Database altered.
修改db_flashback_retention_target参数(flashback保留期限,默认为1440minutes):
SQL>alter system set db_flashback_retention_target=1440 scope=both;
SQL> alter database open;
查看当前可恢复的最早时刻或SCN:
SQL> select * from v$flashback_database_log;
利用flashback database闪回误删除表:
SQL> select flashback_on,log_mode from v$database;
FLASHBACK_ON LOG_MODE
------------------ ------------
YES ARCHIVELOG
SQL> create table flashback_test(id integer,name varchar2(50));
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
551144
SQL> select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual;
TIME
-----------------
13-02-17 14:04:34
SQL> drop table flashback_test;
Table dropped.
SQL> select * from flashback_test;
select * from flashback_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('13-02-17 14:04:34','yy-mm-dd hh24:mi:ss');
或者
SQL> flashback database to scn 551144;
SQL> alter database open resetlogs;
SQL> select * from flashback_test;
no rows selected
注意:打开数据库时,有两种方式,1.alter database open resetlogs,也就是指定时间或SCN后所做的数据修改全部丢失,相当于不完全恢复;2.flashback完成后,不resetlogs打开,而是打开到只读模式(alter database open read only),通过数据泵将误操作涉及的表逻辑导出,再用recover database命令重新应用日志,从而保留误操作时刻之后的其他数据修改,打开数据库后,利用逻辑备份还原误操作涉及的表。这样影响最小。
2.Flashback DROP
10G以后,Flashback DROP用于恢复误删除对象,依赖于tablespace recycle bin(表空间回收站)实现,类似win的回收站,flashback时不支持sys用户。
以sys用户登陆,查看回收站是否打开
SQL> show parameter recycle;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
buffer_pool_recycle string
db_recycle_cache_size big integer 0
recyclebin
禁用与启用该功能:
SQL> alter system set recyclebin=off;
SQL> alter system set recyclebin=on;
SQL> alter session set recyclebin=off;
SQL> alter session set recyclebin=on;
利用Flashback DROP闪回误删除表
以USER01用户登陆数据库:
[oracle@localhost ~]$ sqlplus user01/XXXXXXXX@ann
创建测试表:
SQL> create table flashback_drop as select 'aaa' name from dual;
SQL> select * from flashback_drop;
NAME
----
aaa
查看回收站是否存在该表:
SQL> select * from recyclebin;
no rows selected
删除表:
SQL> drop table flashback_drop;
Table dropped.
查询该表,提示不存在对象:
SQL> select * from flashback_drop;
select * from flashback_drop
*
ERROR at line 1:
ORA-00942: table or view does not exist
查看回收站记录,该表存在于回收站中:
SQL> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$1edSzUpGg6TgQAB/AQA0tg==$0 FLASHBACK_DROP
用flashback恢复该表:
SQL> flashback table FLASHBACK_DROP to before drop;
Flashback complete.
验证:
SQL> select * from flashback_drop;
NAME
----
aaa
新建相同的表,当再次删除该表时,回收站中会有两个相同的表名,这时要用OBJECT_NAME恢复
删除表:
SQL> drop table flashback_drop;
Table dropped.
查看回收站记录发现只有刚刚删除的表:
SQL> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$1edSzUpHg6TgQAB/AQA0tg==$0 FLASHBACK_DROP
新建同名表:
SQL> create table flashback_drop as select 'aaa' name from dual;
Table created.
删除新建的同名表
SQL> drop table flashback_drop;
Table dropped.
查询回收站记录发现有两条记录:
SQL> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$1edSzUpHg6TgQAB/AQA0tg==$0 FLASHBACK_DROP
BIN$1edSzUpIg6TgQAB/AQA0tg==$0 FLASHBACK_DROP
验证表已被删除
SQL> select * from flashback_drop;
select * from flashback_drop
*
ERROR at line 1:
ORA-00942: table or view does not exist
用object_name恢复:
SQL> flashback table "BIN$1edSzUpHg6TgQAB/AQA0tg==$0" to before drop;
Flashback complete.
验证
SQL> select * from flashback_drop;
NAME
----
aaa
查询回收站可看到记录又变为一条:
SQL> select object_name,original_name from recyclebin;
OBJECT_NAME ORIGINAL_NAME
------------------------------ --------------------------------
BIN$1edSzUpIg6TgQAB/AQA0tg==$0 FLASHBACK_DROP
遇到闪回恢复的表名已由现有对象占用则可使用:
SQL> flashback table FLASHBACK_DROP to before drop rename to FLASHBACK_DROP02;
3.Flashback Query
Flashback 是ORACLE 自9i 就开始提供的一项特性,在9i 中利用oracle 查询多版本一致的特点,实现从回滚段中读取表一定时间内操作过的数据,可用来进行数据比对,或者修正意外提交造成的错误数据,该项特性也被称为Flashback Query。
undo表空的设计确保了不堵塞读,即当前用户修改数据未提交,会将修改数据的前镜像存入undo表空间中,其他用户查询该数据时实际上市通过undo表空间来构造数据结果返回给用户,这样其他用户查询时不用等待当前用户提交当前修改。Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据。
1)Flashback Query
可以通过两种方式进行查询,as of timestamp或者as of scn:
查询当前记录:
SQL> select * from test01;
ID NAME
---------- --------------------------------------------------
1 ann
2 Attacker
3 Lily
切换成sys用户查询当前scn和时间:
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
559120
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2013-02-17 16:01:15
删除测试数据:
SQL> delete test01;
3 rows deleted.
SQL> commit;
Commit complete.
查看删除前的数据:
SQL> select * from test01 as of scn 559120;
ID NAME
---------- --------------------------------------------------
1 ann
2 Attacker
3 Lily
SQL> select * from test01 as of timestamp to_timestamp('2013-02-17 16:01:15','yyyy-mm-dd hh24:mi:ss');
ID NAME
---------- --------------------------------------------------
1 ann
2 Attacker
3 Lily
恢复误删除数据:
SQL> insert into test01 select * from test01 as of scn 559120;
SQL> insert into test01 select * from test01 as of timestamp to_timestamp('2013-02-17 16:01:15','yyyy-mm-dd hh24:mi:ss');
记得commit;
需要对多个相互有主外键约束的表进行恢复时,如果使用as of timestamp 的方式,可能会由于时间点不统一的缘故造成数据选择或插入失败,通过scn 方式则能够确保记录的约束一致性。
2)Flashback Version Query
相对于Flashback Query 只能看到某一点的对象状态, Oracle 10g引入的Flashback Version Query可以看到过去某个时间段内,记录是如何发生变化的。 根据这个历史,DBA就可以快速的判断数据是在什么时点发生了错误,进而恢复到之前的状态。
查询test01表的记录变化
SQL> select versions_xid,versions_startscn,versions_endscn,DECODE(versions_operation,'I','Insert','U','Update','D','Delete', 'Original') "Operation", id from test01 versions between scn minvalue and maxvalue;
VERSIONS_XID VERSIONS_STARTSCN VERSIONS_ENDSCN Operatio ID
---------------- ----------------- --------------- -------- ----------
0300040038010000 559870 Insert 2
0300040038010000 559870 Insert 3
05000F003F010000 559314 Delete 3
05000F003F010000 559314 Delete 2
05000F003F010000 559314 Delete 1
559314 Original 1
559314 Original 2
559314 Original 3
Flashback Version Query 技术其实有很多伪列,但是ORA_ROWSCN是最重要。它记录的是最后一次被修改时的SCN, 注意是被提交的修改。如果没有提交,这个伪列不会发生变化。
ORA_ROWSCN 缺省是数据块级别的,也就是一个数据块内的所有记录都是一个ORA_ROWSCN,数据块内任意一条记录被修改,这个数据库块内的所有记录的ORA_ROWSCN都会同时改变。上例的查询结果以证明。不过我们可以在建表时使用关键字 rowdependencies, 可以改变这种缺省行为,使用这个关键字后,每条记录都有自己的ORA_ROWSCN。
验证一下:
SQL> create table test02 (id integer) rowdependencies;
SQL> insert into test02(id) values(1);
1 row created.
SQL> insert into test02(id) values(2);
1 row created.
SQL> commit;
Commit complete.
查询发现两条插入同一时刻提交,ora_rowscn值一致:
SQL> select ora_rowscn,id from test02;
ORA_ROWSCN ID
---------- ----------
560556 1
560556 2
但是不同时刻提交:
SQL> insert into test02(id) values(3);
1 row created.
SQL> commit;
Commit complete.
SQL> insert into test02(id) values(4);
1 row created.
SQL> commit;
Commit complete.
SQL> select ora_rowscn,id from test02;
ORA_ROWSCN ID
---------- ----------
560556 1
560556 2
560659 3
560667 4
发现3和4的ORA_ROWSCN确实不同,得证;
3)Flashback Transaction Query
通过flashback_transaction_query视图可以查询到某个事务对数据的操作:
SQL> select xid,operation,commit_scn,undo_sql from flashback_transaction_query where xid in (select versions_xid from user01.test02 versions between scn minvalue and maxvalue);
XID OPERATION COMMIT_SCN UNDO_SQL
---------------- -------------------------------- ---------- ----------------------------------------------------------------------------------------------------
0200010034010000 INSERT 560667 delete from "USER01"."TEST02" where ROWID = 'AAAMizAAFAAAAAmAAD';
0200010034010000 BEGIN 560667
0100040037010000 INSERT 560659 delete from "USER01"."TEST02" where ROWID = 'AAAMizAAFAAAAAmAAC';
0100040037010000 BEGIN 560659
0A00090037010000 INSERT 560556 delete from "USER01"."TEST02" where ROWID = 'AAAMizAAFAAAAAmAAB';
0A00090037010000 INSERT 560556 delete from "USER01"."TEST02" where ROWID = 'AAAMizAAFAAAAAmAAA';
0A00090037010000 BEGIN 560556
7 rows selected.
4)Flashback Table
Flashback Table也是使用UNDO tablespace的内容来实现对数据的回退。该命令相对简单,输入:flashback table table_name to scn(to timestamp) 即可。注意:如果想要对表进行flashback,必须允许表的row movement.
查看test02表是否启用row movement:
SQL> select row_movement from user_tables where table_name='TEST02';
ROW_MOVE
--------
DISABLED
要禁止或者启用某表row movement:、
SQL> alter table test02 disable row movement;
Table altered.
SQL> alter table test02 enable row movement;
Table altered.
查询当前系统SCN和时间:
SQL> select current_scn from v$database;
CURRENT_SCN
-----------
561575
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2013-02-17 16:42:30
删除数据:
SQL> delete from test02 where id>2;
2 rows deleted.
SQL> commit;
Commit complete.
SQL> select * from test02;
ID
----------
1
2
闪回恢复并验证:
SQL> flashback table test02 to scn 561575;
或者
SQL> flashback table test02 to timestamp to_timestamp('2013-02-17 16:42:30','yyyy-mm-dd hh24:mi:ss');
Flashback complete.
SQL> select * from test02;
ID
----------
1
2
3
4
Flashback table 命令支持同时操作多个表,表名中间以逗号分隔即可,如果你执行一条flashback table命令时同时指定了多个表,要记住单个flashback table 是在同一个事务中,因此这些表的恢复操作要么都成功,要么都失败。如:flashback table a,b ,c to scn 561575;