Oracle闪回技术@H_502_1@
@H_502_1@
1.Flashback Database@H_502_1@
2.Flashback Drop@H_502_1@
3.Flashback Table@H_502_1@
4.Flashback Query@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
1.Flashback Database(利用闪回日志恢复)@H_502_1@
@H_502_1@
描述:Oracle Flashback Database特性允许通过sql语句Flashback Database语句,让数据库前滚到当前的前一个时间点或者SCN。闪回数据库可以迅速将数据库回到误操作或人为错误的前一个时间点,如ctrl+Z操作,可以不利用备份就快速的实现基于时间点的恢复。Oracle通过创建新的Flashback Logs(闪回日志),记录数据库的闪回操作。如果希望能闪回数据库,需要设置如下参数:DB_RECOVER_FILE_DEST日志的存放位置,DB_RECOVER_FILE_DEST_SIZE恢复区的大小。@H_502_1@
@H_502_1@
注:在创建数据库的时候,Oracle将自动创建恢复区,但默认是关闭的,需要执行alter database flashback on命令。@H_502_1@
@H_502_1@
@H_502_1@
1. Flashback Database 不能解决Media Failure, 这种错误RMAN恢复仍是唯一选择@H_502_1@
2. 如果删除了数据文件或者利用Shrink技术缩小数据文件大小,这时不能用Flashback Database技术回退到改变之前的状态,这时候就必须先利用RMAN把删除之前或者缩小之前的文件备份restore 出来, 然后利用Flashback Database 执行剩下的Flashback Datbase。@H_502_1@
3. 如果控制文件是从备份中恢复出来的,或者是重建的控制文件,也不能使用Flashback Database。@H_502_1@
4. 使用Flashback Database锁能恢复到的最早的SCN, 取决与Flashback Log中记录的最早SCN。@H_502_1@
@H_502_1@
@H_502_1@
Flashback Database 包括一个进程Recover Writer(RVWR)后台进程,Flashback Database Log日志 和Flash Recovery Area。一旦数据库启用了Flashback Database, 则RVWR进程会启动,该进程会向Flash Recovery Area中写入Flashback Database Log, 这些日志包括的是数据块的" 前镜像", 这也是Flashback Database 技术不完全恢复块的原因。@H_502_1@
@H_502_1@
配置Flash Recovery Area@H_502_1@
要想使用Flashback Database, 必须使用Flash Recovery Area,因为Flashback Database Log只能保存在这里。 要配置的2个参数如下,一个是大小,一个是位置。如果数据库是RAC,flash recovery area 必须位于共享存储中。数据库必须处于archivelog 模式.@H_502_1@
@H_502_1@
启用Flash Recovery Area:@H_502_1@
sql>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=4G SCOPE=BOTH;@H_502_1@
sql>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST=‘/home/oracle/fast’ SCOPE=BOTH;@H_502_1@
@H_502_1@
禁用Flash Recovery Area:@H_502_1@
sql>ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='' ;@H_502_1@
对于Flash Recovery Area,Oracle 是这样建议的,flash recovery area 设置的越大,flashback database 的恢复能力就越强,因此建议flash recovery area 能够放的下所有的数据文件,增量备份,以及所有尚未备份的归档文件,当然还有它自己产生的flashback logs。@H_502_1@
@H_502_1@
在数据库运行过程中,oracle 自动向该区域写入文件,当剩余空间不足15%的时候,它就会在alert 中增加警告,提示你空间不足。但此时不会影响数据库的正常运转,直到所有空间统统被用掉之后,oracle 首先尝试删除寻些过期的文件,冗余文件或备份过的文件。@H_502_1@
@H_502_1@
步骤:@H_502_1@
@H_502_1@
配置参数信息;@H_502_1@
启动到mount状态@H_502_1@
@H_502_1@
检查Flashback 功能, 缺省时功能是关闭的。@H_502_1@
select name,current_scn,flashback_on from v$database;@H_502_1@
@H_502_1@
NAME CURRENT_SCN FLASHBACK_ON@H_502_1@
--------- ----------- ------------------@H_502_1@
PROD1 1064824 YES@H_502_1@
@H_502_1@
@H_502_1@
off为不打开,改为off可以在open状态下改,改完后flash_recovery_area下的flashback log文件会被Oracle自动删掉.@H_502_1@
这时候会在开始设定的目录/u01/app/oracle/flash_recovery_area 下生成一个ORCL/FLASHBACK目录(ORCL根据数据库名称变化),下面放的是flashback log文件.@H_502_1@
@H_502_1@
设置参数:DB_FLASHBACK_RETENTION_TARGET@H_502_1@
alter system set db_flashback_retention_target=1440 scope=both;@H_502_1@
该参数用来控制flashback log 数据保留的时间,或者说,你希望flashback database 能够恢复的最早的时间点。默认值是1440,单位是minute,即24 小时,需要注意的是该参数虽然未直接指定flash recovery area大小,但却受其制约,举个例子假如数据库每天有10%左右的数据变动的话,如果该初始化参数值设置为1440,则flash recovery area 的大小至少要是当前数据库实际容量的10%,如果该初始化参数设置为2880,则flash recovery area 的大小就至少是数据库所占容量的20%。@H_502_1@
@H_502_1@
@H_502_1@
例:@H_502_1@
@H_502_1@
sql> create table test1@H_502_1@
2 (id number,@H_502_1@
3 name varchar2(20));@H_502_1@
@H_502_1@
Table created.@H_502_1@
@H_502_1@
sql> create table test2@H_502_1@
2 (id number,@H_502_1@
3 name varchar2(20));@H_502_1@
@H_502_1@
Table created.@H_502_1@
@H_502_1@
sql> insert into test1 values(dbms_flashback.get_system_change_number,'A');@H_502_1@
@H_502_1@
1 row created.@H_502_1@
@H_502_1@
sql> insert into test2 values(dbms_flashback.get_system_change_number,'A');@H_502_1@
@H_502_1@
1 row created.@H_502_1@
@H_502_1@
@H_502_1@
Commit complete.@H_502_1@
@H_502_1@
sql> select * from test1;@H_502_1@
@H_502_1@
ID NAME@H_502_1@
---------- --------------------@H_502_1@
1065468 A@H_502_1@
@H_502_1@
sql> select * from test2;@H_502_1@
@H_502_1@
ID NAME@H_502_1@
---------- --------------------@H_502_1@
1065470 A@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
sql> SELECT CURRENT_SCN FROM V$DATABASE;@H_502_1@
@H_502_1@
CURRENT_SCN@H_502_1@
-----------@H_502_1@
1065501@H_502_1@
@H_502_1@
sql> select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual;@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
delete from test1;@H_502_1@
commit;@H_502_1@
select * from test1;@H_502_1@
no rows selected@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
insert into test2 values(dbms_flashback.get_system_change_number,'B');@H_502_1@
commit;@H_502_1@
select * from test2;@H_502_1@
@H_502_1@
ID NAME@H_502_1@
---------- --------------------@H_502_1@
1065470 A@H_502_1@
1065529 B@H_502_1@
@H_502_1@
@H_502_1@
恢复步骤@H_502_1@
shutdown immediate@H_502_1@
startup mount@H_502_1@
@H_502_1@
SCN或时间点恢复@H_502_1@
Flashback database to scn 1065501;@H_502_1@
@H_502_1@
Flashback database to timestamp to_timestamp('16-10-15 09:36:05','yy-mm-dd hh24:mi:ss');@H_502_1@
@H_502_1@
在执行完flashback database 命令之后,oracle 提供了两种方式让你修复数据库:@H_502_1@
1). 先执行alter database open read only 命令以read-only 模式打开数据库,然后立刻通过逻辑导出的方式将误操作涉及表的数据导出,再执行recover database 命令以重新应用数据库产生的redo,将数据库修复到flashback database 操作前的状态,然后再通过逻辑导入的方式,将之前误操作的表重新导入,这样的话对现有数据的影响最小,不会有数据丢失。@H_502_1@
2). 直接alter database open resetlogs 打开数据库,当然指定scn 或者timestamp 时间点之后产生的数据统统丢失。@H_502_1@
@H_502_1@
sql> alter database open read only;@H_502_1@
Database altered.@H_502_1@
sql> select * from test1;@H_502_1@
ID NAME@H_502_1@
---------- ----------@H_502_1@
3759479 A@H_502_1@
对于test1表,这里我们发现恢复点之前的数据已经闪回.这时候应该将闪回的test1表的数据导出,对数据库做完整的恢复,然后将数据导入.@H_502_1@
sql> select * from test2;@H_502_1@
ID NAME@H_502_1@
---------- ----------@H_502_1@
3759479 A@H_502_1@
对于test2表,这里我们发现恢复点之前的数据也存在,但是恢复点之后的数据(3761885 B)丢失了.@H_502_1@
sql> shutdown immediate@H_502_1@
@H_502_1@
exp sys/oracle@PROD1 file=/home/oracle/test1.dmp tables=test1@H_502_1@
@H_502_1@
sql> recover database;@H_502_1@
Media recovery complete.@H_502_1@
sql> alter database open;@H_502_1@
Database altered.@H_502_1@
再来验证数据:@H_502_1@
sql> select * from test1;@H_502_1@
no rows selected@H_502_1@
sql> select * from test2;@H_502_1@
ID VAL@H_502_1@
---------- ----------@H_502_1@
3759479 A@H_502_1@
3761885 B@H_502_1@
@H_502_1@
imp sys/oracle@PROD1 IGNORE=Y TABLES=test1 FULL=N file=/home/oracle/test1.dmp@H_502_1@
@H_502_1@
是完整恢复后的正确数据,把开始test1表的导出数据导入test1表,数据找回完成.@H_502_1@
和Flashback Database 相关的2个视图:@H_502_1@
1. V$database@H_502_1@
这个视图可以查看是否启用了Flashback database功能@H_502_1@
sql> select flashback_on from v$database;@H_502_1@
2. V$flashback_database_log@H_502_1@
Flashback Database 所能回退到的最早时间,取决与保留的Flashback Database Log 的多少, 该视图就可以查看许多有用的信息。@H_502_1@
Oldest_flashback_scn / Oldest_flashback_time : 这两列用来记录可以恢复到最早的时点@H_502_1@
Flashback_size: 记录了当前使用的Flash Recovery Area 空间的大小@H_502_1@
Retention_target: 系统定义的策略@H_502_1@
Estimated_flashback_size: 根据策略对需要的空间大小的估计值@H_502_1@
3. V$flashback_database_stat@H_502_1@
这个视图用来对Flashback log 空间情况进行更细粒度的记录和估计。 这个视图以小时为单位记录单位时间内数据库的活动量,Flashback_Data 代表Flashback log产生数量,DB_Date 代表数据改变数量,Redo_Date代表日志数量,通过这3个数量可以反映出数据的活动特点,更准确的预计Flash Recovery Area的空间需求@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
3、Flashback Drop(利用回收站功能恢复)@H_502_1@
@H_502_1@
Oracle的Flashback Drop闪回删除功能给出我们一种误删除表的便捷恢复方式,实现这种功能的原理是Oracle的“回收站”(RecycleBin)功能。注意,如果被删除的表原先是存放在SYSTEM系统表空间上,则不支持此功能。@H_502_1@
@H_502_1@
恢复被错误drop掉的表。当一张表被删除后,依然可以查看被drop表的内容,是通过查看回收站中的内容实现的。@H_502_1@
@H_502_1@
被删除的表将被存在一个叫recyclebin回收站的地方,当drop掉表后,实际上就是将改表改了个名字。@H_502_1@
@H_502_1@
回收站有关的视图@H_502_1@
DBA_RECYCLEBIN@H_502_1@
USER_RECYCLEBIN@H_502_1@
RECYCLEBIN@H_502_1@
@H_502_1@
被drop掉的表简短信息@H_502_1@
show recyclebin@H_502_1@
@H_502_1@
表空间不足@H_502_1@
purge命令@H_502_1@
使用flashback命令恢复表后,与之对应的回收站中的那条记录内容被清除@H_502_1@
@H_502_1@
@H_502_1@
FLASHBACK TABLE TEST3 TO BEFORE DROP;@H_502_1@
FLASHBACK TABLE "BIN$Z6gzDCWg7hfgQAB/AQAROQ==$0" TO BEFORE DROP;@H_502_1@
@H_502_1@
FLASHBACK TABLE TEST3 TO BEFORE DROP RENAME TO TEST3_VERSION_1;@H_502_1@
@H_502_1@
@H_502_1@
sql> create table test3@H_502_1@
2 (id number,@H_502_1@
3 name varchar2(30))@H_502_1@
4 tablespace users;@H_502_1@
@H_502_1@
Table created.@H_502_1@
@H_502_1@
sql> insert into test3 values(1,'A'@H_502_1@
2 );@H_502_1@
@H_502_1@
1 row created.@H_502_1@
@H_502_1@
sql> insert into test3 values(2,'B');@H_502_1@
@H_502_1@
1 row created.@H_502_1@
@H_502_1@
@H_502_1@
Commit complete.@H_502_1@
@H_502_1@
sql> select * from test3;@H_502_1@
@H_502_1@
ID NAME@H_502_1@
---------- ------------------------------@H_502_1@
1 A@H_502_1@
2 B@H_502_1@
@H_502_1@
sql> drop table test3;@H_502_1@
@H_502_1@
Table dropped.@H_502_1@
@H_502_1@
sql> show recyclebin;@H_502_1@
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME@H_502_1@
---------------- ------------------------------ ------------ -------------------@H_502_1@
TEST3 BIN$PujbM654As3gUKjAZhJL+A==$0 TABLE 2016-10-15:10:06:59@H_502_1@
@H_502_1@
@H_502_1@
sql> select * from test3;@H_502_1@
select * from test3@H_502_1@
*@H_502_1@
ERROR at line 1:@H_502_1@
ORA-00942: table or view does not exist@H_502_1@
@H_502_1@
@H_502_1@
sql> FLASHBACK TABLE TEST3 TO BEFORE DROP;@H_502_1@
Flashback complete.@H_502_1@
@H_502_1@
sql> select * from test3;@H_502_1@
@H_502_1@
ID NAME@H_502_1@
---------- ------------------------------@H_502_1@
1 A@H_502_1@
2 B@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
sql> purge recyclebin;@H_502_1@
sql> purge user_recyclebin;@H_502_1@
@H_502_1@
清除指定表空间tbs_sec_d的回收站@H_502_1@
sql> purge tablespace tbs_sec_d;@H_502_1@
@H_502_1@
清除指定表空间tbs_sec_d,同时指定用户sec的回收站@H_502_1@
sql> purge tablespace tbs_sec_d user sec;@H_502_1@
@H_502_1@
sql> purge dba_recyclebin@H_502_1@
@H_502_1@
这种方法是彻底删除表的方法,使用前要考虑清楚。@H_502_1@
sql> drop table ft_1 purge;@H_502_1@
@H_502_1@
@H_502_1@
3、Flashback Table(利用UNDO保留信息恢复)@H_502_1@
@H_502_1@
Oracle Flashback Table特性允许利用Flashback Table语句,确保闪回到表的前一个时间点。利用回滚段信息来恢复一个或一些表到以前的一个时间点(一个快照)。要注意的是,Flashback Table不等于Flashback Query,Flashback Query仅仅是查询以前的一个快照点而已,并不改变当前表的状态,而Flashback Table将改变当前表及附属对象一起回到以前的时间点。@H_502_1@
@H_502_1@
undo_management,参数需要是“AUTO”@H_502_1@
undo_retention,单位是秒,调整可回滚的时间范围@H_502_1@
@H_502_1@
在线操作@H_502_1@
恢复到指定的时间点(或者SCN)的任何数据@H_502_1@
满足分布式的一致性@H_502_1@
@H_502_1@
sql> flashback table test4 to timestamp to_timestamp('2012-12-29 16:44:17','yyyy-mm-dd hh24:mi:ss');@H_502_1@
sql> flashback table test4 to scn 662421;@H_502_1@
sql> flashback table test4 to timestamp to_timestamp('2012-12-29 16:44:17','yyyy-mm-dd hh24:mi:ss') enable triggers;@H_502_1@
@H_502_1@
普通用户中需要有Flashback any table的系统权限;@H_502_1@
有该表的select、insert、delete、alter权限;@H_502_1@
必须保证该表有row movement(行移动)。@H_502_1@
@H_502_1@
例:@H_502_1@
create table test4 tablespace users as select * from hr.employees;@H_502_1@
@H_502_1@
select count(*) from test4;@H_502_1@
@H_502_1@
select * from test4;@H_502_1@
@H_502_1@
为test4表创建索引@H_502_1@
create index ind_test4 on test4(employee_id);@H_502_1@
@H_502_1@
create or replace trigger tr_test@H_502_1@
after update on test4@H_502_1@
for each row@H_502_1@
begin@H_502_1@
null;@H_502_1@
end@H_502_1@
tr_test;@H_502_1@
/@H_502_1@
@H_502_1@
(sys)@H_502_1@
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') time,to_char(dbms_flashback.get_system_change_number) scn from dual;@H_502_1@
@H_502_1@
delete from test4;@H_502_1@
@H_502_1@
commit;@H_502_1@
@H_502_1@
drop index ind_test4;@H_502_1@
@H_502_1@
create or replace trigger tr_test@H_502_1@
after insert on test4@H_502_1@
for each row@H_502_1@
begin@H_502_1@
null;@H_502_1@
end@H_502_1@
tr_test;@H_502_1@
/@H_502_1@
@H_502_1@
确保该表中的行迁移(row movement)功能@H_502_1@
alter table test4 enable row movement;@H_502_1@
@H_502_1@
@H_502_1@
flashback table test4 to timestamp to_timestamp('2016-10-15 10:49:09','yyyy-mm-dd hh24:mi:ss') enable triggers;@H_502_1@
@H_502_1@
@H_502_1@
select index_name from user_indexes where table_name = 'test4';@H_502_1@
@H_502_1@
select object_name,status from user_objects where object_name in('TR_TEST','IND_TEST');@H_502_1@
@H_502_1@
select text from user_source t where t.name = 'TR_TEST';@H_502_1@
@H_502_1@
1. Flashback table在真正的高可用环境中,使用意义不大,受限比较多,要必须确保行迁移功能@H_502_1@
2. Flashback table过程中,阻止写操作@H_502_1@
3. 使用flashback table可以将delete方式删除的表闪回到之前某个时间点,而表中索引却不能正常恢复,因为drop索引的过程是不记录undo的。@H_502_1@
4. 恢复的触发器本身还是修改后的,并不随表flashback到修改以前的时间点。说明关键字enable triggers只能保证触发器的状态正常,而不是内容回滚.@H_502_1@
5. 由于原理利用其undo信息,来恢复其对象,因此也是不能恢复truncate数据@H_502_1@
6. 恢复数据用flashback query实现比较好@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
@H_502_1@
4.Flashback Query@H_502_1@
@H_502_1@
Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据!@H_502_1@
什么是多版本读一致性@H_502_1@
Oracle 采用了一种非常优秀的设计,通过undo 数据来确保写不堵塞读,简单的讲,不同的事务在写数据时,会将数据的前映像写入undo 表空间,这样如果同时有其它事务查询该表数据,则可以通过undo 表空间中数据的前映像来构造所需的完整记录集,而不需要等待写入的事务提交或回滚。@H_502_1@
@H_502_1@
flashback query 有多种方式构建查询记录集,记录集的选择范围可以基于时间或基于scn,甚至可以同时查询出记录在undo 表空间中不同事务时的前映象。用法与标准查询非常类似,要通过flashback query 查询undo 中的撤销数据,最简单的方式只需要在标准查询语句的表名后面跟上as of timestamp(基于时间)或as of scn(基于scn)即可。这个功能和flashback on/off 以及recyclebin on/off没有关系.@H_502_1@
@H_502_1@
例:@H_502_1@
@H_502_1@
create table test5@H_502_1@
(id number,@H_502_1@
name varchar2(20));@H_502_1@
@H_502_1@
Table created.@H_502_1@
@H_502_1@
sql> insert into hr.test5 values(dbms_flashback.get_system_change_number,'A'); (sys)@H_502_1@
@H_502_1@
@H_502_1@
select * from test5;@H_502_1@
@H_502_1@
ID NAME@H_502_1@
---------- --------------------@H_502_1@
1061963 A@H_502_1@
@H_502_1@
@H_502_1@
select to_char(sysdate,'yy-mm-dd hh24:mi:ss') time from dual;@H_502_1@
@H_502_1@
TIME@H_502_1@
-----------------@H_502_1@
16-10-15 11:27:15@H_502_1@
@H_502_1@
@H_502_1@
alter table test5 enable row movement;@H_502_1@
delete from test5;@H_502_1@
commit;@H_502_1@
@H_502_1@
select * from hr.test5 as of timestamp (SYSTIMESTAMP - INTERVAL '2' MINUTE);@H_502_1@
或者@H_502_1@
select * from test5 as of timestamp to_timestamp('16-10-15 11:27:15','YY-MM-DD hh24:mi:ss');@H_502_1@
@H_502_1@
insert into test5 select * from test5 as of timestamp to_timestamp('16-10-15 11:27:15','YY-MM-DD hh24:mi:ss');@H_502_1@
@H_502_1@
@H_502_1@
As of scn 示例@H_502_1@
SELECT dbms_flashback.get_system_change_number FROM dual;@H_502_1@
@H_502_1@
SELECT CURRENT_SCN FROM V$DATABASE;@H_502_1@
@H_502_1@
delete from hr.test5;@H_502_1@
@H_502_1@
commit;@H_502_1@
@H_502_1@
insert into hr.test5 select * from hr.test5 as of scn 1063434;@H_502_1@
commit;@H_502_1@
@H_502_1@
select * from hr.test5;@H_502_1@
@H_502_1@
事实上,Oracle 在内部都是使用scn,即使你指定的是as of timestamp,oracle 也会将其转换成scn,系统时间标记与scn 之间存在一张表,即SYS 下的SMON_SCN_TIME@H_502_1@
每隔5 分钟,系统产生一次系统时间标记与scn 的匹配并存入sys.smon_scn_time 表,该表中记录了最近1440个系统时间标记与scn 的匹配记录,由于该表只维护了最近的1440 条记录,因此如果使用as of timestamp 的方式则只能flashback 最近5 天内的数据(假设系统是在持续不断运行并无中断或关机重启之类操作的话)。@H_502_1@
注意理解系统时间标记与scn 的每5 分钟匹配一次这句话,举个例子,比如scn:3764577,3765348 分别匹配12-01-12 13:52:00 和12-01-12 13:57:00,则当你通过as of timestamp 查询12-01-12 13:52:00或12-01-12 13:57:00 这段时间点内的时间时,oracle 都会将其匹配为scn:3764577到undo 表空间中查找,也就说在这个时间内,不管你指定的时间点是什么,查询返回的都将是12-01-12 13:52:00 这个时刻的数据。@H_502_1@
查看SCN 和timestamp 之间的对应关系:@H_502_1@
select scn,to_char(time_dp,'yyyy-mm-dd hh24:mi:ss')from sys.smon_scn_time;@H_502_1@