您的位置:首页 > 数据库 > Oracle

关于oracle实例恢复的前滚和回滚的理解

2017-06-04 19:53 363 查看
关于oracle实例恢复的一些理解,一直都有误区,今天通过查看相关资料和与同学探讨,发觉了自己的错误,探讨结果如下:
实例恢复:当数据库非正常关闭的时候(断电或者shu abort等等非一致性关闭),当你从新启动数据库的时候,数据库相关进程自动进行实例恢复,无须人工干预。

什么时候需要实例恢复在shutdown normal or shutdown immediate下,也就是所谓的clean shutdown,checkpoint也会自动触发,并且把SCN纪录写回。 当发生checkpoint时,会把SCN写到四个地方: 三个地方于control file内:SYSTEM CHECKPOINT SCN
Datafile checkpoint SCN
Stop SCN:就是在实例一致性关闭的时候,更新

一个在datafile header内:Start SCN

正常open的状态下一致性的数据库,SYSTEM CHECKPOINT SCN,Datafile checkpoint SCN和数据文件头Start SCN的这三个SCN是一致,并且储存在control file中的stop scn就会恢复为NULL值。
Clean shutdown 时当clean shutdown 时,checkpoint会进行,并且此时datafile的stop scn和控制文件里的start scn会相同, 等到open数据库时,Oracle检查datafile header中的start scn和存于control file中的datafile的scn是否相同, 如果相同,接着检查start scn和stop scn是否相同,如果仍然相同,数据库就会正常开启,否则就需要recovery。 等到数据库开启后,储存在control file中的stop scn就会恢复为NULL值,此时表示datafile是open在正常模式下了。
非正常shutdown如果不正常SHUTDOWN (shutdown abort),则mount数据库后,会发现stop scn并不是等于其它位置的scn, 而是等于NULL,这表示Oracle在shutdown时没有进行checkpoint,下次开机必须进行crash recovery(实例恢复)。 注意一点:启动数据库时,如果发现STOP SCN = NULL,表示需要进行crash recovery;
启动数据库时,如果发现有datafile header的START SCN 不等于储存于CONTROLFILE的DATAFILE SCN,表示需要进行Media recovery

实例恢复的具体过程当数据库突然崩溃,而还没有来得及将buffer cache里的脏数据块刷新到数据文件里,同时在实例崩溃时正在运行着的事务被突然中断,则事务为中间状态,也就是既没有提交也没有回滚。这时数据文件里的内容不能体现实例崩溃时的状态。这样关闭的数据库是不一致的。 下次启动实例时,Oracle会由SMON进程自动进行实例恢复。实例启动时,SMON进程会去检查控制文件中所记录的、每个在线的、可读写的数据文件的END SCN号。 数据库正常运行过程中,该END SCN号始终为NULL,而当数据库正常关闭时,会进行完全检查点,并将检查点SCN号更新该字段,所以可以通过END SCN号是否为null来判断是不是需要实例恢复。 而崩溃时,Oracle还来不及更新该字段,则该字段仍然为NULL。当SMON进程发现该字段为空时,就知道实例在上次没有正常关闭,于是由SMON进程就开始进行实例恢复了。 SMON进程进行实例恢复时,会从控制文件中获得检查点位置。于是,SMON进程到联机日志文件中,找到该检查点位置,然后从该检查点位置开始往下,应用所有的重做条目,从而在buffer cache里又恢复了实例崩溃那个时间点的状态。这个过程叫做前滚,前滚完毕以后,buffer cache里既有崩溃时已经提交还没有写入数据文件的脏数据块,也还有事务被突然终止,而导致的既没有提交又没有回滚的事务所弄脏的数据块。 前滚一旦完毕,SMON进程立即打开数据库。但是,这时的数据库中还含有那些中间状态的、既没有提交又没有回滚的脏块,这种脏块是不能存在于数据库中的,因为它们并没有被提交,必须被回滚。打开数据库以后,SMON进程会在后台进行回滚。 有时,数据库打开以后,SMON进程还没来得及回滚这些中间状态的数据块时,就有用户进程发出读取这些数据块的请求。这时,服务器进程在将这些块返回给用户之前,由服务器进程负责进行回滚,回滚完毕后,将数据块的内容返回给用户。
为什么数据库的实例恢复是先前滚再回滚回滚段实际上也是以回滚表空间的形式存在的,既然是表空间,那么肯定就有对应的数据文件,同时在buffer cache 中就会存在映像块,这一点和其他表空间的数据文件相同。
当发生DML操作时,既要生成REDO(针对DML操作本身的REDO Entry)也要生成UNDO(用于回滚该DML操作,记录在UNDO表空间中),但是既然UNDO信息也是使用回滚表空间来存放的,那么该DML操作对应的UNDO信息(在BUFFER CACHE生成对应中的UNDO BLOCK)就会首先生成其对应的REDO信息(UNDO BLOCK's REDO Entry)并写入Log Buffer中。
这样做的原因是因为Buffer Cache中的有关UNDO表空间的块也可能因为数据库故障而丢失,为了保障在下一次启动时能够顺利进行回滚,首先就必须使用REDO日志来恢复UNDO段(实际上是先回复Buffer Cache中的脏数据块,然后由Checkpoint写入UNDO段中),在数据库OPEN以后再使用UNDO信息来进行回滚,达到一致性的目的。
生成完UNDO BLOCK's REDO Entry后才轮到该DML语句对应的REDO Entry,最后再修改Buffer Cache中的Block,该Block同时变为脏数据块。 实际上,简单点说REDO的作用就是记录所有的数据库更改,包括UNDO表空间在内。
总 结今天最重要的一点我知道了,所谓的前滚,是应用redo来恢复buffer cache的数据,将buffer cache恢复到crash之前状态,所以此时buffer cache 中既有崩溃时已经提交还没有写入数据文件的脏数据块,也还有事务被突然终止,而导致的既没有提交又没有回滚的事务所弄脏的数据块(也就是没有commit,但是dbwr已经将改变刷新到底层磁盘),还有一点是控制文件中还有一个 end scn,用来记录数据库正常关闭的时候的数据库文件头的scn,并且可以通过这个scn是否为null来判断需或者不需实例恢复。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  oracle 前滚 实例恢复