Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1244800
  • 博文数量: 350
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 5668
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-23 17:53
文章分类

全部博文(350)

文章存档

2013年(350)

分类: Oracle

2013-04-24 16:34:04

如大家所知,用户提交的数据并非直接写入数据文件,这中间有一个复杂的处理过程,如下图所示:大致描述了数据写过程中的处理逻辑



数据写过程的体系结构.jpg


写缓存:
单数据库缓存的写过程看起来很简单,但是其实际过程相当复杂,大家务必要注意。最基本的在写数据库缓存之前,肯定会先涉及到读,比如你要更新一个表的数据,那么它会首先查找你要更新的数据是否已经存在于数据库缓存,如果不存在,就需要先将其从数据文件中读取出来,而这个读取又有可能触发写操作,这个写要分两步:
·第一步是判断数据库缓存中是否还有足够的剩余,如果剩余空间不足,则首先按照LRU的规则写一部分脏数据到数据文件中,腾出足够的空闲空间,然后再将要被更新的数据写进来。
·另一步是将更新前的数据写入回滚段,然后再将更新的数据写入数据库缓存。

即使是数据库缓存中的数据,也不是实时写向数据文件的,其触发条件看起来也很简单:
1、数据库缓存区的空闲空间不足
2、执行了检查点

执行检查点主要完成两项工作:
1、更新控制文件,并修改数据文件的头信息,记录检查点
2、向DBWR布置将脏缓存块写入数据文件的任务

其触发条件是比较多的:
1、重做日志文件切换
2、系统收到ALTER SYSTEM CHECKPOINT;命令
3、将表空间置为脱机(offline)/只读(read only)/备份(backup)状态
4、通过初始化参数的设置控制检查点的执行频率。比如log_checkpoint_timeout初始化参数的值可以控制脏数据在DB BUFFER中的保留时间,log_checkpoint_interval初始化参数的值 可以控制在执行检查点之前,redolog文件中操作系统块(非数据库块)的数量。

注意,将表空间置为:脱机(offline)/只读(read only)/备份(backup)状态时触发的DBWR写任务,只会写入相关表空间的脏缓存块。另外,CKPT每隔3秒写控制文件,以记录检查点在重做日志文件中的位置。

你可能会担心,我们的修改被保存在了数据库缓存中,但数据库缓存并非实时向数据文件写数据,虽然有一些触发条件,但触发条件也不是时时都会发生,这会不会造成数据的丢失呢,别担心,Oracle还有重做日志,接着向下看:

写重做日志缓存:

在一步一步学dataguard系列中我写过一段文字专门白话了关于redo的相关概念,这里就不详述了,我们需要紧记一点,只要数据还在重做日志缓存中,尚未写入重做日志文件,这些数据就仍是不安全的,因此明确触发重做日志缓存向重做日志文件写的条件就非常重要:
1、每隔3秒自动触发一次
2、提交(注意理解ddl操作)
3、重做日志缓存被写满1/3
4、Dbwr准备写脏数据块到数据文件,如果这些数据对应的重做信息尚未写入重做日志文件的话,会先等待lgwr将脏数据涉及的重做日志写入重做日志文件,然后再将其写入数据文件(保证数据一致的关键步骤)

注意,没有重做日志文件切换这个条件,需要理解日志文件切换与重做日志缓存写日志文件是两种操作。当然,二者并非完全没有关系,举例来说假如切换日志文件之后,发现要切换的日志文件当然仍然在归档(或者其数据尚未完全写入到数据文件),则此时数据库会被挂起,那么重做日志缓存向日志文件的写过程也会暂停。

综合来看,Dbwr,lgwr,ckpt三者相互关联相互依存,因此我想,搞清楚它们之间的关系,不仅有助于我们了解oracle写数据的逻辑,更有助于我们更深层次去理解oracle的体系。 
阅读(986) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~