Oracle(通常是 RDB?)是不是对受 DML 影响的表进行快照?

Posted

技术标签:

【中文标题】Oracle(通常是 RDB?)是不是对受 DML 影响的表进行快照?【英文标题】:Does Oracle (RDB in general?) take a snapshot of the table affected by DML?Oracle(通常是 RDB?)是否对受 DML 影响的表进行快照? 【发布时间】:2015-08-10 07:48:11 【问题描述】:

目标

了解针对表处理 DML 时的机制/实现。数据库(我在 Oracle 11G R2 上工作)是否拍摄表的快照(针对每个 DML)以应用 DML?

背景

我运行 SQL 以使用源表中的新值更新包含旧值的目标表的 AID 字段。

UPDATE CASES1 t
SET t.AID=(
  SELECT DISTINCT NID
  FROM REF1
  WHERE
    oid=t.aid
)
WHERE EXISTS (
  SELECT 1
  FROM REF1
  WHERE oid=t.aid
);

我认为“OLD01”可以更新两次(OLD01 -> NEW01 -> SCREWED)。

然而,这并没有发生。

问题

对于每个 DML,数据库是否为 DML(第一次)拍摄表 X(称为 X+1)的快照,然后继续为结果 (X+1) 拍摄快照(称为 X+2)表上的下一个 DML(第 2 个),对于每个成功执行的 DML,依此类推?这是否也用作实现回滚/提交的机制?

这是在某处指定为标准的预期行为吗?如果是这样,请建议相关参考。我在 Google 上搜索过,但不确定要获得正确结果的关键词应该是什么。

提前感谢您的帮助。


更新

开始阅读 Jonathan Lewis 的 Oracle Core (ISBN 9781430239543) 并看到了图表。所以目前的理解是每次更新都会在 UNDO 表空间中创建 UNDO 记录,并从那里重建原始数据,我最初认为这是快照。

【问题讨论】:

【参考方案1】:

在 Oracle 中,如果您在同一会话中连续两次运行该更新,并使用您所显示的数据,我相信您应该得到您预期的结果。我想你一定在某个地方偏离了轨道。 (例如,如果您执行了一次更新,然后在没有提交的情况下打开了第二个会话并再次执行了相同的更新,那么您的结果将是有意义的。)

从概念上讲,我认为您的问题的答案是肯定的(特别是关于 Oracle)。 SQL 语句在语句开始执行的时间点有效地对表的快照进行操作。 Oracle 中对此的恰当术语是读一致性。但是,它的机制不涉及在进行更改之前对整个表进行快照。更多的是相反 - 更改的记录保存在撤消段中,并用于根据需要将表块恢复到适当的时间点。

为了更深入地理解这一点,您应该查看的文档位于 Oracle 概念手册中:http://docs.oracle.com/cd/E11882_01/server.112/e40540/part_txn.htm#CHDJIGBH

【讨论】:

感谢您的链接。因此,看起来 CR 克隆也适用于 Update DML(在问题中)本身的更新。据我了解,SQL 从 t (CASES1) 中选取一行,并使用 t.aid 从 REF1 中进行 SELECT。带有 t.aid 的 SELECT 部分实际上是从重构的 CR 块中检索数据,不会影响 SQL 的 UPDATE 部分。这是正确的吗? 我想创建UNDO块发生在每个SQL语句的开头。例如 SQL 1、2、3 分别创建 UNDO 1、2、3。也许 Savepoint 指的是 UNDO (N)。 对于您的第一条评论 - 基本上,是的。整个 UPDATE 语句在开始执行后将看不到所做的更改,即使是它自己的更改。这包括子查询,因为它是一个语句。 语句开始执行时不会创建撤消块。撤消数据是在语句执行时在语句修改单个数据块时生成的。撤消数据基本上是对更改之前存在的数据的记录;但仅限于实际修改的表格部分。 (这可能是整个表,但也可能更少。存储的撤消数据与对表数据所做的实际更改量成正比。)

以上是关于Oracle(通常是 RDB?)是不是对受 DML 影响的表进行快照?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle新手入门:如何提高索引创建速度?

Oracle_DML

术语:DML“修改事物”

Oracle 11g 记录DML错误数据

Oracle DDL+DML+DCL实例

调试 Oracle 批量 DML 错误 - 如何确定导致错误的值?