oracle internals3-4

三、Redo byte address (RBA)

Oracle instance redo thread 产生的最近的日志条目可以通过 RBA redo byte address )来寻址,一个 RBA 包括如下的三部分:
Ø         Log file sequence number 4 bytes
Ø         Log file block number 4 bytes;
Ø         日志开始的时候得块内 offset 2 bytes
RBA 在他们的 redo thread 内不必不同,因为用 RESETLOG 方式开打数据库的时候,所有的 redo thread 都可以设置 log file sequence number 1
RBA 在如下的应用中比较重要:
对于 Daba buffer cache 中的 dirty block ,低的 RBA 是最早改变的数据块产生日志的地址,高的 RBA 是最近变化的产生的日志的地址。
Dirty buffers are maintained on the buffer cache checkpoint queues in low RBA order. The checkpoint RBA is the point up to which DBWn has written buffers from the checkpoint queues if incremental checkpointing is enabled -- otherwise it is the RBA of last full thread checkpoint. The checkpoint RBA is copied into the checkpoint progress record of the controlfile by the checkpoint heartbeat once every 3 seconds. Instance recovery, when needed, begins from the checkpoint RBA recorded in the controlfile. The target RBA is the point up to which DBWn should seek to advance the checkpoint RBA to satisfy instance recovery objectives.
The on-disk RBA is the point up to which LGWR has flushed the redo thread to the online log files. DBWn may not write a block for which the high RBA is beyond the on-disk RBA. Otherwise transaction recovery (rollback) would not be possible, because the redo needed to undo a change is always in the same redo record as the redo for the change itself.
The term sync RBA is sometimes used to refer to the point up to which LGWR is required to sync the thread. However, this is not a full RBA -- only a redo block number is used at this point.
The low and high RBAs for dirty buffers can be seen in X$BH. (There is also a recovery RBA which is used to record the progress of partial block recovery by PMON.) The incremental checkpoint RBA, the target RBA and the on-disk RBA can all be seen in X$TARGETRBA. The incremental checkpoint RBA and the on-disk RBA can also be seen in X$KCCCP. The full thread checkpoint RBA can be seen in X$KCCRT.
buffer  cache 中的 dirty  buffer 中要注意, low  RBA 是指最近一次 clean(block 中已经不再有有用数据 ) 后发生了第一次改变时的 block 的的 redo 的位置, high  RBA 是最近一次发生改变时该 block redo 的位置 (low high 是针对同一个 block 在不同时期发生了变化,变化之间没有被 clean, 可能还没有来得及被写入磁盘就又被更新了 ) 。脏数据块在 检查点写队列里面,按照 low RBA 排列, checkpoint RBA 标志 DBWn 已经从写队列里面写到磁盘了的 buffers (表示写到了哪里)如果增量检查点是激活的(前一个检查点没有结束新的检查点又发生了),否则就是标志最近一次完整的检查点发生之后 ,checkpoint RBA 3 秒别写入控制文件一次,实例恢复的时候如果需要的话就从控制文件中的 checkpoing RBA 开始 ,target RBA 是该 checkpoint RBA 所处的没有完成的检查点的 RBA, 从这里开始就可以找到 checkpoint  RBA  
On-disk RBA 是指 LGWR 已经写到 log  file 中的位置, DBWn 不能写一个 block 到磁盘,假如 high  RBA 高于 ON-DISK RBA (因为这样的话恢复的时候有问题,这个时候 DBWn 就通知 LGWR 写日志文件,也就是写进磁盘的 block redo 一定要先写进 log  file, 这个很容易理解);否则事务恢复或者回滚将不可能,因为重做的时候需要    撤消信息,而撤消信息是和 重做信息放在一个重做记录里面的
什么是 checkpoint?
checkpoint
是一个数据库事件,它将已修改的数据从高速缓存刷新到磁盘,并更新控制文件和数据文件。

什么时候发生 checkpoint?
我们知道了 checkpoint 会刷新脏数据,但什么时候会发生 checkpoint 呢?以下几种情况会触发 checkpoint
1.
当发生日志组切换的时候
2.
当符合 LOG_CHECKPOINT_TIMEOUT LOG_CHECKPOINT_INTERVAL fast_start_io_target,fast_start_mttr_target 参数设置的时候
3.
当运行 ALTER SYSTEM SWITCH LOGFILE 的时候
4.
当运行 ALTER SYSTEM CHECKPOINT 的时候
5.
当运行 alter tablespace XXX begin backup end backup 的时候
6.
当运行 alter tablespace ,datafile offline 的时候 ;

增量检查点( incremental checkpoint
oracle8
以后推出了 incremental checkpoint 的机制,在以前的版本里每次 checkpoint 时都会做一个 full thread checkpoint, 这样的话所有脏数据会被写到磁盘,巨大的 i/o 对系统性能带来很大影响。为了解决这个问题, oracle 引入了 checkpoint queue 机制,每一个脏块会被移到检查点队列里面去,按照 low rdb (第一次对此块修改对应的 redo block address )来排列,靠近检查点队列尾端的数据块的 low rba 值是最小的,而且如果这些赃块被再次修改后它在检查点队列里的顺序也不会改变,这样就保证了越早修改的块越早写入磁盘。每隔 3 秒钟 ckpt 会去更新控制文件和数据文件,记录 checkpoint 执行的情况。
这里应该是只更新控制文件,每 3 秒不是更新数据文件
记录 checkpoint 的执行情况,这个说法,没错,但不够详细,应该说,由于增量检查点和 checkpoint  queue 的原理, ckpt 进程每次只是告诉 dbwr ,写 dirty  buffer 将要一直写到最新这个位置,仅仅是告诉 dbwr 一个 checkpoint queue   中的结束点,而 ckpt 3 秒中,在控制文件中报告一下 dbwr 最新写入的位置。 这样使得,比如数据库要做恢复的时候( instance  recovery )可以从这个最新位置开始做恢复,而不是从数据文件中的 checkpoint  scn 开始做恢复,这样将缩短恢复时间,尤其是 instance  crash 的情况下启动更快

另外要注意的是,检查点发生的时候, ckpt 去更新数据文件头和控制文件,并不是把当前检查点发生时候的 scn 更新进去,而是把上一次 dbwr 写入已经完成的检查点发生时候的   scn 更新进去 ,也就是说,更新控制文件和数据文件头 滞后于检查点的发生的,这个从恢复的原理也很容易理解,因为检查点发生的时候 dirty buffer 还没有写入,自然不能立即更新成当前的 scn 了。

四、Redo Write Triggers

四种情况下会引起 lgwr 执行写操作
1 、当 lgwr 空闲的时候,处于 rdbms ipc message 等待状态,三秒超时( dbwn 也是一样)超时后, lgwr 发现需要写日志,然后就写。
2 、当 process log buffer 中分配 block ,如果 log buffer 占用的大于或者等于 _log_io_size 参数设定值,并且 lgwr 没有 active ,那么 lgwr 被激活进行写操作。默认值为 log buffer 1/3 8i 之后为 1M ,除非显示设定 ,_log_io_size 这样的参数在 v$ksppsv 中设定为 0
3 、当一个事务 commit 的时候,产生一个 commit marker 。但这种情况下,事务不能被回滚,直到 log block 被写进 disk 当中。所以在 process 结束事务的时候返回给用户的时候必须等待 lgwr 写完所有对应的 log block ,这时候 process 处于 log file sync 状态,超时为 1 秒。这时可以设定 _wait_for_sync false ,这样可以避免 redo sync 的等待,但当 instance failure 的时候,不能保证事务的可恢复性。
recursive call 知道返回给用户的时候才需要等待 sync
sga 变量 b 用来连接 log block number 和需要同步的 redo thread 。如果在 lgwr 超时之前好几个事务 commit 的话, b 将记录需要同步的最高的 log block number commit marker 将一次性写入 disk 。这就是所谓的 group commit
4 、当 dbwn 需要写一个或者更多的 block ,他们的 redo rba 超过了 lgwr on_disk rba 的时候,会引发 lgwr 写操作。 8i 以后, dbwn 会将 blocks 放入延迟写的队列当中,然后要求 lgwr 同步最高的 rba dbwn 立即执行其他的操作。 8i 以前, dbwn 需要进入 log file sync 状态等待。

你可能感兴趣的:(oracle,log,buffer,redo,休闲)