REDO、UNDO、COMMIT、ROLLBACK概念_MySQL, Oracle及数据库讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  MySQL, Oracle及数据库讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 2360 | 回复: 0   主题: REDO、UNDO、COMMIT、ROLLBACK概念        下一篇 
jiacyi
注册用户
等级:上尉
经验:752
发帖:24
精华:0
注册:2015-5-28
状态:离线
发送短消息息给jiacyi 加好友    发送短消息息给jiacyi 发消息
发表于: IP:您无权察看 2015-5-28 14:53:36 | [全部帖] [楼主帖] 楼主

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语句,但是oracledbwr进程已经将没有提交的数据写到数据文件中去了。

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

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

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

undo


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

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

redo


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

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

commit 的开销

存在两个因素:

A. 显然会增加与数据库的往返通信。如果每个记录都提交,生成的往返通信量就会大得多。

B. 每次提交时,必须等待redo写至磁盘。这会导致等待。在这种情况下,等待成为日志文件同步log file sysnc

提交事务(COMMIT)

完成的工作:


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


提交事务(COMMIT)

完成的工作:


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


注意

oracle工作期间,LGWR并非缓存着你所做的所有工作;实际上,随着你的工作的进行,LGWR会在后台曾量式地刷新输出重做日志缓冲区的内容到在线重做日志文件中,这样做是为了避免COMMIT等待很长时间来一次性刷新输出所有的redo。直到commit执行,LGWR才将所有余下的缓存重做日志条目写至磁盘,并把SCN记录到在线重做日志文件中。这一部就是真正的COMMIT,此时事务条目会从V$TRANSACTION中删除,这说明我们已经提交。

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) 
系统就回到了原先的状态,没有这条记录了。




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论