日期:2014-05-17  浏览次数:20796 次

关于实例恢复,redo和undo
实例失败后,未提交的事务是要用undo来回滚的,回滚的数据来自撤销段,撤销段来自谁?
在网上查了一下,
第一种说法:撤销数据放在撤销段中,撤销段中标记这个事务将仍为激活状态,在数据库重新启动过程中,后台进程SMON会扫描undo segment header,将发现上面的执行语句还是处于激活状态,于是, 将这些未提交的活动事务标志为dead。数据库后,后台进程SMON发现dead事务,根据情况去逐步回滚。
第二种说法:利用redo中写入的undo数据进行回滚?哪一个正确?

------解决方案--------------------
二种说法都对
------解决方案--------------------
撤销段在撤销表空间中,这个表空间是在oracle创建数据库时分配好的,重启的时候oracle首先去读取重做日志(redo log),找到你对应事务的重做日志条目,这时,再根据当前系统的状态,首先会前滚,注意是前滚,例如这个事务从9点执行到10点,本打算在10点提交,可是9:50系统崩了,可能重做日志归档到了9点45之前的,但是数据缓冲区中的数据块还没有写到磁盘上,磁盘上可能才写到9点40的时候的数据块,这个时候重启数据库,首先要前滚数据,即从9:40滚到9:45.滚到9点45一看,他妈的原来这个事务没提交,唉。。那就再回滚吧,这时,oracle数据库利用刚才前滚在数据缓冲区构建的undo块(如果不够,还有undo表空间里的undo块也调进来),把数据恢复到这是事务开始的时候,就是9点的时候。
至于你说的原理,我个人觉得都对,我上面一段话就是你说的第二种说法,第一种说法是跟深层的解释,我在上文中说了一句“如果不够,还有undo表空间里的undo块也调进来”那具体怎么调进来呢?就是你说的,将那些undo块对应的事务标记为dead,然后再去回滚这个事务。。。