linuxsir首页 LinuxSir.Org | Linux、BSD、Solaris、Unix | 开源传万世,因有我参与欢迎您!
网站首页 | 设为首页 | 加入收藏
您所在的位置:主页 > Linux数据库 >

关于 Oracle redo与undo 的认识

时间:2019-04-10  来源:未知  作者:admin666

一. 什么是redo(用于前滚数据)

redo也就是重做日志文件(redo log file),Oracle维护着两类重做日志文件:在线(online)重做日志文件和归档(archived)重做日志文件。这两类重做日志文件都用于恢复;其主要目的是,万一实例失败或介质失败,它们能够恢复数据。

二. 什么是undo(用于回滚数据)

从概念上讲,undo正好与redo相对。你对数据执行修改时,数据库会生成undo信息,这样万一你执行的事务或语句由于某种原因失败了,或者如果你用一条ROLLBACK语句请求回滚,就可以利用这些undo信息将数据放回到修改前的样子。redo用于在失败时重放事务(即恢复事务),undo则用于取消一条语句或一组语句的作用。

三. 对undo段的一个误解

通常对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会扫描所有高水平线下的数据块。

redo-- undo-- datafile
insert一条记录时, 表跟undo的信息都会放进 redo 中, 在commit 或之前, redo 的信息会放进硬盘上. 故障时, redo 便可恢复那些已经commit 了的数据.

redo- 每次操作都先记录到redo日志中,当出现实例故障(像断电),导致数据未能更新到数据文件,则数据库重启时须redo,重新把数据更新到数据文件
undo- 记录更改前的一份copy,但你系统rollback时,把这份copy重新覆盖到原来的数据

redo- 记录所有操作,用于恢复(redo records all the database transaction used for recovery)
undo- 记录所有的前印象,用于回滚(undo is used to store uncommited data infor used for rollback)

redo- 已递交的事务,实例恢复时要写到数据文件去的
undo- 未递交的事务.

redo的原因是:每次commit时,将数据的修改立即写到online redo中,但是并不一定同时将该数据的修改写到数据文件中。因为该数据已经提交,但是只存在联机日志文件中,所以在恢复时需要将数据从联机日志文件中找出来,重新应用一下,使已经更改数据在数据文件中也改过来!

undo的原因是:在oracle正常运行时,为了提高效率,假如用户还没有commit,但是空闲内存不多时,会由DBWR进程将脏块写入到数据文件中,以便腾出宝贵的内存供其它进程使用。这就是需要UNDO的原因。因为还没有发出commit语句,但是oracle的dbwr进程已经将没有提交的数据写到数据文件中去了。

undo 也是也是datafile, 可能dirty buffer 没有写回到磁盘里面去。
只有先redo apply 成功了,才能保证undo datafile 里面的东西都是正确的,然后才能rollback

做undo的目的是使系统恢复到系统崩溃前(关机前)的状态,再进行redo是保证系统的一致性.
不做undo,系统就不会知道之前的状态,redo就无从谈起

所以instance crash recovery 的时候总是先rollforward, 再rollback

undo
回退段中的数据是以 回退条目 方式存储。
回退条目=块信息(在事务中发生改动的块的编号)+在事务提交前存储在块中的数据

在每一个回退段中oracle都为其维护一张 事务表
在事务表中记录着与该回退段中所有回退条目相关的事务编号(事务SCN 回退条目)

redo
重做记录由一组 变更向量 组成。
每个变更变量中记录了事务对数据库中某个块所做的修改。
当用户提交一条commit语句时,LGWR进程会立刻将一条提交记录写入到重做日志文件中,然后再开始写入与该事务相关的重做信息。

#事务提交成功后,Oracle将为该事备生成一个系统变更码(SCN)。事务的SCN将同时记录在它的提交记录和重做记录中。

commit
提交事务前完成的工作:
在SGA区的回退缓存中生成该事务的回退条目。在回退条目中保存有该事务所修改的数据的原始版本。
在SGA区的重做日志缓存中生成该事务的重做记录。重做记录中记载了该事务对数据块所进行的修改,并且还记载了对回退段中的数据块所进行的修改。缓存中的重做记录有可能在事务提交之前就写入硬盘中。
在SGA区的数据库缓丰中记录了事务对数据库所进行的修改。这些修改也有可能在事务提交之前就写入硬盘中。

提交事务时完成的工作:
在为该事务指定的回退段中的内部事务表内记录下这个事务已经被提交,并且生成一个惟一的SCN记录在内部事务表中,用于惟一标识这个事务。
LGWR后进进程将SGA区重做日志缓存中的重做记录写入联机重做日志文件。在写入重做日志的同时还将写入该事务的SCN。
Oracle服务进程释放事务所使用的所有记录锁与表锁。
Oracle通知用户事务提交完成。
Oracle将该事务标记为已完成。

rollback
回退事务完成的工作:
Oracle通过使用回退段中的回退条目,撤销事务中所有SQL语句对数据库所做的修改。
Oracle服务进程释放事务所使用的所有锁
Oracle通知事务回退成功。
Oracle将该事务标记为已完成

举个例子:
insert into a(id) values(1);(redo)
这条记录是需要回滚的。
回滚的语句是delete from a where id = 1;(undo)

试想想看。如果没有做insert into a(id) values(1);(redo)
那么delete from a where id = 1;(undo)这句话就没有意义了。

现在看下正确的恢复:
先insert into a(id) values(1);(redo)
然后delete from a where id = 1;(undo)
系统就回到了原先的状态,没有这条记录了

更多Oracle相关信息见Oracle 专题页面 https://www.linuxidc.com/topicnews.aspx?tid=12

Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx

友情链接
  • Linux Watch命令示例
  • Oracle DataGuard 报密码文件错误排查
  • 在Ubuntu 18.04上安装Angular图文详解
  • 关于 Oracle redo与undo 的认识
  • 如何在Ubuntu 18.04,16.04,18.10中安装GNU Emacs 26.1
  • 使用Python的turtle画小猫咪
  • RAC下修改内存配置后数据库无法启动问题
  • 使用Python的turtle画炫酷图形
  • RAC环境新建库时报ORA-28000问题解决方法
  • 使用Python的turtle画小猪乔治和哆啦 A 梦
  • OGG的PURGEOLDEXTRACTS不能工作问题的解决
  • 使Python中的turtle模块画图两只小羊
  • Innodb: 自动开启打印show engine status到err日志
  • ORA-00600: 内部错误代码, 参数: [kdsgrp1] 解决案例
  • 英特尔芯片漏洞使攻击者可以完全访问受影响设备上的所有数据
  • MySQL query_cache_type的DEMAND参数介绍和使用举例
  • 黑客可以修改CT扫描结果
  • MySQL入门基础教程大全
  • 在亚马逊云服务器上找到超过5.4亿条Facebook用户记录
  • 和Pipelining说再见,cURL放弃使用管道技术
  • Python之父再度发声:我们能为中国的“996”程序员做什么?
  • Firefox也将支持不可见图片延迟加载功能
  • Unomi成为Apache软件基金会顶级项目
  • Anaconda和JetBrains联手推出'Anaconda的PyCharm'
  • Windows 10又在生产环境进行测试?微软:发错了
  • Android Q将增强未知来源应用安装的安全性
  • Ubuntu MATE推出树莓派版本
  • Apache服务器存在高危提权漏洞,请升级至最新版本2.4.39
  • 阿里开源混沌工程工具ChaosBlade
  • 如何在Chromium Microsoft Edge中使用画中画
  • NetworkManager 1.17.2开始向NetworkManager 1.18进军
  • Systemd 242 准备发布,XBOOTLDR支持
  • LinkedIn研究表明Flutter是软件工程师中发展最快的技能
  • Unreal Engine 4.22 发布,重构渲染代码及其他改进
  • IBM为GCC 9增加了新的“Arch13”处理器支持
  • Radeon Software Adrenalin 2019 Edition 19.4.1 发布,Bug修复
  • 捕鱼视频
  • 全讯网娱乐
  • 正规的彩票app
  • 大乐透基本走势图
  • 足彩论坛
  • 金牛彩票平台
  • 七星彩号码