Buffer cache的左边是buffer右边是链,用来记录buffer。
链的类型有LRU、LRUW。LRU是将干净可用的块串起来,将来从buffer cache找可用块的时候就从LRU链中找。LRUW是将脏块链起来,将来DBWR将脏块写入磁盘时就访问LRUW链。
把块链起来的目的就是为了组织和管理buffer块。
Buffer cache中还有一种叫做检查点队列链(checkpoint chint)。检查点队列链和LRUW一样也是挂的脏块。
oracle按照被访问的频率从低到高把脏块挂在LRUW上。
Oracle按照第一次脏的时间依次把脏块挂到检查点队列链上。
RBA:redo block address。Redo日志块的地址。对buffer进行修改会产生日志,日志有自己的地址,这个地址就是RBA。当buffer脏了以后,就在buffer里记下RBA,将来buffer需要恢复时就知道从哪里找日志。
每个buffer保存了有两个地址:LRBA和HRBA。LRBA是buffer第一次被脏的日志的地址。HRBA记录buffer最近一次脏的日志的地址。LRBA和HRBA中间的地址区域描述了buffer被脏的过程。
由此可见检查点队列上的脏buffer是按照其LRBA地址链接起来的。
Oracle数据库起起来后有一个检查点进程:
[oracle@redhat4 ~]$ ps -ef|grep ora root 9729 9665 0 08:48 pts/2 00:00:00 su - oracle oracle 9730 9729 0 08:48 pts/2 00:00:00 -bash oracle 9759 1 0 08:4 8 ? 00:00:00 ora_pmon_jiagulun oracle 9761 1 0 08:48 ? 00:00:00 ora_psp0_jiagulun oracle 9763 1 0 08:48 ? 00:00:00 ora_mman_jiagulun oracle 9765 1 0 08:48 ? 00:00:00 ora_dbw0_jiagulun oracle 9767 1 0 08:48 ? 00:00:00 ora_lgwr_jiagulun oracle 9769 1 0 08:48 ? 00:00:00 ora_ckpt_jiagulun oracle 9771 1 0 08:48 ? 00:00:00 ora_smon_jiagulun oracle 9773 1 0 08:48 ? 00:00:00 ora_reco_jiagulun oracle 9775 1 0 08:48 ? 00:00:00 ora_cjq0_jiagulun oracle 9777 1 0 08:48 ? 00:00:00 ora_mmon_jiagulun oracle 9779 1 0 08:48 ? 00:00:00 ora_mmnl_jiagulun oracle 9781 1 0 08:48 ? 00:00:00 ora_d000_jiagulun oracle 9783 1 0 08:48 ? 00:00:00 ora_s000_jiagulun oracle 9787 1 0 08:48 ? 00:00:00 ora_p000_jiagulun oracle 9789 1 0 08:48 ? 00:00:00 ora_p001_jiagulun oracle 9791 1 0 08:48 ? 00:00:00 ora_qmnc_jiagulun oracle 9825 1 1 08:48 ? 00:00:00 ora_j000_jiagulun oracle 9827 1 0 08:48 ? 00:00:00 ora_j001_jiagulun oracle 9829 1 0 08:48 ? 00:00:00 ora_j002_jiagulun oracle 9831 1 0 08:48 ? 00:00:00 ora_j003_jiagulun oracle 9833 1 0 08:48 ? 00:00:00 ora_j004_jiagulun oracle 9835 1 0 08:48 ? 00:00:00 ora_j005_jiagulun oracle 9837 1 0 08:48 ? 00:00:00 ora_j006_jiagulun oracle 9843 1 0 08:48 ? 00:00:00 ora_q000_jiagulun oracle 9845 1 0 08:48 ? 00:00:00 ora_q001_jiagulun oracle 9910 9730 0 08:49 pts/2 00:00:00 ps -ef oracle 9911 9730 0 08:49 pts/2 00:00:00 grep ora
CKPT进程有两种工作方式:
1. 完全检查点,当完全检查点发生的时候CKPT进程会触发BDWR,将所有脏块写到磁盘上;
2. 增量检查点,当增量检查点发生的时候CKPT将检查点队列的第一个脏块所对应的LRBA地址记录到控制文件上;
关闭数据库的时候oracle会发出一个完全检查点,CKPT触发DBWR,将所有脏buffer写回磁盘。数据库就干净的关闭了。数据库正常情况下只有在关闭时会发生完全检查点。
Oracle正常运行区间发生在了检查点,oracle每隔三秒钟发生一次增量检查点。此时就会把检查点队列的第一个脏块所对应的LRBA地址记录到控制文件上,如果检查点队列太长了,CKPT会通知DBWR把一部分检查点队列上的脏块写回磁盘。这样检查点队列就缩短了。
On disk rba:
LGWR进程每隔三秒钟(或者commit的时候)把redo logbuffer的日志写入redo log。