检查点队列

检查点队列

     Oracle实例崩溃,恢复呢?Oracle数据库提交了的数据块,只是保证了已经保存到了Redo buffer中。如果oracle数据库崩溃了,需要前滚数据库日志来重构buffer cache中的脏块,从而保证已提交的事物不会丢失。前滚哪些数据文件呢?起点和终点分别在哪里?

     ORACLE 8i之前,采取暴力的形式恢复。直接读取几乎所有的redo log日志文件,来前滚日志。这样,能达到目的,但是非常耗时,用户感知极差。而8i之后的版本,oracle引入检查点队列,完美解决了这个问题。

一、检查点队列相关概念

1、检查点队列链 

     检查点队列是将Buffer cache中的脏块,按照buffer第一次脏的顺序连接起来。这里隐藏了一个意思:检查点队列的第一个脏块,是Buffer cache中的第一个脏块,它之前脏的所有的buffer,都已经保存到dbf中了。 

2、RBA

每次PGA对buffer进行修改,都会生成日志。PGA会将这个日志的地址写到buffer中。这个地址就叫RBA。RBA就是日志地址。

3、LRBA

LRBA对应Buffer第一次被修改对应的日志地址。

4、HRBA

HRBA对应buffer最近一次被修改对应的日志地址。

5、ON DISK RBA

   ON DISK RBA是目前数据库(REDO LOG)所保存的最后一条日志的地址。

   检查点队列也就是按照LRBA地址链接起来的。  

二、Check point(检查点)

Check point进程主要用来记录检查点。

1、完全检查点

   当oracle数据库关闭时,需要调用完全检查点进程。当完全检查点发生的时候,这个进程会触发dbwrite将所有的脏块写到磁盘。

2、增量检查点

   当增量检查点发生的时候 CKPT将检查点队列的第一个块所对应的LRBA日志地址和时间点(SCN)记录到控制文件中。增量检查点每3秒发生一次。当检查点队列过长时,也会触发DBWR写入磁盘,从最早的开始写起,从而减小检查点队列。

三、ORACLE实例崩溃恢复(前滚)

当数据库崩溃时,oracle将取ON DISK RBA和增量检查点之间的REDO LOG日志来前滚,构造脏块为什么能实现呢?

1、回滚的要求:

   所有用户已经提交的还没有保存到DBF中的buffer,都需要构造出来,才能保证数据的一致性。因为数据库要求所有已经提交的,都不允许丢失。

2、实现过程

所有已经提交了的数据,都肯定已经记录到了redo log中了。而redo log中会存在以下几种数据:

(1)已经提交,DBF中的数据和redo log中的一致(崩溃时,buffer是clean的)。

(2)已经提交,DBF中的数据和redo log不一致(崩溃时,buffer是dirty的)。

(3)未提交,DBF中的数据和redo log不一致(崩溃时,buffer是dirty的)。

  以上三种buffer,第三种的,是用户没有提交的,不需要恢复。第一种是已经提交的,dbf也已经入库的,也不需要恢复。

第二种,是用户已经提交了,但是数据只在redo log中记录了,还没来得及写入dbf中,数据库就崩溃了,这种是需要恢复的。

   数据库崩溃后,重启时,会检测到异常崩溃,就会开始跑redo log日志。介绍检查点队列的时候,已经提过,检查点队列的第一个脏块,是buffer cache中第一个脏块。意思是第一个脏块之前的脏块,都已经写入到DBF中了。所以,Oracle重启,跑日志时,取检查点队列的第一个脏块对应的RBA到ON DISK RBA之间的数据,来构造已经提交但是没有保存到DBF中的脏块。

 

原文地址:https://www.cnblogs.com/ironyoda/p/6054904.html