在ORACLE实例异常中止时,如果后面成功重新启动数据库到open阶段,这时后台进程SMON会进行实例恢复。
首先了解下涉及到的相关后台进程
LGWR
将redo log buffer中的redo entries写入online redo log 中
满足以下条件之一:
1、 提交事务时comit
2、 切换日志 log switch
3、 每3s
4、 redo log buffer三分之一满或者达到1MB
DBWR
将buffer cache中的被修改过的buffer也就是脏buffer写入到磁盘数据文件中,推进检查点的主要实施进程。
满足以下条件之一:
1、 产生检查点事件时
2、 脏数据缓冲区达到阈值
3、 time out 也就是每3s
4、 表级别的truncate或者drop
5、 修改表空间状态
6、 begin backup命令
CKPT
是检查点进程,但是实际上不是主要实施者,主要实施进程是dbwr,ckpt只负责在检查点事件发生时,将对应的检查点信息包含LRBA写入到控制文件和数据文件头中。
完全检查点
①一致性的关闭数据库
②ALTER SYSTEM CHECKPOINT
③联机重做日志文件切换
④ALTER DATABASE BEGIN BACKUP
以上均会使ckpt将检查点信息写入到控制文件和数据文件头中。
增量检查点
为了避免数据库关闭或者重做日志文件切换时需要大量写入数据块而存在的检查点。
dbwr至少每3s刷脏时,ckpt会记录此时的进度也就是将ckpt queue的第一个LRBA写入到控制文件中。
那么在buffer cache中的脏buffer是如何准确无误的刷入到磁盘中的呢?(我的理解:数据块block在内存中叫buffer,在磁盘文件中叫block)
这里有一个ckpt queue-检查点队列。
在buffer cache中的buffer第一次被修改时,这个buffer的文件号和块号以及修改过程中产生的redo entries的redo block address也就是LRBA都会写入到这个ckpt queue中,换句话说,脏buffer都被按照修改顺序串联在这个队列中。dbwr在写的时候就会按照ckpt queue的顺序进行脏块的落盘,从脏到不脏的变化。
而按照修改顺序地串联在检查点队列之中,对应产生的redo也是按照顺序写入到redo log之中的,可以理解为检查点队列中的信息和redo log中的信息是有对应的顺序关系的。
梳理一下一个update语句的过程
1、server进程在buffer cache中寻找是否有匹配的数据块,如果没有,则从数据文件中缓存出来存放在buffer cache中,如果有,则直接进行修改
2、在buffer cache中进行对应buffer的update,这些被修改过的buffer此时和磁盘中的不一致,变为了脏buffer,被server进程记录其文件号和块号以及对应的redo block address到ckpt qunue中。这时是第一次被修改为脏块所以对应的是LRBA,如果此时这个数据块被反复修改,那么会继续产生其redo到redo log中(lgwr进程的作用),但是不会产生在ckpt queue中。ckpt queue只会记录其第一次被修改的信息。
3、在第二步中,所有的修改操作都包含将脏buffer链接到ckpt queue中,如果没有完成这步,修改操作不能视作完成。
4、dbwr在每3s的定期唤醒中检查ckpt queue,检查其脏块数量是否达到阈值,然后决定是否刷新到磁盘中。
5、ckpt会定时去检查dbwr的工作进度,将此时检查点队列中的第一个记录的LRBA写入到控制文件中。(增量检查点机制)
6、如果发生了完全检查点,比如alter system checkpoint或者日志切换,那么LRBA被写入的地方除了控制文件外还有一个是数据文件头。
7、ckpt queue的最后一个记录信息中的RBA则是on disk rba,也就是整个数据库运行周期中最后一个脏块的位置。
实例恢复:
如果在dbwr刷脏的时候,实例出现异常中止,重新启动到open阶段时,会进行一次实例恢复。
那么实例恢复的目的是什么?起点和终点在哪里?
对于第一个问题,实例恢复的目的我理解为就是将已提交未写入磁盘数据文件的数据前滚重现出来,将未提交已写入数据文件的数据回滚撤销。
对于第二个问题,我们要应用的目标是将所有脏块重现出来也就是回滚前滚,那么这些脏块就存在于检查点队列中,起点就是检查点队列的第一个LRBA,终点就是检查点队列的最后一个RBA也就是on disk rba。
由于ckpt queue检查点队列的记录顺序和redo log记录顺序是一致的,在实例重启时,只需要找到控制文件中记录的LRBA(这个LRBA就是增量检查点发生时记录在控制文件中的信息),根据这个地址去找到redo log中对应的位置开始进行实例恢复也就是应用redo即可直到最后一个log记录。
总结:
dbwr和lgwr以及ckpt机制保证了oracle数据一致性的问题,检查点机制协调以上三个进程定期写入数据,减少实例恢复时间以及数据库正常关闭时数据的一致性。
以上是学习oracle大致运转的一个过程,对于更复杂更细化的过程留待后续能力增进再进行研究。