Chinaunix首页 | 论坛 | 博客
  • 博客访问: 92757
  • 博文数量: 46
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 470
  • 用 户 组: 普通用户
  • 注册时间: 2006-12-15 03:05
文章分类

全部博文(46)

文章存档

2011年(1)

2008年(45)

我的朋友

分类: Oracle

2008-03-13 21:21:48

CheckPoint Process 的深入研究

三个钟的故事:假设一个公司只有三个员工,每个员工有自己的一个钟。该公司规定,每天早晨8:30上班。有一天,非常不幸,三个员工的钟的时间各不相同,在没有其他外部因素的帮助下,他们无法确定当前的确切时间,他们无法上班,该公司无法正常的OPEN 运作。

  这个故事,帮助我们说明,在实例经过分配内存结构,加载控制文件后,然后要打开数据库的时候,需要做到控制文件,数据文件,联机重做日志保持相互状态一致性,数据库才可以打开。当数据库发生实例不正常关闭时(比如系统掉电或者Shutdown abort 进行关闭),要进行实例恢复,Oracle 数据库具有相应的机制来实现这一点。

像任何一家公司一样,不同的员工具有不同的技能专长,负责不同的工作,但是一个成功的项目,需要一个优秀的项目经理,来保持,督促项目中的成员各自工作步调相互一致。在Oracle 实例中,这样的一个重要角色,被检查点(CheckPoint) 进程(CKPT)担任。Oracle 实例在必要的时候,出现检查点,当检查点出现时,CKPT 进程一方面催促DBWR 进程及时地把该检查点时刻前DB_Buffer 中被一些Service_Process 进程修改过的数据及时写入数据文件中,写完之后,CKPT 进程更新相关的数据文件和控制文件的同步时刻点。也就是说,Oracle 实例在运行过程中,需要CKPT 进程来定期同步控制文件、数据文件和联机日志文件的时间点
  在这篇文章当中,我们将详细,深入的讨论检查点和检查点进程的作用。

注:这篇文章主要参考 上的一篇文章

大多数关系型数据库都采用在提交时并不强迫针对数据块的修改完成而是提交时保证修改记录(以重做日志的形式)写入日志文件的机制,来获得性能的优势。这句话的另外一种描述是:当用户提交事务,写数据文件是异步的,写日志文件是同步的。这就可能导致数据库实例崩溃时,内存中的DB_Buffer 中的修改过的数据,可能没有写入到数据块中。数据库在重新打开时,需要进行恢复,来恢复DB Buffer 中的数据状态,并确保已经提交的数据被写入到数据块中。检查点是这个过程中的重要机制,通过它来确定,恢复时哪些重做日志应该被扫描并应用于恢复。

检查点和检查点进程的操作的三个步骤:

A、系统触发一个检查点,系统并记录该检查点时刻的Checkpoint SCN 号,并记录该时刻修改的DB Buffer的块所参考的RBA 作为Checkpoint RBA RBA (Redo Byte Address)

B、该Checkpoint RBA 之前的日志实体所参考的DB_Buffer 中数据块的修改,要被写出到数据文件中。

C、完成2步骤后,CKPT 进程记录该检查点完成信息到控制文件。

只有上面三个步骤完成,才表示系统的检查点已经被推进,推进了日志文件,数据文件,控制文件到一个新的同步点

检查点只发生在下列情形:

  管理员使用:Alter system checkpoint 命令;

  实例被正常的关闭;

  特别注意:日志切换并不导致一个完全检查点的发生。

如何确定哪些DB_Buffer中的数据块需要被写到磁盘上,是一个蛮复杂的算法。大致思想就是:所有dirty data按照Low RBA 的升序进行链接成一个list,当CKPT被唤醒的时候,首先先从控制文件读取上次check point,把中间这段时间的dirty data 写到磁盘上。

二、触发的条件

这里需要明白两个概念完全检查点和增量检查点的区别。

增量检查点(incremental checkpoint
oracle8
以后推出了incremental checkpoint的机制,在以前的版本里每checkpoint时都会做一个full thread checkpoint,这样的话所有脏数据会被写到磁盘,巨大的i/o对系统性能带来很大影响。为了解决这个问题,oracle引入了checkpoint queue机制,每一个脏块会被移到检查点队列里面去,按照low rdb(第一次对此块修改对应的redo block address)来排列,靠近检查点队列尾端的数据块的low rba值是最小的,而且如果这些赃块被再次修改后它在检查点队列里的顺序也不会改变,这样就保证了越早修改的块越早写入磁盘。每隔3秒钟ckpt会去更新控制文件和数据文件,记录checkpoint执行的情况。

在运行的Oracle 数据中,有很多事件、条件或者参数来触发检查点。比如
        
l 当已通过正常事务处理或者立即选项关闭例程时;(shutdown immediate或者Shutdown normal;
       
l  当通过设置初始化参数LOG_CHECKPOINT_INTERVALLOG_CHECKPOINT_TIMEOUT FAST_START_IO_TARGET 强制时;
        
l 当数据库管理员手动请求时;(ALter system checkpoint

 l alter tablespace ... offline;

   l  每次日志切换时;alter system switch logfile

需要说明的是,alter system switch logfile也将触发完全检查点的发生。

alter database datafile ... offline不会触发检查点进程。

如果是单纯的offline datafile,那么将不会触发文件检查点,只有针对offline tablespace的时候才会触发文件检查点,这也是为什么online datafile需要media recoveryonline tablespace不需要。

对于表空间的offline后再online这种情况,最好做个强制的checkpoint比较好。

  上面几种情况,将触发完全检查点,促使DBWR 将检查点时刻前所有的脏数据写入数据文件。

另外,一般正常运行期间的数据库不会产生完全检查点,下面很多事件将导致增量检查点,比如:

在联机热备份数据文件前,要求该数据文件中被修改的块从DB_Buffer 写入数据文件中。所以,发出这样的命令:

l  ALTER TABLESPACE tablespace_name BIGEN BACKUP & end backup; 也将触发和该表空间的数据文件有关的局部检查点另外,

l  ALTER TABLESPACE tablespace_name READ ONLY;

l  ALTER TABLESPACE tablespace_name OFFLINE NORMAL;

等命令都会触发增量检查点。

三、检查点位置的影响因素

相比传统检查点(也就是指那些有明确含义的检查点) 增量检查点可以平缓的、持续的推进日志文件和数据文件的同步点。理解这一点是学习Checlpoint 有关原理的关键点。。很多朋友(包括我自己),总是将增量检查点和那些有明确含义的检查点做对比联系起来,竭力去探求,什么时候该出现增量检查点?很难得到确定的答案,是大家学习的难点。实际上,对于增量检查点,主要讨论的并不是什么时候出现增量检查点,而是:如何控制增量检查点推进的速率?检查点本质上是为了推进写日志和写数据.

文件的异步机制的同步,我们感兴趣的内容终究要归结到:系统崩溃时,异步的距离将需要系统多少时间来进行恢复?事实上,Oracle 正是这样设计的,数据库提供了一些参数设置(以oracle 9.2 为例)

AFAST_START_MTTR_TARGET 参数来控制增量检查点的推进速率

我们都希望当实例崩溃后,恢复需要读取的日志流尽可能的短,恢复需要的时间尽可能的短。这样,我们会将FAST_START_MTTR_TARGET 设置值更小, 增量检查点会出现的更加密集频繁。但设置值太小,将显剧增加DBWR 写数据文件的工作量,写数据文件的I/O 的增加将降低系统的性能,降低写日志文件和写数据文件的异步机制所带来的性能效益。

难以说明设置FAST_START_MTTR_TARGET 为多少是合适的设置,这和我们各自的数据库应用业务有关。Oracle 提供了一个视图V$MTTR_TARGET_ADVICE 作为我们设置参考,从该视图中,Oracle 会给出一些估计,当您设置不同的FAST_START_MTTR_TARGET 的值时,对应的物理写数据文件的数量的估计值。我们可以选择一个合适的值,可以降低恢复时间,但是不让DBWR 的工作量增加太大。

 

 

阅读(803) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~