内存数据块写入数据文件,在写的过程中,一旦发生实例崩溃,就需要实例恢复
要有一套完整的机制能够保证用户已经提交的数据不会丢失
而且这套机制要充分考虑IO效率问题
Oracle引入了CKPT和LGWR这两个后台进程,这两个进程与DBWn进程互相合作,
提供了既安全又高效的写脏数据块的解决方案。

用户进程每次修改内存数据块时,都会在日志缓冲区(log buffer)中构造一个相应的重做条目(redo entry),
该重做条目描述了被修改的数据块在修改之前和修改之后的值。
而LGWR进程则负责将这些重做条目写入联机日志文件。
只要重做条目进入了联机日志文件,那么数据的安全就有保障了,否则这些数据都是有安全隐患的。

 

用户提交(commit)时,Oracle是不一定会把提交的数据块写入数据文件的。
那么实例崩溃时,必然会有一些已经提交但是还没有被写入数据文件的内存数据块随内存断电消失,就需要恢复
当实例再次启动时,Oracle需要利用日志文件中记录的重做条目在buffer cache中重新构造出被丢失的数据块,
从而完成先前滚和后回滚的工作,并将丢失的数据块找回来。


在恢复的过程中必然要有恢复的起点和终点

终点很好解决.最后commit的点
起点就比较难定位 起点就意味着这之前的数据都已经从内存同步到数据文件中了.其后的就是脏数据
 起点定位时间太长,说明下次恢复周期长,周期长安全隐患大
 起点定位时间太短,说明DBWN进程频繁的写,IO就比较紧张
为了确定最佳起点位置oracle采用CKPT进程实现完全检查点和增量检查点来分别定位起点
可以说检查点的引入就是为了加速实例恢复.

oracle为检查点进程提供了检查点队列,该队列串起来的都是脏数据块所对应的buffer header.
概括下来其实就是DBWn负责写检查点队列上的脏数据块,
而CKPT负责记录当前检查点队列的第一个数据块所对应的的重做条目在日志文件中的地址,将其写到控制文件中去.

增量检查点引入的原因 就是加速实例恢复和减缓DBWR一次突发大任务量

完全:所有内存中的脏块+所有的数据文件+所有的控制文件
  增量:只更新控制文件中的LRBA的位置
  延迟:日志切换,不立即做那个版本,日志切换就会触发完全检查点
同时,完全检查点会更新控制文件和数据文件头.
检查点队列随着时间增长,由CKPT通知DBWR去写,每次告诉DBWR写到队列的什么地方 与主机的IO效率有关
 也就是CKPT是监工,向DBWR提交任务,DBWR即为劳力
 CKPT除了通知DBWR去写以外,还会每三秒检查一次DBWR的工作进度,并将DBWR当前进度记录到控制文件
 如果3秒触发,CKPT只做一件事,就是找出检查点队列里第一个buffer header
 并将该buffer header中所记录的LRBA(Low Redo Block Address Low表示第一次修改时对应的RBA)
 将LRBA记录到控制文件中去。
 如上事件即称为增量检查点.目的是实例如果是日志切换,也换做检查点,这个检查点并不立即去做,当日志循环切一圈时,第一次切换的日志要被覆盖前必须写盘时会去做
 除了记录LRBA到控制文件,还需要记录到每个数据文件头。



 

到了8I版本后,完全检查点只有在两种情况下才触发:
 1. alter system checkpoint;
 2.除了shutdown abort以外的正常关库命令

 手动执行alter system checkpoint完全检查点会将所有脏块写盘(包括未提交的)
 关闭数据库时会将为完成的事物回滚.再将脏块写盘

 
概括下来其实就是DBWn负责写检查点队列上的脏数据块,
而CKPT负责记录当前检查点队列的第一个数据块所对应的的重做条目在日志文件中的地址,将其写到控制文件中去.

崩溃后,定位恢复的redo起点. 使起点和终点尽可能短,恢复时间就少.