在oracle 9i中引入了flashback查询,flashback query实际上是利用UNDO信息来获得过去的数据。由于UNDO空间是循环使用的,事务的前映像不可能永久保存,因此flashback query只能支持过去一段时间内的数据查询,这个时间与undo_retention相关,undo_retention默认设置900s

       下面我们来看下flashback查询恢复数据的例子:

1、创建用户fly
SQL> create user fly identified by fly;
User created.
SQL> grant dba,connect,resource to fly;
Grant succeeded.
2、创建表和索引
SQL> conn fly/fly
Connected.
SQL> create table fly as select * from dba_objects;
Table created.
SQL> create index idx_fly on fly(object_id);
Index created.
SQL> select count(1) from fly;
COUNT(1)
----------
78193
3、更改会话时间显示格式
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
2013-12-05 21:19:52
4、假设误删除删除数据并提交了,如下所示:
SQL> delete from fly where rownum<500;
499 rows deleted.
SQL> commit;
Commit complete.
5、可考虑如下方法恢复数据,优先使用flashback
5.1 flashback
5.2 imp/impdp
5.3 rman
5.4 logminer
6、通过flashback技术来闪回查询表被删除前的时间点的数据,并保存为一张临时表
SQL> create table fly_tmp_1205 as select * from fly as of timestamp to_timestamp('2013-12-05 21:19:52','yyyy-mm-dd hh24:mi:ss');
Table created.
SQL> select count(*) from fly_tmp_1205;
COUNT(*)
----------
78193
如果只是大概记得是几分钟前被delete的,假设当前时间数据被删除了11分钟左右的话:
SQL> select count(1) from fly as of timestamp sysdate-11/1440;
COUNT(1)
----------
78193

          在Oracle 10g中,增强了闪回查询功能,并且提供了将整个数据库回退到过去某个时刻的能力,这个功能
是通过flashback log实现的。flashback log有点类似redo log,只不过redo log将数据库往前滚,flashback log
则将数据库往后滚。为了保存管理和备份恢复相关的文件,oracle10g提供了一个叫做闪回恢复,这个区域默认创建在ORACLE_BASE目录下。可以将所有恢复相关的文件,比如flashback log,archive log,
backup set等,放到这个区域集中管理。
         到了Oracle 11g,闪回又出了一个新特性:Oracle Flashback Data Archive. FDA通过将变化数据存储到另外创建的闪回归档区(Flashback Archive)中,和undo区别开来,这样就可以为闪回归档区单独设置存储策略,也可以闪回到指定时间之前的旧数据而不影响undo策略,就是减少对undo的依赖性。 因为在一个很忙的系统,undo保
存的时间是很有限的。 但通过FDA,我们就要灵活很多了。
         Flashback技术可以细分以下4种:
Flashback Database,需要开启闪回功能,默认不开启闪回功能,生产库一般不开启闪回功能
Flashback Drop,需要开启回收站,默认开启
Flashback Query(分Flashback Query, Flashback Version Query, Flashback Transaction Query 三种), 基于undo信息
Flashback Table。 用的不多,其原理也是基于undo信息,一般恢复数据使用flashback query来代替flashback table

如何查看闪回恢复区里包含的内容
SQL> select file_type from v$flash_recovery_area_usage;
FILE_TYPE
--------------------
CONTROL FILE
REDO LOG
ARCHIVED LOG
BACKUP PIECE
IMAGE COPY
FLASHBACK LOG
FOREIGN ARCHIVED LOG
7 rows selected.

        从Oracle 10g开始,在一些动态性能视图里面,如 V$CONTROLFILE, V$LOGFILE, V$ARCHIVED_LOG, V$DATAFILE_COPY 等都新增加了一列:IS_RECOVERY_DEST_FILE ,指明相关的文件是否在恢复区内。

SQL> select recid,is_recovery_dest_file from v$archived_log where recid<=5;
RECID IS_
---------- ---
1 YES
2 YES
3 YES
4 YES
5 YES

      1、设置flashback recovery area参数
闪回恢复区主要通过3个初始化参数来设置和管理:
db_recovery_file_dest:指定闪回恢复区的位置
db_recovery_file_dest_size:指定闪回恢复区的可用空间大小
db_flashback_retention_target:指定数据库可以回退的时间,单位为分钟,默认1440分钟,也就是一天。
当然,实际上可回退的时间还决定于闪回恢复区的大小,因为里面保存了回退所需要的flash log。所以这个
参数要和db_recovery_file_dest_size配合修改。

SQL> show parameter db_recovery
NAME                                TYPE       VALUE
-----------------------------------------------------------------------------
db_recovery_file_dest               string        /home/oracle/flash_recovery_area
db_recovery_file_dest_size     big integer   2G
SQL> alter system set db_recovery_file_dest_size=8G scope=both;
System altered.
SQL> alter system set db_recovery_file_dest='/u01/app/oracle/flash_recovery_area';
System altered.
SQL> show parameter db_recovery
NAME                                TYPE       VALUE
-----------------------------------------------------------------------------
db_recovery_file_dest               string          /u01/app/oracle/flash_recovery _area
db_recovery_file_dest_size        big integer   8G

说明:
        设置闪回恢复区后,如果没有设置过log_archive_dest_n参数,则归档日志默认是保存到该区域的。我们需要
注意闪回恢复区空间的使用率,如果闪回恢复区满了,就没地方放归档了,数据库会hang住,实际上,oracle是通
过隐式的设置log_archive_dest_10='location=USE_DB_RECOVERY_FILE_DEST'来实现的。多个数据库的闪回恢
复区可以指定到同一个位置,但是db_name不能一样,或者db_unique_name不一样。RAC的闪回恢复区必须位于
共享磁盘上,能被所有实例访问。

生产环境,一般建议更改归档路径到非闪回恢复区
SQL>alter system set  log_archive_dest_1='location=/archivelog';

 

     2、Flashback Database

       2.1、如何启用和禁用Flashback Database

数据库的Flashback Database功能缺省是关闭的,要想启用这个功能,就需要做如下配置。

(1)配置Flash Recovery Area
(2)启动flashback database  默认可以将数据库闪回1天内,根据db_flashback_retention_target参数
默认情况数据库的flashback database是关闭,可以在mount状态下打开。在设置了闪回恢复区后,可以启动闪回数据库功能。

SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
NO
--数据库必须已经处于归档模式:
SQL> archive log list;
SQL> shutdown immediate;
SQL>startup mount;
SQL>alter database flashback on;
SQL>alter database open;
SQL>select flashback_on from v$database;
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 3240239104 bytes
Fixed Size                  2164048 bytes
Variable Size            2499807920 bytes
Database Buffers          721420288 bytes
Redo Buffers               16846848 bytes
Database mounted.
SQL> archive log list;
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            /archivelog
Oldest online log sequence     511
Next log sequence to archive   514
Current log sequence           514
SQL> alter database flashback on;
Database altered.
SQL> alter database open;
Database altered.
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES

         2.2 使用Flashback Database 实现对数据库进行不完全恢复的示例

2.2.1. 查询当前的scn和时间
SQL> show user
USER is "SYS"
SQL>select dbms_flashback.get_system_change_number from dual;
或者
SQL>  select current_scn from v$database;
CURRENT_SCN
-----------
32945957
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
SQL> select sysdate from dual;
SYSDATE
-------------------
2013-12-05 23:12:39
2.2.2.  创建表
SQL> conn fly/fly
Connected.
SQL> drop table fly;
Table dropped.
SQL> create table fly as select * from dba_objects;
Table created.
2.2.3. 重启数据库到mount
SQL> conn sys/oracle as sysdba
Connected.
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 3240239104 bytes
Fixed Size                  2164048 bytes
Variable Size            2499807920 bytes
Database Buffers          721420288 bytes
Redo Buffers               16846848 bytes
Database mounted.
SQL>
2.2.4. 执行恢复:可以使用timestamp或者scn两种方式进行闪回
SQL>flashback database to timestamp to_timestamp('2013-12-05 23:12:39','yyyy-mm-dd hh24:mi:ss');
或者
SQL> flashback database to scn 32945957;
2.2.5. 需要以resetlogs打开数据库,查看fly表不存在
SQL>alter database open resetlogs;
SQL>select count(*) from fly;

 

 3、flashback drop
       flashback drop是从Oracle 10g开始出现的,用于恢复用户误删除的对象(包括表,索引等), 这个技术依赖于Tablespace Recycle Bin(表空间回收站),功能和windows的回收站非常类似。
      flashback drop不支持sys,system用户,因为它们创建的对象默认在system表空间。system表空间下的对象,被删除后,不会进入回收站。故使用sys或者system用户登陆时, show recyclebin 为空。

     3.1.Tablespace Recycle Bin
           从Oracle 10g 开始, 每个表空间都会有一个叫作回收站的逻辑区域,当用户执行drop命令时, 被删除的表和表的关联对象( 包括索引,约束,触发器,LOB段,LOB index 段)不会被物理删除, 这些对象先转移到回收站中,这就给用户提供了一个恢复的可能。
          注意:dba_recyclebin只保留非SYSTEM表空间下的对象,对于SYSTEM表空间的对象,在DROP的时候,也是直接删除,不会放入回收站。
          当一个对象drop后,如果开启了回收站功能.它并没有真正被删除,实际上只是修改了一下名字,我们用select * from user_objects where type= 'TABLE'还能查到.只是它的名字有点怪.例如BIN$qAUuckGyd3TgQKjAFAFTAg==$0

参数recyclebin用于控制是否启用recyclebin功能,缺省是ON, 可以使用OFF关闭。
SQL> show parameter recyclebin
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
recyclebin                           string      on
表空间的Recycle Bin 区域只是一个逻辑区域,而不是从表空间上物理的划出一块区域固定用于回收站,因此Recycle Bin是和普通对象共用表
空间的存储区域,或者说是Recycle Bin的对象要和普通对象抢夺存储空间。当发生空间不够时,Oracle会按照先入先出的顺序覆盖Recycle Bin中的对象。
也可以手动的删除Recycle Bin占用的空间:
1. Purge dba_recyclebin: 删除所有用户的Recycle Bin中的对象,该命令要sysdba权限
2. Purge recyclebin: 删除当前用户的Recycle Bin中的对象
3. Drop table table_name purge:  删除对象并且不放在Recycle Bin中,即永久的删除,不能用Flashback恢复。
4. Purge tablespace tablespace_name : 用于清空表空间的Recycle Bin
5. Purge tablespace tablespace_name user user_name: 清空指定表空间的Recycle Bin中指定用户的对象
6. Purge index recycle_bin_object_name: 当想释放Recycle bin的空间,又想能恢复表时,可以通过释放该对象的index所占用的空间来缓解空间压力。 因为索引是可以重建的。
3.2.查看回收站内容
禁用回收站后删除的对象将直接删除,不会写到recyclebin中,当然在删除时,指定purge 参数,表也将直接删除,不会写到recyclebin中。
查看recyblebin对象里的内容:
SQL>select * from "BIN$RWXQQcTPRde0ws4h9ewJcg==$0";
3.3.Flashback Drop 实例操作
恢复fly表:
SQL> flashback table fly to before drop;
如果fly表被删除后,又重新创建表的名字和fly一样,则可以恢复的时候rename成另外一张表名:
SQL>flashback table fly to before drop rename to fly007;

 

  4、Flashback Query 是利用多版本读一致性的特性从UNDO 表空间读取操作前的记录数据。
flashback query对v$tables,x$tables 等动态性能视图无效,但对于dba_*,all_*,user_*等数据字典是有效的。补充闪回查询恢复函数,存储过程,包,触发器等对象Flashback Drop 可以闪回与表相关联的对象, 如果是其他的对象,比如function,procedure,trigger等。 这时候,就需要使用到all_resource表来进行Flashback Query。

4.1.查看dba_source 的所有type
SQL> select type from all_source group by type;
TYPE
------------
PROCEDURE
PACKAGE
PACKAGE BODY
LIBRARY
TYPE BODY
TRIGGER
FUNCTION
TYPE
8 rows selected.
4.2.创建一函数
SQL> conn fly/fly
Connected.
SQL> CREATE OR REPLACE function getdate return date
2  as
3  v_date date;
4  begin
5     select  sysdate into v_date from dual;
6     return v_date;
7  end;
8  /
Function created.
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
SQL> select getdate() from dual;
GETDATE()
-------------------
2013-12-05 23:51:23
4.3.查询dba_source 表:
SQL>select text from dba_source where name='GETDATE' order by line;
SQL>drop function getdate;
4.4 Flashback Query 查询
SQL>select text from dba_source as of timestamp to_timestamp('2013-12-05 23:51:23','yyyy-mm-dd hh24:mi:ss') where name='GETDATE' order by line;