Oracle - 2.2 - 【学习笔记】for ocp 12c、undo、redo浅析

参考:https://www.cnblogs.com/yhq1314/p/10180158.html

  • redo(重做信息)是oracle在线(或归档)重做日志文件中记录的信息,可以利用redo重放事务信息前滚
  • undo(撤销信息)是oracle在undo段中记录的信息,用于撤销或回滚事务回滚

undo(用于回滚数据)

oracle undo 解析

你对数据执行修改时,数据库会生成undo信息,以便回滚到更改前的状态
(这样万一你执行的事务或语句由于某种原因失败了,或者如果你用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据放回到修改前的样子。)

从概念上讲,undo正好与redo相对。
redo用于在失败时重放事务(即恢复事务),undo则用于取消一条语句或一组语句的作用。

关注点:

  • UNDO在数据库内部存储在一组特殊的段中,这称为UNDO段(UNDO segment),或者“回滚段”(rollback segment)。

    (新版oracle还提供了undo表空间用于存储先前存在undo段中的数据)

    需要注意,UNDO并不能将数据库物理地恢复到执行语句或事务之前,只是逻辑地恢复,所有修改都被逻辑地取消,但是数据结构以及数据库块本身在回滚后可能会改变。考虑到可能会有并发事务,必须这样。
    在这里插入图片描述

  • Undo segment 是保存在表空间上的。Undo 大小是固定的,既然是固定的也就是有限的。如果保存的记录非常多,那么它就会被占满,新记录的数据会覆盖掉最早的数据。所以用一个圆形的盘片能更加形象的表示。数据从一个位置开始写入,当写满一圈后,最新的数据就会覆盖最早写入的数据。

  • UNDO也会受到REDO的保护。换句话说,会把UNDO数据当成是表数据或索引数据一样,对UNDO的修改会生成一些REDO,这些REDO将计入日志。

# undo可以做哪些事儿?

在这里插入图片描述

  • Transaction rollback(事务反转)
    事务反转是人主动去做的,人在操作的过程中反悔了,相当于我在写文档时按个ctrl+z 。

  • Transaction recovery(事务恢复)
    事务恢复是机器自动完成的,比如在事务进行过程中简拼突然断电了,下次重启服务之后,系统自动回滚。

  • Read consistency (读一致性)
    读一致性对于多用户操作是非常重要的。如果你在多人开发中使用过版本控制工具(git\cvs\svn)的话,下面的概念你将很容易理解。

# Oracle 读一致性概念

我知道oracle允许可以由多个用户对数据库进行操作,当你执行一个查询几百万条记录的操作时,这个过程可能需要几分钟。在这个过程中其它用户对你查询的数据时行了修改。这里就要保证你查询的结果是被修改之前的。

这里明确一个概念,事务的开始,在我们执行一条(更新、修改、删除)语句时;事务的结束,必须执行提交动作(执行commit 或 rollback 命令)

在这里插入图片描述

我们从上面的流程图来理解一下oracle是如何保证读一致性的。

当我们执行一个事务的时候,oracle会分配一个SCN编号,这个编号是递增的。下一个事务的编号一定比当前事务的编号大。

上图中执行第一个事务分配的编号为10023,在这个事务执行的过程中,另一事务对SCN 编号为10008和10021的数据块进行了修改。用来替换的数据块SCN编号为10024 ,而被替换掉的数据块会被保存到undo segment上面。
当第一个事务(scn=10023)执行到被修改过的数据块时,发现10024比10023大,这个时候就会到undo segment上找比自己SCN号小的数据块进行读,于是发找到了SCN号为10008和10021两个块。这样就有效的保证了读一致性。

如果找不到就报错:ORA-01555:snapshot too old 错误

当然,会有一种特殊情况,也就是undo segment 太小,最多放100条数据,可一下子来了120条数据,那么最先写入的20条数据被最后写入的20条数据覆盖。这个时候就会报错,这也是为什么要对数据据进行调优的原因。

# 对undo段的一个误解:物理恢复 or 逻辑恢复

通常对undo有一个误解,认为undo用 于数据库 物理地恢复 到执行语句或事务之前的样子,但实际上并非如此。数据库只是 逻辑地恢复 到原来的样子,所有修改都被逻辑地取消,但是数据结构以及数据库 块本身在回滚后可能大不相同。
(比如一个插入操作,新分配了一些数据块。后来事务失败,插入操作全部回滚,新分配的一些数据块还是存在的)

无法物理恢复(的原因在于…)

在所有多用户系统中,可能会有数十、数百甚至数千个并发事务。数据库的主要功能之一就是协调对数据的并发访问。 也许我们的事务在修改一些块,而一般来讲往往会有许多其他的事务也在修改这些块。因此,不能简单地将一个块放回到我们的事务开始前的样子,这样会撤销其他人 (其他事务)的工作!

例如:
假设我们的事务执行了一个INSERT语句,这条语句导致分配一个新区段(也就是说,导致表的空间增大)。通过执行这个INSET,我们将得到一个新的块,格式化这个块以便使用,并在其中放上一些数据。此时,可能出现另外某个事务,它也向这个块中插入数据。如果要回滚我们的事务,显然不能取消对这个块的格式化和空间分配。
因此,Oracle回滚时,它实际上会做与先前逻辑上相反的工作。 对于每个INSERT,Oracle会完成一个DELETE。对于每个DELETE,Oracle会执行一个INSERT。对于每个UPDATE,Oracle则会执行一个“反UPDATE“,或者执行另一个UPDATE将修改前的行放回去。

所以有一种异常情况就很容易解释了
一个表明明只有1000行左右的数据,一条select * from table语句可能需要耗时1,2分钟。
这张表应该是经常进行新增删除操作的表

比如
我新增了1000万行数据,然后又将这些数据删除。对这个表进行全表扫描的时候,仍然会去扫描这1000万行以前所占用的那些数据块,看看里面是否包含数据。也就是oracle里面所说的高水平线(HWM),这些数据块都增加到了高水平线下面,oracle会扫描所有高水平线下的数据块。

逻辑恢复的验证

undo在数据库内部存放在一组特殊的段中,为undo段(回滚段

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

骆言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值