Flashback
Overview
• oracle数据库闪回技术主要使用于纠正用户错
  误, 比如错误地提交了事务, 在某些时候闪回还
  可以替代传统的数据库恢复操作. 本章将介绍
  闪回技术的以下方面:
 – 从回收站中还原已删除的表
 – 闪回查询(flashback query)
 – 闪回事务(flashback transaction)
 – 闪回表相关的操作(flashback table operations)
 – 数据库闪回
 – 设置和使用闪回数据的归档
Flashback types
• 共有四种闪回技术, 可以应用在不同的方面, 在功能上它们存在一定的交集.
  分别简述如下:
  – flashback database
  数据库闪回对数据库进行回滚, 最终将数据库还原至某一个过去的时间点, 此时必
  须使用resetlogs选项打开数据库. 在效果上这相当于执行了一次数据库的不完全恢
  复(数据库闪回速度更快也更为灵活), 不同的是数据库闪回不能处理坏块和介质丢
  失, 这种情况下只能使用不完全恢复.
  – flashback query, transaction, and table
  这三种闪回操作均基于数据库的回滚段,
      • 闪回查询
      可以查询过去的某个时间点的数据, 比如半个小时之前的数据.
      • 事务闪回
      事务闪回会针对某个事务(通常指导致错误的事务)生成一个与该事务效
      果正好相反的事务, 以抵消该事务的影响.
      • 表闪回
      如果对表进行了误操作, 执行了错误的更新, 可以使用表闪回将该表闪回
      到某个时间点.
Flashback types
– flashback drop
在当前的数据库版本中DROP语句不会实际上删除一张表, 而只是将
表更改为一个系统生成的名称. 在该表占用的空间没有被覆盖的情况
下, 可以使用闪回删除将该表修改为之前的名称(数据仍存在).
Tip: 闪回删除不能应用于truncate table的情况.
– flashback data archive
以上三种闪回技术均存在时间限制, 数据库闪回限制于闪回日志, 闪
回查询限制于回滚段的存留, 闪回删除则依赖于表空间中可用的空间,
针对表的数据归档闪回则可以被设置为保存所有的历史记录, 因此也
常被称为(Total Recall). 当对一个表启用数据归档闪回时, 另外一个表
将会被创建以存储当前表数据所有的版本, 这通过进FBDA(flashback
data archive process)执行. 通常而言会为数据归档闪回指定一个时间.
Flashback
        - When to use
• 不同的闪回技术被使用在不同的场景, 下面描述
  了这些具体的场景:
 – flashback database
 在执行数据库的不完全恢复时, 可以考虑使用数据库
 闪回作为替代, 后者需要花费的时间更少. 数据库闪
 回需要进行相应的配置, 比如设置数据库归档模式 etc.
 – flashback drop
 当需要撤销对表的删除操作时(un-drop), 使用闪回删
 除, 该表将恢复到被删除之前的状态.
 – flashback table, transaction
 表/事务闪回用于更为细粒度的数据恢复.
 Tip: 对于介质丢失或者损坏的情形, 闪回技术无法进行处
 理, 应当使用传统的数据还原和恢复机制.
Flashback Database
               - Architecture
• Architecture
  当数据库闪回被启用, 数据块缓冲区的修改将导致该数据块被拷贝到SGA
  一个新的内存缓冲区: 闪回缓冲区(flashback buffer). 随后RVWR(Recovery
  Writer)进程将该缓冲区的内容写入到闪回日志(flashback logs), 闪回日志记
  录的是数据块历史版本的内容.
  Tip: 与重做日志不同的是, 闪回日志不能进行归档和多路复用. 它被自动创
  建和管理.
  Tip: 不是所有对数据块的修改都会导致该版本被写入闪回日志, 这样会对
  数据库的整体性能产生巨大影响.
  当执行数据库闪回时, 根据闪回的时间点, 闪回日志中的相应的数据块(与
  闪回时间点最近的)被拷贝至数据文件中, 此时数据库会处在一种不一致的
  状态(闪回日志没有记录数据块所有的历史版本). 重做日志将会被使用, 从
  而将数据库恢复到一致的状态. 示例:
  数据块A在10:00/10:05被修改, 10:00的修改被拷贝至闪回日志; 数据块B在
  10:05/10:20被修改, 均被拷贝至闪回日志. 此时是11:00, 需要将数据库闪回
  到10:15. 数据块闪回操作将会拷贝数据块A在10:00的版本和数据块B在
  10:05的版本, 之后执行重做日志.
  Tip: 数据块闪回要求数据库运行在归档模式, 并且在闪回操作之后需要使
  用resetlogs选项打开数据库.
Flashback Database
              - Configuration
• 配置数据库闪回会导致一定的downtime, 因为有的配置只能
  在mount阶段执行. 按照如下步骤进行配置:
 – 配置数据库归档模式, 使用下面的SQL进行检查:
 select log_mode from v$database;
 – 配置闪回区(flash recovery area), 参考:
 《Configure Database for Backup and Recovery》
 – 配置闪回日志存留的时间, 这限制了数据库能够向前闪回的时间
    段. 使用参数db_flashback_retention_target进行配置, 单位为分钟,
    默认为1天. 示例:
    alter system set db_flashback_retention_target=240;
 – 重启数据库至mount, 开启闪回后打开数据库
    shutdown immeidate;
    startup mount;
    alter database flashback on;
    alter database open;
Flashback Database
                 - Monitor
• 可以通过以下方面监控数据库闪回的状态,
 – 是否开始了数据库闪回?
   select flashback_on from v$database;
 – 在linux/Unix系统上可以查看到RVWR进程, 在
   windows平台它实现为ORACLE.exe的一个线程.
 – 通过视图v$flashback_database_log可以查询当前闪
   回日志占用的空间, 以及为达到目标预估需要的空
   间, 数据库能闪回到的最早时间;
   通过视图v$flashback_database_stat查询为支持数
   据库闪回在每小时进行的IO读写统计信息
 – 通过以下查询闪回缓冲占用的内存,
   select * from v$sgastat where name = 'flashback generation buff';
Flashback Database
                    - SQL*PLUS
• 可以通过以下三种方式进行数据库闪回操作: SQL*PLUS, RMAN以及
  Database Control, 无论使用哪种方式实质上执行的动作是一样的:
   – 关闭数据库并重启至MOUNT阶段;
   – 将数据库闪回到指定的时间点, SCN或者某个日志切换序号;
   – 使用resetlogs选项打开数据库.
• 下面以一个假设的情况进行演示, 某用户在2013/3/17日下午3点之后drop
  了一张表, 现在需要使用数据库闪回恢复该表. 由于无法确定具体的删除时
  间, 首先闪回到3:00:
      shutdown abort;
      startup mount;
      flashback database to timestamp to_timestamp('07-03-13 15:00:00',
                'dd-mm-yy hh24:mi:ss');
     alter database open read only;
  此时发现该表已经存在, 可以重复执行上面的动作进行检查以恢复更多的
  数据. 最后使用如下命令正常打开数据库:
      shutdown abort;
     startup mount;
      alter database open resetlogs;
Flashback Database
       - RMAN & Database Control
• 类似地在RMAN中也使用flashback database命
  令执行数据库闪回, 示例:
 flashback database to time = to_date('20-12-08 10:00:00',‘
             yy-mm-dd hh24:mi:ss');
 flashback database to scn=2728665;
 flashback database to sequence=2123 thread=1;
• 也可以在database control执行数据库闪回, 与
  前两种方式不同的是, 它只能指定闪回到某分
  钟, RMAN可以指定秒, SQL*PLUS可以闪回到某
  个时间戳.
Flashback Drop
                       - Overview
• 从数据库版本10g开始, 在执行DROP命令删除表时实际上执行的是alter
  table ... rename to命令修改了表的名称, 可以通过user_recyclebin和
  dba_recyclebin视图查询这些被删除的对象.闪回删除正是利用了这一特
  性, 它能够将表恢复到删除之前的状态, 这包括表的数据/索引/触发器和
  权限设置/非空和主键约束, 但不包含外键约束(被物理删除).
  Tip: drop table时如果指定purge选项, 将无法在回收器中找到相应的记录.
• 闪回删除不能确保能够成功执行, 这有可能是之前表占用的空间被覆盖,
  或者创建了另一张同名的表. 下面是一个执行闪回删除的示例:
    conn demo/demo;
    drop table newtab purge;
    select * from newtab; -- error
    flashbask table newtab to before drop;
  Tip: 如果需要闪回的表名称已经被使用那么必须使用rename to子句对表进行
       重命名.
  Tip: SYSTEM表空间的表不支持闪回删除, 它们被删除时会立即purge掉.
Flashback Drop
                - Recycle Bin
• 回收站用于管理已经模式下被drop掉的对象,
  回收站对象的空间在需要使用时可以被覆盖.
  默认情况下回收站可用, 使用实例参数
  RECYCLEBIN控制是否启用回收站, 该参数是一
  个动态参数. 可以在session或者system级别设
  置.
• 查看回收站的内容
 – 使用show recyclebin命令查看;
 – 查询dba_recyclebin或者user_recyclebin视图. 示例:
   select original_name, object_name, operation, type,
     droptime, can_undrop from user_recyclebin;
Flashback Query
                         - Overview & Basic
•   自9i版本开始闪回查询被引入, 在该版本中可用于查询数据库在过去某个时间点的数据. 在后续的版
    本中, 闪回查询功能被增强, 可用于查询数据行的所有版本、撤销已提交的事务、或者将表闪回到
    过去的某一个时间点 .
    Tip: 闪回查询的所有形式均依赖于回滚数据.
•   Basic Flashback Query
    下面是一个基础闪回查询的示例:
    select to_char(sysdate,'dd-mm-yy hh24:mi:ss') from dual; -- 07-03-13 23:57:57
    select * from newtab;
          C2
          ---------
          07-MAR-13
    delete from newtab;
    commit;
    select * from newtab; -- no data
    select * from newtab as of timestamp to_timestamp('07-03-13 23:57:57',
            'dd-mm-yy hh24:mi:ss'); -- same data as above
    有的时候需要连续执行多个闪回查询, 为了避免在每次查询都要指定闪回的时间点, 可以通过以下
    调用将查询设置在某一个时间点:
    execute dbms_flashback.enable_at_time(to_timestamp('27-12-08 16:54:06',
         'dd-mm-yy hh24:mi:ss'));
    取消该设置:
    execute dbms_flashback.disable;
    Tip: 如果无法通过回滚段重建指定时间点的数据, 那么ORA-08180: “No snapshot found based on
    specified time”错误将会被抛出.
Flashback Query
                           - Flashback Table
•   表闪回利用了回滚段, 在一个独立的事务中进行回滚操作. 如果闪回的表存在外键约束, 那么闪回操
    作通常会失败. 表闪回的一个前提条件是该表要开启行迁移(row movement). 下面以dep和emp表为
    例, 其中emp外键引用了dep表:
    -- 数据初始化
    create table dep(id NUMBER primary key, name VARCHAR2(100),
            location VARCHAR2(200));
    create table EMP(id NUMBER, name VARCHAR2(100), title VARCHAR2(100),
            dep_id NUMBER);
    alter table emp add constraint fk_emp_dep foreign key(dep_id) references dep(id);
    insert into dep values(50,'SUPPORT','LONDON');
    insert into emp values(8000,'WATSON','ANALYST',50);
    commit;
    -- 闪回数据
    delete from emp where id = 8000;
    delete from dep where id = 50;
    commit;
    -- 执行表闪回
    flashback table emp to timestamp to_timestamp('08-03-13 10:00:00',
            ‘dd-mm-yy hh24:mi:ss’); -- ORA-08189提示表没有开启行迁移
    --表开启行迁移
    alter table emp enable row movement;
    alter table dep enable row movement;
Flashback Query
                    - Flashback Table
 再次对emp表执行闪回, 这一次会因为外键约束的原因
 失败. oracle支持同时对多个表进行闪回(外键约束在闪
 回操作的末尾进行检查), 以解决上述的问题:
 flashback table emp, dep to timestamp to_timestamp('08-03-13 10:00:00',
       'dd-mm-yy hh24:mi:ss');
• 表闪回操作还可能会因为下面的原因失败:
  – 违反主键约束, 某个主键在被删除之后被重用;
  – ORA-08180: 快照太旧;
  – ORA-00054: 行被锁定. 需要闪回的行被用户锁定;
  – ORA-01466: 表定义发生变化. 表闪回不支持闪回到之前表
    的定义;
  – 对于SYS模式下的对象, 不支持表闪回操作.
• 默认情况下进行表闪回时触发器被禁用, 可以通过如下
  方式启用触发器:
      flashback table emp,dept to scn 6539425 enable triggers;
Flashback Query
                     - Flashback Versions
• 版本查询可以用于查看数据的历史版本, 在执行该查询时以下伪列被支持:
  – VERSIONS_STARTSCN
  行数据版本被创建时的SCN, 使用insert或者update;
  – VERSIONS_STARTTIME
  行数据版本被创建时的时间;
  – VERSIONS_ENDSCN
  行数据版本被更新或者删除时的SCN;
  – VERSIONS_ENDTIME
  行数据版本被更新或者删除的时间;
  – VERSIONS_XID
  行数据版本被创建的事务标识;
  – VERSION_OPERATION
  行数据版本创建的操作, INSERT/UPDATE/DELETE.
 查询示例:
 select id, name, title, dep_id, versions_xid, versions_startscn, versions_endscn, versions_operation
 from emp versions between scn minvalue and maxvalue where id = 8000;
 Tip: versions between 子句还可以指定为时间间隔, 比如:
       versions between timestamp (systimestamp - 1/24) and systimestamp
 Tip: 版本查询不支持使用在外部表/临时表/V$视图, 因此它们不会生成undo.
Flashback Query
                  - Flashback Transaction
•   闪回查询和版本查询会使用特定对象的undo数据,事务闪回则需要分析特定事务的undo, 这可能涉
    及到很多不同的对象. 使用事务闪回的一个前提是开启数据库supplemental logging, 使用下面的命令:
    ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
•   与事务闪回相关的视图是flashback_transaction_query, 该视图的undo_sql列包含了进行事务闪回操
    作相关的SQL语句. 查询该视图需要有select any transaction权限, 默认情况下该权限被分配给SYS账户
    和DBA角色. 接着以上面的emp/dep为例, 闪回对emp/8000的update事务:
    –   首先使用版本查询确认事务的id(versions_xid)
         select id, name, title, dep_id, versions_xid
         from emp versions between scn minvalue and maxvalue
         where id = 8000;
    –   使用flashback_transaction_query视图可以查看相应的undo sql
            select operation,undo_sql from flashback_transaction_query
            where xid=hextoraw('08000400DD030000');
    –   使用dbms_flashback包进行事务闪回, 示例:
         execute dbms_flashback.transaction_backout(numtxns=>1, xids=>sys.xid_array('08000400DD030000'),
            options=>dbms_flashback.cascade);
         commit; -- 提交
         该存储过程的参数说明:
         • numtxns 需要闪回的事务数量
         • xids                 事务id列表
         • options              附加选项, 可以有:
               – cascade        闪回事务时, 避免出现违反数据库约束
               – noncascade     不处理数据库约束, 这可能会导致闪回失败(默认值)
               – nonconflict_only
               – noncascade_force
Flashback and Undo
• 闪回查询完全依赖于UNDO数据, 如果某个时间点
  的undo数据被覆盖那么针对该时间点的闪回查询
  将会失败, “ORA-1555: 快照过旧”错误被抛出.
  undo数据被保存在undo表空间中, 为了保证闪回
  查询在一定的时间段内能够成功执行, 需要作如
  下设置:
 – 设置实例参数undo_retention;
 – 设置undo表空间的RETENTION GUARANTEE属性.
 这样带来的一个问题是, 如果表空间的大小没有被设置
 为一个合理的大小, 在表空间被使用完时, 会导致当前事
 务的DML操作停止往下执行(hanged). 可以通v$undostat
 视图计算undo表空间合理的大小.
Flashback Data Archive
•   前面介绍的闪回技术在时间上都有一定的限制(通常不会太长), 归档闪回则可以设置为闪回到过去的任意时间. 下
    面使用示例进行演示:
     –   创建用于归档闪回的表空间, 该表空间用于存放支持归档闪回表的历史数据
    create tablespace fda datafile 'fda1.dbf' size 10m;
     –   在该表空间中创建闪回归档, 指定存留时间为7Y
    create flashback archive fla1 tablespace fda retention 7 year;
     –   创建相应的用户并授予权限
    grant dba to fbdauser identified by fbdauser;
    grant flashback archive on fla1 to fbdauser;
     –   登录该用户创建表并设置归档闪回
    connect fbdauser/fbdauser
    create table t1 as select * from all_users;
    alter table t1 flashback archive fla1;

     –   查询FDA表空间, 相应的段被创建, 该段包含了被保护对象的历史数据
    select segment_name,segment_type from dba_segments where tablespace_name='FDA';
     –   实例归档查询
    delete from t1;
    commit;
    select count(*) from t1;
    select count(*) from t1 as of timestamp(sysdate - 2/1440);

     –   as SYSDBA
    alter table fbdauser.t1 no flashback archive;
    drop user fbdauser cascade;
    drop tablespace fda including contents and datafiles;
    drop flashback archive fla1;
END

10, OCP - flashback

  • 1.
  • 2.
    Overview • oracle数据库闪回技术主要使用于纠正用户错 误, 比如错误地提交了事务, 在某些时候闪回还 可以替代传统的数据库恢复操作. 本章将介绍 闪回技术的以下方面: – 从回收站中还原已删除的表 – 闪回查询(flashback query) – 闪回事务(flashback transaction) – 闪回表相关的操作(flashback table operations) – 数据库闪回 – 设置和使用闪回数据的归档
  • 3.
    Flashback types • 共有四种闪回技术,可以应用在不同的方面, 在功能上它们存在一定的交集. 分别简述如下: – flashback database 数据库闪回对数据库进行回滚, 最终将数据库还原至某一个过去的时间点, 此时必 须使用resetlogs选项打开数据库. 在效果上这相当于执行了一次数据库的不完全恢 复(数据库闪回速度更快也更为灵活), 不同的是数据库闪回不能处理坏块和介质丢 失, 这种情况下只能使用不完全恢复. – flashback query, transaction, and table 这三种闪回操作均基于数据库的回滚段, • 闪回查询 可以查询过去的某个时间点的数据, 比如半个小时之前的数据. • 事务闪回 事务闪回会针对某个事务(通常指导致错误的事务)生成一个与该事务效 果正好相反的事务, 以抵消该事务的影响. • 表闪回 如果对表进行了误操作, 执行了错误的更新, 可以使用表闪回将该表闪回 到某个时间点.
  • 4.
    Flashback types – flashbackdrop 在当前的数据库版本中DROP语句不会实际上删除一张表, 而只是将 表更改为一个系统生成的名称. 在该表占用的空间没有被覆盖的情况 下, 可以使用闪回删除将该表修改为之前的名称(数据仍存在). Tip: 闪回删除不能应用于truncate table的情况. – flashback data archive 以上三种闪回技术均存在时间限制, 数据库闪回限制于闪回日志, 闪 回查询限制于回滚段的存留, 闪回删除则依赖于表空间中可用的空间, 针对表的数据归档闪回则可以被设置为保存所有的历史记录, 因此也 常被称为(Total Recall). 当对一个表启用数据归档闪回时, 另外一个表 将会被创建以存储当前表数据所有的版本, 这通过进FBDA(flashback data archive process)执行. 通常而言会为数据归档闪回指定一个时间.
  • 5.
    Flashback - When to use • 不同的闪回技术被使用在不同的场景, 下面描述 了这些具体的场景: – flashback database 在执行数据库的不完全恢复时, 可以考虑使用数据库 闪回作为替代, 后者需要花费的时间更少. 数据库闪 回需要进行相应的配置, 比如设置数据库归档模式 etc. – flashback drop 当需要撤销对表的删除操作时(un-drop), 使用闪回删 除, 该表将恢复到被删除之前的状态. – flashback table, transaction 表/事务闪回用于更为细粒度的数据恢复. Tip: 对于介质丢失或者损坏的情形, 闪回技术无法进行处 理, 应当使用传统的数据还原和恢复机制.
  • 6.
    Flashback Database - Architecture • Architecture 当数据库闪回被启用, 数据块缓冲区的修改将导致该数据块被拷贝到SGA 一个新的内存缓冲区: 闪回缓冲区(flashback buffer). 随后RVWR(Recovery Writer)进程将该缓冲区的内容写入到闪回日志(flashback logs), 闪回日志记 录的是数据块历史版本的内容. Tip: 与重做日志不同的是, 闪回日志不能进行归档和多路复用. 它被自动创 建和管理. Tip: 不是所有对数据块的修改都会导致该版本被写入闪回日志, 这样会对 数据库的整体性能产生巨大影响. 当执行数据库闪回时, 根据闪回的时间点, 闪回日志中的相应的数据块(与 闪回时间点最近的)被拷贝至数据文件中, 此时数据库会处在一种不一致的 状态(闪回日志没有记录数据块所有的历史版本). 重做日志将会被使用, 从 而将数据库恢复到一致的状态. 示例: 数据块A在10:00/10:05被修改, 10:00的修改被拷贝至闪回日志; 数据块B在 10:05/10:20被修改, 均被拷贝至闪回日志. 此时是11:00, 需要将数据库闪回 到10:15. 数据块闪回操作将会拷贝数据块A在10:00的版本和数据块B在 10:05的版本, 之后执行重做日志. Tip: 数据块闪回要求数据库运行在归档模式, 并且在闪回操作之后需要使 用resetlogs选项打开数据库.
  • 7.
    Flashback Database - Configuration • 配置数据库闪回会导致一定的downtime, 因为有的配置只能 在mount阶段执行. 按照如下步骤进行配置: – 配置数据库归档模式, 使用下面的SQL进行检查: select log_mode from v$database; – 配置闪回区(flash recovery area), 参考: 《Configure Database for Backup and Recovery》 – 配置闪回日志存留的时间, 这限制了数据库能够向前闪回的时间 段. 使用参数db_flashback_retention_target进行配置, 单位为分钟, 默认为1天. 示例: alter system set db_flashback_retention_target=240; – 重启数据库至mount, 开启闪回后打开数据库 shutdown immeidate; startup mount; alter database flashback on; alter database open;
  • 8.
    Flashback Database - Monitor • 可以通过以下方面监控数据库闪回的状态, – 是否开始了数据库闪回? select flashback_on from v$database; – 在linux/Unix系统上可以查看到RVWR进程, 在 windows平台它实现为ORACLE.exe的一个线程. – 通过视图v$flashback_database_log可以查询当前闪 回日志占用的空间, 以及为达到目标预估需要的空 间, 数据库能闪回到的最早时间; 通过视图v$flashback_database_stat查询为支持数 据库闪回在每小时进行的IO读写统计信息 – 通过以下查询闪回缓冲占用的内存, select * from v$sgastat where name = 'flashback generation buff';
  • 9.
    Flashback Database - SQL*PLUS • 可以通过以下三种方式进行数据库闪回操作: SQL*PLUS, RMAN以及 Database Control, 无论使用哪种方式实质上执行的动作是一样的: – 关闭数据库并重启至MOUNT阶段; – 将数据库闪回到指定的时间点, SCN或者某个日志切换序号; – 使用resetlogs选项打开数据库. • 下面以一个假设的情况进行演示, 某用户在2013/3/17日下午3点之后drop 了一张表, 现在需要使用数据库闪回恢复该表. 由于无法确定具体的删除时 间, 首先闪回到3:00: shutdown abort; startup mount; flashback database to timestamp to_timestamp('07-03-13 15:00:00', 'dd-mm-yy hh24:mi:ss'); alter database open read only; 此时发现该表已经存在, 可以重复执行上面的动作进行检查以恢复更多的 数据. 最后使用如下命令正常打开数据库: shutdown abort; startup mount; alter database open resetlogs;
  • 10.
    Flashback Database - RMAN & Database Control • 类似地在RMAN中也使用flashback database命 令执行数据库闪回, 示例: flashback database to time = to_date('20-12-08 10:00:00',‘ yy-mm-dd hh24:mi:ss'); flashback database to scn=2728665; flashback database to sequence=2123 thread=1; • 也可以在database control执行数据库闪回, 与 前两种方式不同的是, 它只能指定闪回到某分 钟, RMAN可以指定秒, SQL*PLUS可以闪回到某 个时间戳.
  • 11.
    Flashback Drop - Overview • 从数据库版本10g开始, 在执行DROP命令删除表时实际上执行的是alter table ... rename to命令修改了表的名称, 可以通过user_recyclebin和 dba_recyclebin视图查询这些被删除的对象.闪回删除正是利用了这一特 性, 它能够将表恢复到删除之前的状态, 这包括表的数据/索引/触发器和 权限设置/非空和主键约束, 但不包含外键约束(被物理删除). Tip: drop table时如果指定purge选项, 将无法在回收器中找到相应的记录. • 闪回删除不能确保能够成功执行, 这有可能是之前表占用的空间被覆盖, 或者创建了另一张同名的表. 下面是一个执行闪回删除的示例: conn demo/demo; drop table newtab purge; select * from newtab; -- error flashbask table newtab to before drop; Tip: 如果需要闪回的表名称已经被使用那么必须使用rename to子句对表进行 重命名. Tip: SYSTEM表空间的表不支持闪回删除, 它们被删除时会立即purge掉.
  • 12.
    Flashback Drop - Recycle Bin • 回收站用于管理已经模式下被drop掉的对象, 回收站对象的空间在需要使用时可以被覆盖. 默认情况下回收站可用, 使用实例参数 RECYCLEBIN控制是否启用回收站, 该参数是一 个动态参数. 可以在session或者system级别设 置. • 查看回收站的内容 – 使用show recyclebin命令查看; – 查询dba_recyclebin或者user_recyclebin视图. 示例: select original_name, object_name, operation, type, droptime, can_undrop from user_recyclebin;
  • 13.
    Flashback Query - Overview & Basic • 自9i版本开始闪回查询被引入, 在该版本中可用于查询数据库在过去某个时间点的数据. 在后续的版 本中, 闪回查询功能被增强, 可用于查询数据行的所有版本、撤销已提交的事务、或者将表闪回到 过去的某一个时间点 . Tip: 闪回查询的所有形式均依赖于回滚数据. • Basic Flashback Query 下面是一个基础闪回查询的示例: select to_char(sysdate,'dd-mm-yy hh24:mi:ss') from dual; -- 07-03-13 23:57:57 select * from newtab; C2 --------- 07-MAR-13 delete from newtab; commit; select * from newtab; -- no data select * from newtab as of timestamp to_timestamp('07-03-13 23:57:57', 'dd-mm-yy hh24:mi:ss'); -- same data as above 有的时候需要连续执行多个闪回查询, 为了避免在每次查询都要指定闪回的时间点, 可以通过以下 调用将查询设置在某一个时间点: execute dbms_flashback.enable_at_time(to_timestamp('27-12-08 16:54:06', 'dd-mm-yy hh24:mi:ss')); 取消该设置: execute dbms_flashback.disable; Tip: 如果无法通过回滚段重建指定时间点的数据, 那么ORA-08180: “No snapshot found based on specified time”错误将会被抛出.
  • 14.
    Flashback Query - Flashback Table • 表闪回利用了回滚段, 在一个独立的事务中进行回滚操作. 如果闪回的表存在外键约束, 那么闪回操 作通常会失败. 表闪回的一个前提条件是该表要开启行迁移(row movement). 下面以dep和emp表为 例, 其中emp外键引用了dep表: -- 数据初始化 create table dep(id NUMBER primary key, name VARCHAR2(100), location VARCHAR2(200)); create table EMP(id NUMBER, name VARCHAR2(100), title VARCHAR2(100), dep_id NUMBER); alter table emp add constraint fk_emp_dep foreign key(dep_id) references dep(id); insert into dep values(50,'SUPPORT','LONDON'); insert into emp values(8000,'WATSON','ANALYST',50); commit; -- 闪回数据 delete from emp where id = 8000; delete from dep where id = 50; commit; -- 执行表闪回 flashback table emp to timestamp to_timestamp('08-03-13 10:00:00', ‘dd-mm-yy hh24:mi:ss’); -- ORA-08189提示表没有开启行迁移 --表开启行迁移 alter table emp enable row movement; alter table dep enable row movement;
  • 15.
    Flashback Query - Flashback Table 再次对emp表执行闪回, 这一次会因为外键约束的原因 失败. oracle支持同时对多个表进行闪回(外键约束在闪 回操作的末尾进行检查), 以解决上述的问题: flashback table emp, dep to timestamp to_timestamp('08-03-13 10:00:00', 'dd-mm-yy hh24:mi:ss'); • 表闪回操作还可能会因为下面的原因失败: – 违反主键约束, 某个主键在被删除之后被重用; – ORA-08180: 快照太旧; – ORA-00054: 行被锁定. 需要闪回的行被用户锁定; – ORA-01466: 表定义发生变化. 表闪回不支持闪回到之前表 的定义; – 对于SYS模式下的对象, 不支持表闪回操作. • 默认情况下进行表闪回时触发器被禁用, 可以通过如下 方式启用触发器: flashback table emp,dept to scn 6539425 enable triggers;
  • 16.
    Flashback Query - Flashback Versions • 版本查询可以用于查看数据的历史版本, 在执行该查询时以下伪列被支持: – VERSIONS_STARTSCN 行数据版本被创建时的SCN, 使用insert或者update; – VERSIONS_STARTTIME 行数据版本被创建时的时间; – VERSIONS_ENDSCN 行数据版本被更新或者删除时的SCN; – VERSIONS_ENDTIME 行数据版本被更新或者删除的时间; – VERSIONS_XID 行数据版本被创建的事务标识; – VERSION_OPERATION 行数据版本创建的操作, INSERT/UPDATE/DELETE. 查询示例: select id, name, title, dep_id, versions_xid, versions_startscn, versions_endscn, versions_operation from emp versions between scn minvalue and maxvalue where id = 8000; Tip: versions between 子句还可以指定为时间间隔, 比如: versions between timestamp (systimestamp - 1/24) and systimestamp Tip: 版本查询不支持使用在外部表/临时表/V$视图, 因此它们不会生成undo.
  • 17.
    Flashback Query - Flashback Transaction • 闪回查询和版本查询会使用特定对象的undo数据,事务闪回则需要分析特定事务的undo, 这可能涉 及到很多不同的对象. 使用事务闪回的一个前提是开启数据库supplemental logging, 使用下面的命令: ALTER DATABASE ADD SUPPLEMENTAL LOG DATA; • 与事务闪回相关的视图是flashback_transaction_query, 该视图的undo_sql列包含了进行事务闪回操 作相关的SQL语句. 查询该视图需要有select any transaction权限, 默认情况下该权限被分配给SYS账户 和DBA角色. 接着以上面的emp/dep为例, 闪回对emp/8000的update事务: – 首先使用版本查询确认事务的id(versions_xid) select id, name, title, dep_id, versions_xid from emp versions between scn minvalue and maxvalue where id = 8000; – 使用flashback_transaction_query视图可以查看相应的undo sql select operation,undo_sql from flashback_transaction_query where xid=hextoraw('08000400DD030000'); – 使用dbms_flashback包进行事务闪回, 示例: execute dbms_flashback.transaction_backout(numtxns=>1, xids=>sys.xid_array('08000400DD030000'), options=>dbms_flashback.cascade); commit; -- 提交 该存储过程的参数说明: • numtxns 需要闪回的事务数量 • xids 事务id列表 • options 附加选项, 可以有: – cascade 闪回事务时, 避免出现违反数据库约束 – noncascade 不处理数据库约束, 这可能会导致闪回失败(默认值) – nonconflict_only – noncascade_force
  • 18.
    Flashback and Undo •闪回查询完全依赖于UNDO数据, 如果某个时间点 的undo数据被覆盖那么针对该时间点的闪回查询 将会失败, “ORA-1555: 快照过旧”错误被抛出. undo数据被保存在undo表空间中, 为了保证闪回 查询在一定的时间段内能够成功执行, 需要作如 下设置: – 设置实例参数undo_retention; – 设置undo表空间的RETENTION GUARANTEE属性. 这样带来的一个问题是, 如果表空间的大小没有被设置 为一个合理的大小, 在表空间被使用完时, 会导致当前事 务的DML操作停止往下执行(hanged). 可以通v$undostat 视图计算undo表空间合理的大小.
  • 19.
    Flashback Data Archive • 前面介绍的闪回技术在时间上都有一定的限制(通常不会太长), 归档闪回则可以设置为闪回到过去的任意时间. 下 面使用示例进行演示: – 创建用于归档闪回的表空间, 该表空间用于存放支持归档闪回表的历史数据 create tablespace fda datafile 'fda1.dbf' size 10m; – 在该表空间中创建闪回归档, 指定存留时间为7Y create flashback archive fla1 tablespace fda retention 7 year; – 创建相应的用户并授予权限 grant dba to fbdauser identified by fbdauser; grant flashback archive on fla1 to fbdauser; – 登录该用户创建表并设置归档闪回 connect fbdauser/fbdauser create table t1 as select * from all_users; alter table t1 flashback archive fla1; – 查询FDA表空间, 相应的段被创建, 该段包含了被保护对象的历史数据 select segment_name,segment_type from dba_segments where tablespace_name='FDA'; – 实例归档查询 delete from t1; commit; select count(*) from t1; select count(*) from t1 as of timestamp(sysdate - 2/1440); – as SYSDBA alter table fbdauser.t1 no flashback archive; drop user fbdauser cascade; drop tablespace fda including contents and datafiles; drop flashback archive fla1;
  • 20.