实例恢复(Instance Recovery)之前滚(Rolling Forward)和回滚(Rolling Back)

简介: Oracle实例恢复(Instance Recovery)之前滚(Rolling Forward)和回滚(Rolling Back)     关于oracle实例恢复的一些理解,一直都有误区,今天通过查看相关资料和...

Oracle实例恢复(Instance Recovery)之前滚(Rolling Forward)和回滚(Rolling Back)



   



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

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

 正常open的状态下一致性的数据库,SYSTEM CHECKPOINT SCN,Datafile checkpoint SCN和数据文件头Start SCN的这三个SCN是一致,并且
储存在control file中的stop scn就会恢复为NULL值,

1.1 Clean shutdown 时       
当clean shutdown 时, checkpoint会进行,并且 此时datafile的start scn和控制文件里的stop scn会相同 , 等到open 数据库 时,Oracle检查datafile header中的start scn和存于control file中的datafile的scn是否相同, 如果相同,接着检查datafile header中的start scn和control file中stop scn是否相同,如果仍然相同,数据库就会正常开启,否则就需要recovery。        等到数据库开启后,储存在control file中的stop scn就会恢复为NULL值 ,此时表示datafile是open在正常模式下了。  

1.2 非正常shutdown     
   如果不正常SHUTDOWN (shutdown abort),则mount数据库后,
会发现stop scn并不是等于其它位置的scn, 而是等于NULL, 这表示Oracle在shutdown时没有进行checkpoint, 下次开机必须进行crash recovery(实例恢复)   注意一点:       
(1)启动数据库时,如果发现STOP SCN = NULL,
表示需要进行crash recovery;       
(2)启动数据库时,如果发现有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来判断需或者不需实例恢复。





保持数据一致性和完整性,是每一款成功商业数据库软件都必须要做到的基本要求。从故障中恢复,保证ACID原则,保证事务完整性,一直是Oracle数据库核心功能组成部分。本篇主要介绍Oracle实例意外终止(断电或者强制关闭)之后,重新启动时发生的恢复过程,也可以称作“前滚和回滚”。

 

基础知识说明

 

为了更明确的说明问题,笔者首先介绍一下本文涉及到的一些重要知识。

 

数据库实例失败

 

我们经常说的数据库服务器failure是有多层含义的。Oracle数据库是一个由多进程组件共同构成的结构体系。最重要的部分包括监听器、Oracle数据库实例两个部分,当然还包括各类文件,更广义的还有硬件和操作系统OS。不同部分的Failure现象和处理方法都有所不同。本文所阐述的过程是Oracle实例失败后的自动恢复过程。

 

在实例失败的时候,往往是突然性的终止。此时Oracle数据库可能在进行一系列完成或者未完成的事务。实例失败恢复,就是要将这些状态进行还原,恢复到数据完整性的状态。

 

 

写日志(Redo Log)在先机制

 

Oracle数据库是采用“日志在先”机制的。当我们对数据库数据进行修改时,并不是立即将修改写入到文件中,而是写入到共享内存SGA空间中的Buffer Cache里。同时,将修改的日志不断的写入到SGA中另一块Log Buffer缓存中。有一个后台进程LGWn不断的将Log Buffer缓存中的日志内容写入到online redo log文件中。

 

 

写入Log Buffer缓存和LGWn写入文件的过程是异步进行的。触发LGWn工作的时点有几个:

 

ü        用户进行直接的commit操作;

ü        日志进行切换;

ü        距离上次LGWn写入操作超过三秒;

ü        Redo Buffer数据超过1/3或者超过1M大小;

ü        DBWn启动,将Buffer Cache中的脏数据写入到文件中;

 

而数据文件写入进程DBWn工作的触发点,则比较平缓和低频率。

 

ü        Buffer Cache中缺少用于写入数据的clean block的时候,DBWn会开始将一些脏块“Dirty Block”写入到文件中,清理出一些可以使用的Clean Block

ü        周期性的CheckPoint写入,当CKPT进程进行检查点打入的时候,DBWn会启动进行写入;

 

综合DBWnLGWn工作的特点,我们可以得到日志文件的几个特点:

 

首先,日志文件的写入是很频繁的。LGWn会不断将日志信息从Log Buffer中写入Online Redo Log

 

其次,在日志文件上,可以有三个类型的事务事件。

 

1、事务结束,已经被commit,之后打过checkpoint检查点。这种事务记录在Log File上,但是变化信息已经被DBWn写入进数据文件;

2、事务结束,已经被commit,之后没有打入checkpint检查点。这种情况下,Log File已经写入了日志项目,数据文件可能包括脏数据,也可能没有写入脏数据;

3、事务未结束,没有commit。这种时候,数据块Dirty Block上面是有事务槽信息,表示未结束事务,是不会将数据写入到数据文件中。但是,日志Log Buffer可能将部分未提交的DML操作项目写入到Log File中;

 

 

检查点Checkpoint

检查点Checkpoint是数据库一致性检查的一个标记。简单的说,就是在这个点上,Oracle保证各个文件(数据、控制、日志等)是一致的。检查点的作用就是在进行实例恢复的时候,告诉SMON进程,这个点之前的内容不需要进行恢复。

 

 

前滚和回滚介绍


“前滚和回滚”是Oracle数据库实例发生意外崩溃,重新启动的时候,由SMON进行的自动恢复过程。下面通过模拟实例和讲解介绍这个过程。

 

失败前场景说明

 

日志中记录过程如下:

 

1、事务A进行之后,结束commit。之后系统进行了一次checkpoint A

2、Checkpoint之后,进行事务B,结束commit

3、进行事务CC事务量较大,其中进行了一定量的Redo Log文件写入。之后系统断电;

 

 

1、系统启动过程,进入实例恢复阶段

 

当实例意外中断的时候,各类型文件,包括控制文件、数据文件和日志文件上,会存在不一致的问题。这种不一致主要体现在SCN值的差异上。

实例在启动的时候,经过三阶段(nomountmountopen)。在open之前,会进行这种不一致现象的检查,如果出现不一致,要启动SMON进程的恢复流程。

SMONOracle实例的一个后台进程,主要负责进行系统监控恢复。进行恢复的依据主要是Redo Log记录。

 

2、前滚进程

 

SMON首先找到最后SCN记录的Redo Log File。寻找最后一个打入的Checkpoint

顺序找到CheckPoint A之后,表示A之前的所有事务都是完全写入到数据文件中,不存在不一致性问题。恢复过程从Checkpoint A开始,Oracle开始依据重做日志Redo Log的系列条目,进行推进。

首先遇到了事务B信息,由于事务B已经commit,所以事务B所有相关的Redo Log条目已经全都写入到Redo Log File中。所以,按照日志继续条目推进,完全可以重演replay,并且应用apply事务B的全部过程。

这样,事务B全部实现,最终将通过DBWn完全写入到数据文件中。所以,实例失败之前提交commit的事务B,完全恢复。

进入事务C的范畴,由于一部分事务CRedo Log条目已经进入Redo Log File中,所以在进行前滚的时候,一定会replay到这部分的内容。不过,这部分内容中不可能出现commit的标记。所以,前滚的结果一定是遇到实例突然中断的那个时点。此时replay的结果是,事务C没有提交。这样结束了前滚过程,进入回滚阶段。

 

3、回滚过程

 

对事务C,要进行回滚过程,释放所有相关资源。从Undo空间中寻找到旧版本SCN的数据块信息,来进行SGABuffer Cache数据块恢复。

 

4、说说恢复过程的损耗

 

很多时候,由于我们事务规模较大,当出现实例崩溃的时候,重启所需要的时间很多。有一种经验说法是,事务有多长,前滚和回滚所消耗的时间有多长×2。而且,如果不能完成SMON恢复过程,数据库是不能算作正常的Open的。

SMON的恢复过程是Oracle强制进行的一个过程,即使恢复中发生断电或者其他中断失败事件。Oracle在下一次启动的时候,还是会继续这个过程,只有耐心等待。


通过检查一些内部视图(X$视图),可以观察到恢复进程和速度,但是丝毫不能影响到最终恢复的过程。

这个过程虽然可以保证数据一致性,但是也带来了系统不能启动,影响生产环境的问题。我们可以通过两个方式进行缓解:

首先,我们在设计开发系统时,要保证事务规模的可控性,不要让事务规模在技术层面上过大。避免一旦发生崩溃,大规模强制回滚的发生;

其次,一旦出现了这个强制回滚,要注意对生产环境的影响。可以采用备库standby进行顶替,让主库安静的慢慢恢复;





    



  

      

  

  •  

  •   


  •  

  •  



  

 

De.ion of Figure 13-5 follows


   

 


   

    

 

De.ion of Figure 13-6 follows


  

  •  

  •  


  

 

>

                                          

                                                        

                                                        

                                                        

                                                        

                                                        

                                                        

                                                

                                                

                                                      

                                                      

                                                        

                                                        

                                                        

                                                        

                                                        

                                                        

                                                      

                                                      

                                                 

                                                      

                                                 

                                                 

                                                      

                                                      

                                                      

>

>

 

 

 

 

 

 

 







    

img_e3029f287d989cd04bd75432ecc1c172.png
DBA笔试面试讲解
欢迎与我联系

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
4月前
|
关系型数据库 数据库
Harbor断电重启postgres报错 could not locate a valid checkpoint record
Harbor断电重启postgres报错 could not locate a valid checkpoint record
199 0
【异常】svn: E200009: Commit failed (details follow)/both sides of the move must be committed together的解决办法
svn: E200009: Commit failed (details follow)/both sides of the move must be committed together的解决办法
475 0
|
SQL Oracle 关系型数据库