暂无图片
暂无图片
4
暂无图片
暂无图片
暂无图片

Flashback - 数据库中的月光宝盒

甲骨文云技术 2023-03-11
1383

一部优秀的老电影中有这样一个经典的桥段,剧中角色打开月光宝盒大喊一声“波若波罗密”,便可触发时光倒流帮他回到事情发生之前以挽回悲剧结局,抑或直接回到500年前寻找他的前世姻缘。那么Oracle数据库中是否有类似的“宝物”,能帮我们嗖的一声回到“500年前”呢?让我们一起来探寻Oracle的月光宝盒--数据库闪回技术。

Oracle数据库的闪回技术是若干闪回特性的组合,提供了多种闪回手段,好像数据库中的时间穿梭机器,可以查看过去时间点时刻的数据状态,或者是将数据状态恢复到某个过去的时间点。
借助Oracle数据库闪回技术这台时光穿梭机,可以帮助我们实现以下功能:
- 查看数据的过去状态
- 查询数据的历史变化过程
- 恢复表或者表中的部分数据行到某一指定的过去时刻
- 协助用户进行错误分析和恢复
- 数据库整体闪回到某一指定的过去时刻

 闪回技术的历史演进

Oracle数据库在9i首次引入闪回概念,提供了闪回查询功能。
Oracle 10g版本:优化了闪回的效率,同时简化了闪回的使用方法;引入了更多的扩充闪回技术,包括:闪回数据库(Flashback Database)、闪回表(Flashback Table)、闪回删除(Flashback Drop)、闪回版本查询(Flashback Versions Query)和闪回事务查询(Flashback Transaction Query)。从这个版本开始,闪回功能已经十分完善。
Oracle 11g版本:引入了一种使用闪回数据存档管理和查询长期历史数据的创新方法,即Total Recall。(Total Recall最初是作为数据库的选件,12c以后包含在企业版中。中间改名为Flashback Data Archive,目前最新的名字为Oracle Flashback Time Travel此版本还提供了一种简单的一步式事务撤销操作,具有新的闪回事务功能。
Oracle 12c版本:Flashback Data Archive(即之前的Total Recall)功能的增强;12.2开始支持单个PDB的闪回。
Oracle 19c版本:DG备库随主库闪回而自动闪回;闪回日志在FRA空间自动清理机制的引入。
Oracle闪回技术主要由3类底层技术支撑,分别是基于undo的闪回,基于回收站的闪回和基于闪回日志的闪回,下面我们将分别介绍。
 基于undo的闪回

undo记录了每次数据变化中被覆盖的值,我们可以说它记录了数据变化时的前镜像值,例如一个事务将某数据从1改成了2,那么最终数据块记录的值应该是2,但是undo会记录下来更改前的值即1。undo数据是一个循环覆盖的结构,如下图:

基于undo的闪回我们主要介绍三种:闪回查询、闪回版本查询和闪回表。

闪回查询

闪回查询可以帮助我们查询一张表在过去某时间的数据状态。具体使用方法也很简单,主要就是在普通的select查询语句中多写一个“AS OF TIMESTAMP ”子句,以返回指定时间戳时的数据状态。

在我们日常使用时,主要有以下3种常用的方式:

    -- 1.闪回到某精确时间点:
    SELECT * FROM <table_name> AS OF TIMESTAMP 
    TO_TIMESTAMP('2020-12-21 08:45:00','yyyy-mm-dd hh24:mi:ss');


    -- 2.闪回到相对时间点之前(例如:1分钟前)
    SELECT * FORM <table_name AS OF TIMESTAMP SYSDATE - 1/24/60;


    -- 3.闪回到指定SCN
    SELECT * FROM <table_name> AS OF SCN 5572156;  


    闪回版本查询


    使用VERSIONS子句查询某一段时间对应行的所有版本,返回结果是行的改变历史,且只返回已提交的行(包括删除和重新插入的行版本)。

      SELECT
      versions_startscn,
      versions_starttime,
      versions_endscn,
      versions_endtime,
      versions_xid,
      versions_operation,
      last_name,
      salary
      FROM
      employees
      VERSIONS BETWEEN TIMESTAMP
      TO_TIMESTAMP('2023-02-28 14:00:00', 'YYYY-MM-DD HH24:MI:SS')
      AND
      TO_TIMESTAMP('2022-12-18 17:00:00', 'YYYY-MM-DD HH24:MI:SS')
      WHERE
          first_name = 'Steven';
      闪回版本查询还可以返回多个标识列,帮助我们分析数据的历史变化,具体如下:
      标识列含义
      VERSIONS_STARTSCN数据版本被创建时的SCN
      VERSIONS_STARTTIME数据版本被创建时的时间戳
      VERSIONS_ENDSCN数据版本消逝时的SCN
      VERSIONS_ENDTIME数据版本消逝时的时间戳
      VERSIONS_XID数据版本被创建时的事务号
      VERSIONS_OPERATION数据版本创建时的事务类型


      闪回表

      闪回表技术可以将表恢复到过去的指定时间点,使用过程主要分为以下步骤和方式:

        -- 1.开启行移动:
        ALTER TABLE <table_name> ENABLE ROW MOVEMENT;


        -- 2-1. 将表闪回到指定时间点
        FLASHBACK TABLE <table_name> TO TIMESTAMP TO_TIMESTAMP('2020-12-12 13:30:00','YYYY-MM-DD HH24:MI:SS');


        -- 2-2. 或将表闪回到 n分钟(小时)之前
        FLASHBACK TABLE <table_name> TO TIMESTAMP sysdate – N/24/60;


        -- 2-3. 将表闪回到指定的SCN
        FLASHBACK TABLE <table_name>TO SCN 5572156;


        Flashback Data Archive(FDA)

        undo数据具有时效性,旧的undo数据会被新的事务产生的undo覆盖。所以,Oracle依赖于undo的闪回技术也会受到该时效性的影响,无法闪回到很久前的数据。

        为了能够闪回到更久远的过去时刻,Oracle引入了FDA特性,即闪回数据归档,该特性最初在11g版本引入并被命名为Total Recall。它记录了数据库事务变化的历史值,将其固化在表空间中的闪回归档对象中保存,使开启了该功能的表可以不受undo覆盖限制,闪回到更远的历史时刻。

        开启FDA示例:


        基于回收站的闪回

        Oracle数据库回收站是一个虚拟容器,所有丢弃的对象都驻留在其中。如果开启了回收站后,删除数据对象并不会立即释放该对象占用的空间,只有在满足一些条件的时候才会实际释放该对象占用的空间。例如表 EMP 是在 USERS 表空间中创建的,则删除的表 EMP 将保留在 USERS 表空间中。删除的表和任何关联对象(如索引、约束、嵌套表和其他依赖对象)都不会移动,它们只是用前缀 BIN$$ 重新命名该对象。可以通过数据字典视图:USER_RECYCLEBIN 和 DBA_RECYCLEBIN快速查看回收站中的对象。

        Oracle的FLASHBACK DROP,可以逆转drop table操作,在数据没有purge的情况下将数据从回收站中恢复回来。

          -- 闪回被drop的表
          FLASHBACK TABLE <table_name> TO BEFORE DROP;



           基于闪回日志的数据库闪回

          使用 Oracle 的闪回日志,将整个数据库恢复到特定时间点,可以闪回整个数据库或者单个PDB。闪回数据库需要依赖闪回日志,需要开启flashback database设置。

          数据库闪回必须满足以下的前提条件:

          a. 执行用户需具备系统权限SYSDBA, SYSBACKUP, 或 SYSDG
          b. 数据库需要具备快速恢复区(FRA)的设置
          c. 数据库必须开启归档模式
          d. 须以clean的方式关闭数据库
          e. 数据库需打开闪回功能(flashback on)

          然后需要以干净的方式停止数据库,并启动到mount状态:

            SQL> shutdown immediate
            SQL> startup mount

            通过以下命令可闪回到某指定的点(SCN,时间戳,日志序列号等):

              FLASHBACK DATABASE TO TIMESTAMP TO_TIMESTAMP('2020-12-12 13:30:00','YYYY-MM-DD HH24:MI:SS');


              FLASHBACK DATABASE TO TIMESTAMP(sysdate - 2/24);


              FLASHBACK DATABASE TO SCN 9527;

               闪回特性总结及适用场景

              最后,我们以表格方式整理对比Oracle数据库的各项闪回技术,以及分别适合的应用场景。

               闪回常见问题

              问题1.如果表发生过truncate table,是否还可以进行闪回,可以用何种闪回?
              回答:如果表被truncate了,就无法执行表闪回了(会报错:表结构发送变化),只能通过数据库整体闪回。
              问题2:启用了Flashback Database后,是否会影响Undo的Retention,对Flashback Query/Table/Transaction是否有影响?
              回答:不会影响,开启flashback database只对数据库整体闪回有效,数据库闪回依赖闪回日志,对闪回查询/表/事务没有影响。
              问题3:除了基于undo的flashback query,有没有基于archivelog的历史数据查询方法。
              回答:对于归档日志的分析,可以通过logminer分析查询archivelog中的历史数据变化,与闪回是不同的两个机制。
              问题4:闪回数据库,和RMAN的区别和联系?
              回答:闪回数据库更倾向于数据库的逻辑修复,而RMAN更倾向于数据库或数据文件的保护,从效率来说,闪回的效率更高,能够更快速的完成数据的恢复。另可参考以下文章了解更多的RMAN与闪回的区别:https://blogs.oracle.com/maa/post/why-is-flashback-often-better-than-backups
              问题5:RAC 架构和DG模式下的数据库闪回,与普通的闪回有何不同?
              回答:RAC架构下的数据库闪回和单实例的区别不大,需要将RAC的实例都停掉然后open mount其中一个实例,执行闪回操作,最后open resetlog之后,再将该实例关闭,然后整体启动RAC数据库的所有实例。
              DG模式,如果是19c版本,备库可以随着主库一起自动闪回。
              问题6:闪回查询(flashback query)最久能回看多长时间?由哪个参数控制呢?
              回答:普通的闪回查询是基于undo的,这个无法100%确保能够闪回到哪个时间点。undo_retention参数指定undo的保留策略,正常情况下是可以保障闪回到这个点的,但是如果新的transaction得不到undo的情况下也会突破这个参数限制,回收未过期的undo,在这种情况下,无法保障undo_retention。另外如果开启了FDA(Total Recall)则不受Undo回收机制限制,可以根据FDA策略闪回到更久远的历史查询。
              问题7:flashback table后索引是否需要重建或rebuild?
              回答:index会随着表一同闪回,不需要重建
              问题8:如果有pk/fk ,flash 表会出错吗?
              回答:如果闪回数据会产生constraint violation,即违反了约束策略,则会报错。
              问题9:闪回后行移动是否需要关闭?
              回答:rowmovement在闪回后可以选择disable
              问题10:recyclebin是否有容量的限制 或者保留期限?
              回答:没有明确的参数指定保留期或空间限制,占用的空间仍然在原表空间,表空间需要扩张或者无可用空间时会回收。另外,可以使用purge强制立即回收。
              问题11:开启闪回后,会产生大量的日志,如何预估日志产生量
              回答:可以通过监控视图V$FLASHBACK_DATABASE_LOG监视闪回日志的生成量。具体可以参考mos文档:ID 761126.1。
              问题12:闪回数据库时,可以否再重新闪回到某个其它时间点(之前或之后)?
              回答:闪回数据库后如果执行过open resetlog,则无法向后再闪回。单独的表闪回可以支持双向。

              编辑:萧宇

              文章转载自甲骨文云技术,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

              评论