• Learn How To Use Oracle Flashback


      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;

  • 相关阅读:
    [译]git reflog
    [译]git rebase -i
    [译]git rebase
    [译]git commit --amend
    [译]git clean
    [译]git reset
    [译]git revert
    [译]git checkout
    [译]git log
    [译]git status
  • 原文地址:https://www.cnblogs.com/assassinann/p/flashback.html
Copyright © 2020-2023  润新知