oracle 闪回功能详解

时间:2022-12-26 07:34:12

  Oracle的闪回技术提供了一组功能,可以访问过去某一时间的数据并从人为错误中恢复。闪回技术是Oracle 数据库独有的,支持任何级别的恢复,包括行、事务、表和数据库范围。使用闪回特性,您可以查询以前的数据版本,还可以执行更改分析和自助式修复,以便在保持数据库联机的同时从逻辑损坏中恢复。

闪回技术包括以下特性:
   (1) 闪回查询允许用户查询过去某个时间点的数据,以重新构建由于意外删除或更改而丢失的数据。
   (2) 闪回版本查询提供了一种查看行级数据库随时间变化的方法。
   (3) 闪回事务查询提供了一种查看事务级数据库变化的方法。
   (4) 闪回数据库是进行时间点恢复的新策略。它能够快速将Oracle 数据库恢复到以前的时间,正确更正由于逻辑数据损坏或用户错误而引起的任何问题。
   (5) 闪回表功能使 DBA 可以非常快速、轻松地将一个表或一组表恢复至过去特定的某一时间点。
   (6) 闪回删除在删除对象时提供了一个安全网,您可以非常快速、轻松地取消对一个表及其相关对象对象的删除。

 Flashback技术是以Undo Segment中的内容为基础的, 因此受限于UNDO_RETENTON参数。要使用flashback 的特性,必须启用自动撤销管理表空间。闪回参数如下:

  Connected to Oracle Database 11g Enterprise Edition Release 11.1.0.7.0
  Connected as system@LOCAL_DB
  SQL> show parameter undo_
  NAME TYPE VALUE
  ------------------------------------ ----------- ------------------------------
  undo_management string AUTO
  undo_retention integer 900 --默认是1440 即24*60,只保留一天的闪回数据,具体值在安装数据库实例时可以设置
  undo_tablespace string UNDOTBS1

接下来讲讲oracle数据库闪回类型主要有三种:

  (1) 闪回数据库(flashback database)

    闪回数据库就是当出现逻辑错误时,能够将整个数据库回退到出错前的那个状态。

  (2) 闪回删除(flashback drop)

    Oracle10g之前,一旦删除了一个表,那么该表就会从数据字典里面删除。要恢复该表,需要进行不完全恢复。

    Oracle10g以后,当我们删除表时,默认Oracle只是在数据库字典里面对被删的表的进行了重命名,并没有真正的把表删除。

  (3) 闪回表(flashback table)

    所谓闪回表,就是将表里的数据会退到历史上的某个时间点,例如回退到用户误删除数据之前的时间点,从而将误删除的数据恢复回来,在这个过程中,数据库仍然可用,而且不需要类似于闪回日志一样的额外空间。闪回表利用的是undo表空间里记录的数据被改变前的值,如果闪回表所需要的undo数据,由于保留的时间超过了初始化参数undo_retention所指定的值,从而导致该undo数据块被其他事务覆盖,就不能恢复到指定的时间点了。

一、闪回数据库详解

  Flashback Database整个架构包括一个进程Recover Writer(RVWR)后台进程、Flashback Database Log日志和Flash Recovery Area。闪回数据库的实现机理是闪回日志,只要配置了闪回数据库,就会自动创建闪回日志。只要数据库里的数据发生变化,oracle会将数据修改前的旧值保存在闪回日志中。

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

(1)数据库配置为归档模式
  SQL> select log_mode from v$database;
    LOG_MODE
    ------------
    NOARCHIVELOG
  SQL> archive log list;
    数据库日志模式 非存档模式
    自动存档 禁用
    存档终点 USE_DB_RECOVERY_FILE_DEST
    最早的联机日志序列 320
    当前日志序列 322
1、启动归档为归档模式(其与将非归档模式转为归档模式步骤相似):
  (1)保存一致性,先关闭数据库
    shutdown immediate ;
  (2)启动到mount阶段
    startup mount;
  (3)启动闪回功能
    alter database flashback on; --alter database archivelog;将数据库改为规定模式
  (4)切换到open阶段
    alter database open;
  (5)对数据做一个完整备份
    full backup --可以使用数据泵(expdp)或者使用RMAN

 启动闪回功能完善。

 2、配置闪回恢复区(flash recovery area FRA)

 SQL> show parameter db_recovery_file
  NAME TYPE VALUE
  ------------------------------------ ----------- ------------------------------
  db_recovery_file_dest string D:\app\flash_recovery_area
  db_recovery_file_dest_size big integer 2G
一般在安装数据库实例时,会让你选择是否开启oracle数据闪回功能,默认是开启的,安装过程中可以配置闪回路径以及闪回空间的大小。
3、配置闪回保留时间
  SQL> show parameter db_flashback_retention_target
    NAME TYPE VALUE
    ------------------------------------ ----------- ------------------------------
    db_flashback_retention_target integer 1440
    db_flashback_retention_target参数用来控制flashback log 数据保留的时间,默认值是1440,单位是minute,即24小时。  4、启动数据库实例即可  5、获取当前时间点和SCN
   SQL> select dbms_flashback.get_system_change_number from dual;
   GET_SYSTEM_CHANGE_NUMBER
    ------------------------
     13081009
   SQL> select to_char(systimestamp,'yyyy-mm-dd HH24:MI:SS') as sysdt from dual;
   SYSDT
    -------------------
    2013-08-25 21:12:46    SQL> truncate table dept;
    Table truncated
 Flashback Database 实际是对数据库的一个不完全恢复操作,因为需要关闭数据库重启到mount状态。
  SQL> shutdown immediate;
   数据库已经关闭。
   已经卸载数据库。
   ORACLE 例程已经关闭。
  SQL> startup mount;
  ORACLE 例程已经启动。
  Total System Global Area 1071333376 bytes
  Fixed Size 1348508 bytes
  Variable Size 385879140 bytes
  Database Buffers 679477248
  bytes Redo Buffers 4628480 bytes
  数据库装载完毕。
  SQL> flashback database to timestamp to_timestamp('2013-08-25 21:12:46','yyyy-mm-dd HH24:MI:SS');
闪回完成。
 或者使用 SQL> flashback database to scn 13081009;

 在执行完flashback database 命令之后,oracle 提供了两种方式让你修复数据库:
  1) 直接alter database open resetlogs打开数据库,当然,指定scn或者timestamp时间点之后产生的数据统统丢失。
  2) 先执行alter database open read only命令以read-only模式打开数据库,然后立刻通过逻辑导出的方式将误操作涉及表的数据导出,再执行recover database命令以重新应用数据库产生的redo,将数据库修复到flashback database 操作前的状态,然后再通过逻辑导入的方式,将之前误操作的表重新导入,这样的话对现有数据的影响最小,不会有数据丢失。

  SQL>alter database open read only;

查询被truncate的表,是否已经闪回数据。
  SQL> select deptno from dept;
  deptno
  ----------------------------------------
  0105206000001
  0105108040001
  0105304000001
  0105304010001
  010560001
  0105600010001
  0105601000001
  0105602000001

  证明闪回成功。

二、闪回删除
  Oracle10g以后,当我们删除表时,默认Oracle只是在数据库字典里面对被删的表的进行了重命名,并没有真正的把表删除。
  回收站(recyclebin):用来维护表被删除前的名字与删除后系统生成的名字之间的对应关系的数据字典,表上的相关对象(索引、触发器等)也会一并进入回收站。

  SQL> show parameter recycle
  NAME                                 TYPE        VALUE
  ------------------------------------ ----------- ------------------------------
  buffer_pool_recycle                  string     
  db_recycle_cache_size                big integer 0
  recyclebin                                                  on

实例一:闪回sys用户下的表
SQL> select * from user_recyclebin;
OBJECT_NAME                    ORIGINAL_NAME                    OPERATION TYPE                      TS_NAME                        CREATETIME          DROPTIME               DROPSCN PARTITION_NAME                   CAN_UNDROP CAN_PURGE    RELATED BASE_OBJECT PURGE_OBJECT      SPACE
------------------------------ -------------------------------- --------- ------------------------- ------------------------------ ------------------- ------------------- ---------- -------------------------------- ---------- --------- ---------- ----------- ------------ ----------
SQL> drop table dept;
Table dropped
SQL> select * from user_recyclebin;
OBJECT_NAME                    ORIGINAL_NAME                    OPERATION TYPE                      TS_NAME                        CREATETIME          DROPTIME               DROPSCN PARTITION_NAME                   CAN_UNDROP CAN_PURGE    RELATED BASE_OBJECT PURGE_OBJECT      SPACE
------------------------------ -------------------------------- --------- ------------------------- ------------------------------ ------------------- ------------------- ---------- -------------------------------- ---------- --------- ---------- ----------- ------------ ----------
SQL>flashback table dept to before drop; --或者使用(flashback table dept to before drop rename to dept_bak;)
报如下错误:ORA-38305: 对象不在回收站中
原因:Flashback不支持sys用户与system表空间下的对象,也不能从回收站里拿到。故使用SYS或者SYSTEM用户登陆时,show recyclebin为空。
实例二:闪回非sys、system用户下的表

先删除表:
SQL> drop table DEPT_BAK;
Table dropped
SQL> select * from user_recyclebin a where a.original_name = 'DEPT_BAK';
OBJECT_NAME ORIGINAL_NAME OPERATION TYPE TS_NAME CREATETIME DROPTIME DROPSCN PARTITION_NAME CAN_UNDROP CAN_PURGE RELATED BASE_OBJECT PURGE_OBJECT SPACE
------------------------------ -------------------------------- --------- ------------------------- ------------------------------ ------------------- ------------------- ---------- -------------------------------- ---------- --------- ---------- ----------- ------------ ----------
BIN$BnpnsFC8SfSYdJ7Qio0k2g==$0 DEPT_BAK DROP TABLE TESTSPACE 2013-04-21:15:38:04 2013-08-25:22:11:45 13087074 YES YES 745783 745783 745783 8
SQL> flashback table DEPT_BAK to before drop;
Done

备注:

1、 禁用与启用recyclebin该功能:

  SQL> alter system set recyclebin=off;

  SQL> alter system set recyclebin=on;

禁用后删除的对象将直接删除,不会写到Recyclebin中,当然在删除时,指定purge参数,表也将直接删除,不会写到recyclebin中。

  SQL> drop table name purge;

2、关于purge命令

  表空间的RecycleBin区域只是一个逻辑区域,而不是从表空间上物理的划出一块区域固定用于回收站,因此RecycleBin是和普通对象共用表空间的存储区域,或者说是RecycleBin的对象要和普通对象抢夺存储空间。当发生空间不够时,Oracle会按照先入先出的顺序覆盖RecycleBin中的对象。也可以手动的删除Recycle Bin占用的空间。

  1) Purge tablespace tablespace_name;  用于清空表空间的RecycleBin

  2) Purge tablespace tablespace_name user user_name;  清空指定表空间的Recycle Bin中指定用户的对象

  3) Purge recyclebin;  删除当前用户的Recycle Bin中的对象

  4) Purge dba_recyclebin  删除所有用户的Recycle Bin中的对象,该命令要sysdba权限

  5) Drop table table_name purge;  删除对象并且不放在Recycle Bin中,即永久的删除,不能用Flashback恢复。

  6) Purge index recycle_bin_object_name;  当想释放Recycle bin的空间,又想能恢复表时,可以通过释放该对象的index所占用的空间来缓解空间压力。因为索引是可以重建的。

三、闪回表
  查询过去某个时刻表的数据的情况,一旦确认某个时刻的数据满足我们的需求以后,可以根据这个时间执行闪回表。

  ORA-08189: 因为未启用行移动功能, 不能闪回表,需要先执行一个命令:

  ALTER TABLE dept ENABLE ROW MOVEMENT。

 语法一:
  select * from dept
  VERSIONS BETWEEN TIMESTAMP SYSTIMESTAMP - INTERVAL '1' DAY AND SYSTIMESTAMP -INTERVAL '1' HOUR;
语法二:
  select * from dept as of timestamp to_timestamp('2013-08-25 21:12:46','yyyy-mm-dd HH24:MI:SS');
语法三:
  select * from dept as of scn 13081009;
语法四:
  select * from flashback_transaction_query a where a.table_name='DEPT';

附注:interval用法

Oracle语法:

INTERVAL '{ integer | integer time_expr | time_expr }' { { DAY | HOUR | MINUTE } [ ( leading_precision ) ] | SECOND [ ( leading_precision

[, fractional_seconds_precision ] ) ] } [ TO { DAY | HOUR | MINUTE | SECOND [ (fractional_seconds_precision) ] } ]

leading_precision值的范围是0到9, 默认是2. time_expr的格式为:HH[:MI[:SS[.n]]] or MI[:SS[.n]] or SS[.n], n表示微秒.

该类型与INTERVAL YEAR TO MONTH有很多相似的地方,建议先看INTERVAL YEAR TO MONTH再看该文.

INTERVAL '20' DAY - INTERVAL '240' HOUR = INTERVAL '10-0' DAY TO SECOND

表示: 20天 - 240小时 = 10天0秒

INTERVAL '30.12345' SECOND(2,4)

表示: 30.1235秒, 因为该地方秒的后面精度设置为4, 要进行四舍五入.

查询tableA中10分钟前的数据(闪回查询,前提:undo没有被覆盖..如果undo被覆盖,查询会失败)

Select * From table dept As Of Timestamp (systimestamp - Interval '10' minute);

-------------------THE END----------------------------

参考:http://www.cnblogs.com/coohoo/archive/2011/01/16/1936888.html