闪回技术是Oracle强大数据库备份恢复机制的一部分,在数据库发生逻辑错误的时候,闪回技术能提供快速且最小损失的恢复(多数闪回功能都能在数据库联机状态下完成)。须要注意的是,闪回技术旨在快速恢复逻辑错误,对于物理损坏或是介质丢失的错误,闪回技术就回天乏术了,仍是得借助于Oracle一些高级的备份恢复工具如RAMN去完成(这才是Oracle强大备份恢复机制的精髓所在啊)html
在讲闪回技术前,须要先了解Oracle中一个逻辑结构--撤销段。由于大部分闪回技术都须要依赖撤销段中的撤销数据。撤销数据是反转DML语句结果所需的信息,只要某个事务修改了数据,那么更新前的原有数据就会被写入一个撤销段。(事务回滚也会用到撤销段中的数据)。事务启动时,Oracle 会为其分配一个撤销段,事务和撤销段存在多对一的关系,即一个事务只能对应一个撤销段,多个事务能够共享一个撤销段(不过在数据库正常运行时通常不会发生这种状况)。数据库
Oracle提供了四种可供使用的闪回技术(闪回查询,闪回删除,闪回归档,闪回数据库),每种都有不一样的底层体系结构支撑,但其实这四种不一样的闪回技术部分功能是有重叠的,使用时也须要根据实际场景合理选择最合适的闪回功能。缓存
闪回查询(Flashback Query)session
a.基本闪回查询工具
功能描述:能够查询过去某个时间段的数据库状态。post
工做原理:Oracle 会提取所须要的撤销数据(前提是撤销是可用的,即撤销数据还没被覆盖)进行回滚,但这种回滚是临时的,仅针对当前session可见。大数据
SQL> select * from dept as of timestamp to_timestamp('2016-09-10 11:00:00','yyyy-mm-dd hh24:mi:ss');
b.闪回表url
功能描述:可将某个表回退到过去某个时间点spa
工做原理:一样,Oracle会先去查询撤销段,提取过去某个时间点以后的全部变动,构造反转这些变动的SQL语句进行回退,闪回操做是一个单独的事务,因此若因为撤销数据过时之类的缘由致使没法闪回,整个操做会回滚,不会存在不一致的状态。日志
步骤:
1.启用表闪回首先要在表上支持行移动(在数据字典中设置标识来标识该操做可能会改变行ID,即同一条数据闪回成功后主键都同样,但行ID其实已经发生变化了)
SQL> alter table emp enable row movement;
2.闪回表操做
SQL> flashback table dept to timestamp to_timestamp('2016-09-10 11:00:00','yyyy-mm-dd hh24:mi:ss');
闪回表可能会失败,有可能有如下几种状况:
违反了数据库约束,好比用户不当心删除了子表中的数据,如今想利用闪回表技术进行回退,刚好在这中间,父表中与该数据对应的那条记录也被删除了,在这种状况下,因为违反了外键约束,致使闪回表操做失败了;
撤销数据失效,好比用于支撑闪回操做的撤销数据被覆盖了,这种状况闪回表操做天然会失败;
闪回不能跨越DDL,即在闪回点和当前点之间,表结构有过变动,这种状况闪回操做也会失败。
注意:上述闪回功能都是基于撤销数据的,而撤销数据是会被重写的(Expired会被重写,Active不会被重写),因此,在须要使用这几种闪回功能去恢复数据的时候(确切地说,是须要使用基于撤销数据的闪回功能时),最短期发现错误,第一时间执行闪回操做,才能最大程度地保证闪回功能的成功。
功能描述:闪回删除能够轻松将一个已经被Drop的表还原回来。相应的索引,数据库约束也会被还原(除了外键约束)
原理描述:Drop命令实际上是Rename命令,早期的Oracle版本(10g以前),闪回删除意味着从数据字典中删除了该表的全部引用,虽然表中数据可能还存在,但已成了孤魂野鬼,无法进行恢复了,10g版本以后,Drop命令则仅仅是一个Rename操做,因此恢复就很容易了。
闪回删除操做执行命令很简单
SQL> flashback table emp to before
若是要还原的表名在当前系统中已经被占用,也能够在闪回删除的时候对表重命名
SQL> flashback table emp to before drop rename to emp_new
也能够经过回收站查看当前用户那些表被删除了,每一个用户都有一个回收站,这个回收站是个逻辑结构,它不是一块独立的存储空间,它存在在当前表空间内,因此若是有别的操做须要空间,好比如今须要建立一张表,没有足够空间可用,回收站中的数据就会被清理,这也是致使闪回删除失败的缘由。
SQL> SHOW RECYCLEBIN;
完全删除表,闪回删除也无能为力
SQL> DROP TABLE EMP PURGE;
清空回收站
SQL> PURGE RECYCLEBIN;
注意:闪回删除只针对Drop命令,注意区分truncate操做和drop操做,truncate称为表截断,会清空表中数据(调节Oracle高水位线实现),表结构不受影响,速度很快,弊端是此过程不会产生任何撤销数据或是重作日志,若是误删,恢复异常麻烦,要慎重使用。而Drop则会删除数据+表结构,闪回删除仅针对Drop操做。
功能描述:闪回数据归档可以使表具备回退到过去任什么时候间点的能力,前面提到的闪回查询,闪回表都会受限于撤销数据是否失效,若是撤销数据被覆盖重写了,闪回操做天然会失败,闪回删除则受限于表空间是否有足够可用空间,而闪回数据归档,则没有这些限制。
建立闪回归档
1.建立一个用户闪回数据归档的表空间,固然,也可使用已经存在的表空间。
SQL> create tablespace test_tb datafile 'test.dbf' size 20m;
2.建立一个保留时间为2年的闪回归档
SQL> create flashback archive test_fa tablespace test_tb retention 2 year;
为scott用户下的emp表启用闪回归档
1.赋予用户归档的权限
SQL> grant flashback archive on test_fa to scott;
2.链接用户
SQL> conn scott/tiger;
3.为emp表启用闪回归档
SQL> alter table emp flashback archive test_fa;
至此,emp表就拥有了能够查询或回退到过去2年任意时间点的能力!
功能描述:闪回数据库可将整个数据库回退到过去某个时间点,闪回表是某张表的时空穿梭,闪回数据库则是整个数据库的时空穿梭。固然,闪回点以后的全部工做就丢失了,其实就至关于数据库的不完整恢复,因此只能以resetlogs模式打开数据库。闪回数据库会形成停机时间,固然相比于传统备份恢复机制,恢复过程会快不少。
工做原理:闪回数据库不使用撤销数据,使用另一种机制来保留回退所须要的恢复数据,当启用闪回数据库,发生变化的数据块会不断从数据库缓冲区缓存中复制到闪回缓冲区,而后,称为恢复写入器(Recovery Writer)的后台进程会将这些数据刷新到磁盘中的闪回日志文件中。闪回的过程,则是一个 提取闪回日志-->将块映像复制回数据文件 的过程。
配置闪回数据库(闪回数据库要求数据库为归档模式)
1.指定闪回恢复区,也就是存放闪回日志的位置,但闪回恢复区不只仅是为了存放闪回日志,Oracle的不少备份恢复技术都用到这个区域,好比控制文件的自动备份等都会存放到此区域。
SQL> alter system set db_recovery_file_dest ='/flash_recovery_area';
2.指定恢复区大小
SQL> alter system set db_recovery_file_dest_size=4G;
3.指定闪回日志保留时间为2小时,即经过闪回操做,能够将数据库回退到前两小时内的任意时间点
SQL> alter system set db_flashback_retention_target=120;
4.有序关闭数据库--mount模式下启用闪回数据库--打开数据库
SQL> shutdown immediate;
SQL> startup mount; SQL> alter database flashback on; SQL> alter database open;
至此,闪回数据库配置完成!
使用闪回数据库功能
SQL> shutdown immediate; SQL> startup mount; SQL> flashback database to timestamp sysdate-60/1440; SQL> alter database open resetlogs;
本文列举了四类闪回技术,其中,闪回查询,包括基本闪回查询,闪回表等技术都依赖于撤销数据(还有一类闪回技术为闪回事务,能够对指定事务进行闪回操做,原理相似,借助于撤销数据来构建用于反转事务的SQL语句),依赖于撤销数据,则天然受限于撤销数据的保留时间,可能会因为撤销数据被覆写而致使闪回失败。闪回删除,则是因为10g版本后对表的删除仅表现为一个rename操做,引入回收站的概念,但此回收站仅是当前表空间的一块逻辑划分,因此会受限于当前表空间的可用空间的限制;闪回归档可提供查询或回退到过去任意时间点的功能,闪回数据库则是一中更极端的数据库恢复功能,至关于不完整恢复,依赖于闪回日志。
做者: dreamcatcher-cx
出处: <http://www.cnblogs.com/chengxiao/>
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在页面明显位置给出原文连接。