【云原生进阶之数据库技术】第二章-Oracle-原理-4.6.3.8-闪回事务技术

时间:2024-10-04 07:06:13

1 闪回事务(Flashback Transaction)

        到目前为止,介绍的所有功能均不会直接将数据恢复为“以前”的样子。闪回查询只是查看,闪回数据归档只是延伸了闪回查询的时间窗口,闪回事务查询虽然提供了撤销SQL,但是否执行及如何执行还需要管理员进一步手动操作。

        若是管理员决定撤销某个或某些事务,Oracle提供一个专门用来撤销事务的工具——闪回事务。

1.1 闪回事务概念概述

        闪回事务又名撤销事务(Backout Transaction),能够撤销一个或多个事务的修改,其功能由一个名为DBMS_FLASHBACK.TRANSACTION_BACKOUT的存储过程实现。该存储过程的工作原理是自动分析重做日志,挖掘出变更前的值用以构建撤销SQL(Undo SQL),然后执行撤销SQL最后达到撤销事务的目的。

        为使用该功能,至少需要事先启用主键补充日志。另外,为了能够跟踪外键依赖还需要启用外键补充日志。

        闪回事务是利用存储过程dbms_flashback.transaction_backout 来回滚某个事务。其回退的原理是利用undo日志逻辑撤销事务的影响,并根据选项决定是否一并撤销依赖其的子事务。

1.2 事务的依赖性

        在继续讨论此功能前,首先应了解一个概念:事务的依赖性。比如,两个事务TX1和TX2,符合以下3个条件的任意一个就可以认为TX2依赖TX1:

  • WAW依赖(Write After Write):在TX1修改了表的某行之后,TX2又修改了同一行。
  • 主键依赖:在一张拥有主键的表中TX1首先删除了一行,之后TX2又插入了具有相同主键值的另一行。
  • 外建依赖:由于TX1的修改(insert或update)而产生了新的可被外键参考的字段值,之后TX2修改(insert或update)外键字段时利用了TX1所产生的字段值。

        了解事务依赖性有助于解决在撤销事务时遇到的矛盾,以主键依赖为例,试想若直接将事务TX1撤销并且不理会事务TX2,岂不是会出现主键值重复的行?

1.3 闪回事务的限制

        TRANSACTION_BACKOUT存储过程的OPTIONS参数就是为了解决事务依赖性问题而存在的。假设被撤销的事务是TX1,若其具有依赖事务,则称为TX2。OPTIONS参数有4种可选值:

  1. NOCASCADE:TX1不可以被任何其他事务依赖(即TX2必须不存在),否则撤销操作报错。
  2. CASCADE:将TX1和TX2一起撤销。
  3. NOCASCADE_FORCE:忽略TX2,只将TX1撤销,如果没有约束上的冲突操作将成功,否则约束报错导致撤销失败。
  4. NONCONFILICT_ONLY:在不影响TX2的前提下,撤销TX1的修改。会首先过滤一下TX1的撤销SQL,确保它们不会作用在TX2修改的行上。

        闪回事务有一定的限制条件:

  1. 表的结构不能改变(事务提交后未对表进行DDL变更)。
  2. 事务中不能使用大字段类型(bfile/blob/clob/nclob)。
  3. 无法使用LogMiner不支持的特性。

        因为事务之前可能存在依赖性,dbms_flashback.transaction_backout可以通过选项来控制是否一同闪回其依赖事务。

        dbms_flashback.transaction_backout语法:

  1. DBMS_FLASHBACK.TRANSACTION_BACKOUT
  2. numtxns NUMBER,
  3. xids XID_ARRAY, -- 通过事务ID列表来闪回
  4. options NUMBER default NOCASCADE, -- 闪回选项,取值可以为cascade/nocascade/nocascade_force/nonconflict_only
  5. timeHint TIMESTAMP default MINTIME); -- timeHint可以替换为scnhint,提示事务开始前的时间或SCN
  6. DBMS_FLASHBACK.TRANSACTION_BACKOUT
  7. numtxns NUMBER,
  8. txnnames TXNAME_ARRAY, -- 通过事务名称列表来闪回
  9. options NUMBER default NOCASCADE, -- 闪回选项,取值可以为cascade/nocascade/nocascade_force/nonconflict_only
  10. timehint TIMESTAMP MINTIME ); -- timeHint可以替换为scnhint,提示事务开始前的时间或SCN

1.4 闪回事务示例

        employees表中employee_id为206的记录示例,salary初始值为10000,第一个事务更新为1000,第二个事务在第一个事务基础上将salary乘以2(依赖事务)。

        首先通过闪回版本查询,找到记录206在近期的所有事务ID(XID),SCN较小的update即第一个事务。

  1. SELECT xid,commit_scn,commit_timestamp,operation
  2. FROM flashback_transaction_query
  3. WHERE xid IN (
  4. SELECT versions_xid FROM VERSIONS BETWEEN TIMESTAMP
  5. TO_TIMESTAMP('2021-12-18 03:35:58', 'YYYY-MM-DD HH24:MI:SS') AND
  6. TO_TIMESTAMP('2021-12-18 03:37:58', 'YYYY-MM-DD HH24:MI:SS')
  7. where employee_id=206); -- 指定查询该条记录上的事务。

        通过找到的XID(示例中为'0A00000062050000'),先用默认的选项闪回(nocascade)。因为第二个事务在第一个事务基础上将salary值乘2(闪回的目标事务存在被依赖关系),因此无法单独闪回第一个事务,执行报错。

        将选项设置为dbms_flashback.cascade,Oracle会先闪回子事务,再闪回目标事务。可以看到salary值恢复到了初始值10000,事务1和事务2的效果全部都消失了。

        闪回事务后,系统并不会自动提交(依然会占有锁,其他会话看不到闪回结果)。 通过查询闪回后的结果,我们发现结果已经恢复到了原始状态,需要显式提交让结果持久化。

        以上即是闪回单个事务的示例,多个事务的闪回只需要将xids参数用逗号分隔,numtxns修改为要闪回的事务数量即可。

参考链接

oracle闪回技术_oracle 闪回-****博客

Flashback - 数据库中的月光宝盒 - 墨天轮

flashback table 闪回表到指定时间或SCN

Oracle数据库闪回功能的详解和相关命令_oracle闪回-****博客

oracle中闪回的定义,Oracle闪回技术-****博客

Oracle闪回详解(闪回查询,闪回数据,回退数据,闪回表,闪回数据库,闪回快照,闪回主备库(恢复关系),闪回归档,注意事项,有关闪回常用查询命令)_oracle 闪回-****博客

oracle闪回技术详解(闪回表、闪回数据)_oracle_

Oracle闪回技术(Flashback)_oracle flashback-****博客

ORACLE的闪回技术

Oracle数据闪回flashback

Oracle Flashback 技术大解密

Oracle数据库闪回技术:时间倒流的魔力_oracle闪回恢复数据-****博客

用户体验 | YashanDB&Oracle闪回功能对比及使用示例