Oracle的检查点

本帖最后由 oraunix 于 2010-11-24 18:11 编辑

1,增量检查点,
   增量检查点所涉及的主要概念,是一个队列一个进程.队列是检查点队列,进程是CKPT进程.CKPT进程有两项任务,一个是在一定的时机触发DBWR并告知DBWR的Target RBA,另一个任务是每3秒一次将DBWR的写进度更新到控制文件中.CKPT的这两个任务合在一起,叫做--增量检查点.通常所说的触发增量检查点,是指CKPT进程通知DBWR刷新脏块这个操作.
   在10g中把 log_checkpoint_to_alert设置为真,可以在告警日志中观察到增量检查点的触发.在9I中看不到增量检查点,可以看到其他检查点的触发信息.

观察增量检查点:
步骤1:
SQL> alter system set log_checkpoints_to_alert=true;

系统已更改。

步骤2:将增量检查点的切换频率定为300秒.  
SQL> alter system set log_checkpoint_timeout=300;[单位是秒]

系统已更改。

步骤3:查看告警日志中的增量检查点信息.
...
Incremental checkpoint up to RBA [0x2b9.747.0], current log tail at RBA [0x2b9.848.0]
Mon Mar 03 14:51:40 2008
Incremental checkpoint up to RBA [0x2b9.855.0], current log tail at RBA [0x2b9.876.0]
Mon Mar 03 14:56:43 2008
Incremental checkpoint up to RBA [0x2b9.877.0], current log tail at RBA [0x2b9.8f0.0]
Mon Mar 03 15:01:43 2008
Incremental checkpoint up to RBA [0x2b9.8f5.0], current log tail at RBA [0x2b9.d70.0]
Mon Mar 03 15:06:43 2008
Incremental checkpoint up to RBA [0x2b9.d74.0], current log tail at RBA [0x2b9.fd9.0]
Mon Mar 03 15:11:44 2008
...
    注:Incremental checkpoint(增量检查点的意思)/第1个RBA(增量检查点发生时当前的检查点位置)/第2个RBA(检查点发生时的当前的on disk rba);

可以看到每5分钟一次检查点.

另外可以通过v$kcccp视图观察当前的检查点位置.
SQL> select CPDRT,to_char(CPLRBA_SEQ,'xxxx')||'.'||to_char(CPLRBA_BNO,'xxxxx')||'.'||CPLRBA_BOF "Low 16",CPLRBA_SEQ||'.'||CPLRBA_BNO||'.'||CPLRBA_BOF "Low RBA",CPODR_SEQ||'.'||CPODR_BNO||'.'||CPODR_BOF "On disk RBA",CPODS,CPODT,CPHBT from x$kcccp where cphbt<>0;

     CPDRT Low 16               Low RBA         On disk RBA     CPODS            CPODT                  CPHBT
---------- -------------------- --------------- --------------- ---------------- -------------------- ----------
        26   2ba.    9d.0       698.157.0       698.307.0       2363076          03/03/2008 15:23:07   648336376
为了便于观察:Low 16 是Low RBA 的16进制.
   
   注:在x$kcccp中看到的是DBWR的写进度.当把 log_checkpoints_to_alert这个参数设置为true后,可以在告警日志中看到增量检查点的触发信息.

  2,日志切换时的检查点.
   当发生日志切换时,也会触发检查点.在数据库并不繁忙的情况下,日志切换的检查点并不急于完成.之所以在日志切换的时候触发一次检查点,是为了保证重做日志文件所对应的脏块都被写进磁盘文件.如果写脏块的速度比较慢,日志文件循环一圈后,又该覆盖此日志文件时,而此日志文件的检查点还没有完成,那么覆盖操作将等待.等待事件名:log file switch(checkpoint incomplete).如果出现该等待事件,解决方法:1,可以增加日志文件组的数量.2,观察下增量检查点的间隔时间.如果是因为增量检查点间隔时间太长,导致积攒的脏块过多.可以把增量检查点参数设置的频繁点.

  日志切换检查点除了会触发DBWR写脏块外,CKPT进程还要将切换时的SCN写进数据文件头和控制文件中的数据库信息节,还有数据文件节.另外还要将新的连机重做日志文件中第一条重做记录的RBA写进数据文件头.

日志切换检查点写进数据文件头的SCN,可以通过v$datafile_header视图查看.
日志切换检查点写进控制文件中数据库信息节的SCN,可以通过v$database查看.
日志切换检查点写进控制文件中的数据文件节中的SCN,可以通过v$datafile查看.

先把log_checkpoints_to_alert这个参数设置为真,以便可以在告警日志中看到日志切换检查点的相关信息.
alter system set log_checkpoints_to_alert=true;

实验:验证下当触发了日志切换检查点后, 数据文件头,控制文件中的日志切换检查点信息都是什么:

步骤一:查看当前数据文件头的SCN
SQL> select checkpoint_change#,checkpoint_time,checkpoint_count from v$datafile_header;

CHECKPOINT_CHANGE# CHECKPOINT_TIM CHECKPOINT_COUNT
------------------ -------------- ----------------
           2372527 03-3月 -08                  646
           2372527 03-3月 -08                  609
           2372527 03-3月 -08                  646
           ......
已选择11行。

步骤二:查看当前控制文件中的数据库信息节的日志切换检查点信息
SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#
------------------
           2372527

步骤三:查看当前控制文件中的数据文件节中的日志切换检查点信息
SQL> select checkpoint_change#,checkpoint_time,last_change#,last_time,substr(name,1,30) from v$datafile;

CHECKPOINT_CHANGE# CHECKPOINT_TIM LAST_CHANGE# LAST_TIME      SUBSTR(NAME,1,30)
------------------ -------------- ------------ -------------- -------------------------------------------
           2372527 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           2372527 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           2372527 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           ......
已选择11行。

步骤四:查看当前SCN
SQL> select dbms_flashback.get_system_change_number from dual;

GET_SYSTEM_CHANGE_NUMBER
------------------------
                 2373997

步骤五:手动触发日志切换检查点

SQL> alter system switch logfile;

系统已更改。

步骤六:查看日志切换后的数据文件头的SCN
SQL> select checkpoint_change#,checkpoint_time,checkpoint_count from v$datafile_header;

CHECKPOINT_CHANGE# CHECKPOINT_TIM CHECKPOINT_COUNT
------------------ -------------- ----------------
           2372527 03-3月 -08                  646
           2372527 03-3月 -08                  609
           2372527 03-3月 -08                  646
           ......
已选择11行。


步骤七:查看日志切换后控制文件中的数据库信息节的日志切换检查点信息
SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#
------------------
           2372527

步骤八:查看日志切换后控制文件中的数据文件节中的日志切换检查点信息
SQL> select checkpoint_change#,checkpoint_time,last_change#,last_time,substr(name,1,30) from v$datafile;

CHECKPOINT_CHANGE# CHECKPOINT_TIM LAST_CHANGE# LAST_TIME      SUBSTR(NAME,1,30)
------------------ -------------- ------------ -------------- -----------------------------------------------
           2372527 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           2372527 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           2372527 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           ......
已选择11行。

**由于普通测试机的I/O并不繁忙,看到的数据很有可能是没有发生变化的,这个时候可以查看告警日志.发现
Mon Mar 03 19:50:35 2008
Beginning log switch checkpoint up to RBA [0x2c0.2.10], SCN: 2374009
Thread 1 advanced to log sequence 704
  Current log# 9 seq# 704 mem# 0: E:\LOG9A.RDO
此时的日志切换还为完成,数据文件头的日志切换的检查点和控制文件的日志切换检查点还没来的急更新.少等一会就会完成.oracle会根据机器的繁忙程度来决定什么时候完成日志切换的检查点.通常如果机器比较繁忙,oracle趋向于更急切的完成日志切换检查点.

少等一会再次查看告警日志:
Mon Mar 03 19:50:35 2008
Beginning log switch checkpoint up to RBA [0x2c0.2.10], SCN: 2374009
Thread 1 advanced to log sequence 704
  Current log# 9 seq# 704 mem# 0: E:\LOG9A.RDO
Mon Mar 03 19:53:58 2008
Completed checkpoint up to RBA [0x2c0.2.10], SCN: 2374009
可以发现除了beginning log switch chenkpoint外,多了一个completed checkpoint.日志切换的检查点到此才真正的完成.由于我的实验环境并不繁忙,oracle拖了3分钟才去真正的完成日志切换检查点.

此时再查看日志切换后的数据文件头的SCN
SQL> select checkpoint_change#,checkpoint_time,checkpoint_count from v$datafile_header;

CHECKPOINT_CHANGE# CHECKPOINT_TIM CHECKPOINT_COUNT
------------------ -------------- ----------------
           2374009 03-3月 -08                  647
           2374009 03-3月 -08                  610
           2374009 03-3月 -08                  647
           ......
再查看日志切换后控制文件中的数据库信息节的日志切换检查点信息
SQL> select checkpoint_change# from v$database;

CHECKPOINT_CHANGE#
------------------
           2374009

再查看日志切换后控制文件中的数据文件节中的日志切换检查点信息
SQL> select checkpoint_change#,checkpoint_time,last_change#,last_time,substr(name,1,30) from v$datafile;

CHECKPOINT_CHANGE# CHECKPOINT_TIM LAST_CHANGE# LAST_TIME      SUBSTR(NAME,1,30)
------------------ -------------- ------------ -------------- ----------------------------------------------
           2374009 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           2374009 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
           2374009 03-3月 -08                                 E:\ORACLE\PRODUCT\10.2.0\ORADA
              ......

****从结果可以看出日志切换时的SCN是2373997,而视图中所显示的2374009比2373997大了12.这是因为手动查看SCN和手动切换日志这两个命令间有个时间差.(忽略不计).由此可以证明,在日志切换时,CKPT写进数据文件和控制文件中的SCN,是切换命令开始时的SCN.

  在日志切换时,被写进数据文件头的并不只有SCN信息,还有RBA信息.这个RBA是新的连机重做日志文件第一条重做记录的RBA.根据告警日志中的信息,此处是RBA [0x2c0.2.10].上面所介绍的几个视图中,没有显示RBA信息.我们可以通过转储查看到这个RBA.   
转储命令如下:
SQL> alter session set events 'immediate trace name file_hdrs level 10';

会话已更改。

转储数据文件头的结果:
DATA FILE #1:  
  (name #7) E:\ORACLE\PRODUCT\10.2.0\ORADATA\ONE10G\SYSTEM01.DBF
...
Checkpointed at scn:  0x0000.00243979 03/03/2008 19:50:35   [这些信息对应v$datafile_header]
thread:1 rba0x2c0.2.10)
...
****在转储文件中的每个数据文件相关信息中,都可以找到如上两行,这其中检查点SCN和时间戳,我们都已经在视图中看到了.
RBA信息,告警日志中显示的有,上述3个视图中并未显示出来.

转储控制文件的结果:

这是控制文件中 数据库信息节中的日志切换检查点信息:
***************************************************************************
DATABASE ENTRY
***************************************************************************
...
Database checkpoint: Thread=1 scn: 0x0000.00243979[这些信息对应v$database]
...
这是控制文件中的数据文件记录节,可以看到日志切换检查点SCN.
DATA FILE #1:  
  (name #7) E:\ORACLE\PRODUCT\10.2.0\ORADATA\ONE10G\SYSTEM01.DBF
...
Checkpoint cnt:647 scn: 0x0000.00243979 03/03/2008 19:50:35  [这些信息对应v$datafile]
...
****在控制文件中,只记录日志切换时的SCN,不记录RBA.


   3,完全检查点.
   完全检查点,将会写出所有的脏块,完全检查点发生时,将不能有新的脏块产生,直到完全检查点完成,以非shutdown abort关闭数据库时就会发生完全检查点,还有就是手动发布命令:alter system checkpoint;
   完全检查点也将会在数据文件头,控制文件中数据库信息节,数据文件节中写入当前SCN.
查看告警日志信息如下:
Mon Mar 03 15:38:11 2008
Beginning global checkpoint up to RBA [0x2ba.285.10], SCN: 2363568
Completed checkpoint up to RBA [0x2ba.285.10], SCN: 2363568
   
*****小结:日志切换所触发的检查点,1,要通知DBWR写脏块.2,要向数据文件头和控制文件中写入切换时的SCN.3,把新的连机重做日志的第一重做记录的RBA写进数据文件头.******

为什么要记录写入时的SCN和RBA呢??

   如果现在数据文件头和控制文件中的SCN是2374009,假如说现在发生了介质故障,数据库宕机,将两星期前备份的某一个数据文件还原过来覆盖当前的已损坏的数据文件.这个备份的数据文件头SCN是2370000,当启动数据库时,oracle会发现数据文件头的SCN和控制文件中的SCN 不匹配,此时会要求完成介质恢复.当 recover datafile 时,oracle会根据数据文件头所记载的RBA,到相应的日志文件中寻找重做信息,进行恢复.
标签: 暂无标签
oraunix

写了 199 篇文章,拥有财富 1026,被 339 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

P4 | 发表于 2010-11-25 17:06:18
RBA是新的连机重做日志文件第一条重做记录的RBA  跟 LRBA有什么内在区别?
回复

使用道具

P4 | 发表于 2010-11-25 17:34:29
回复 shark 的帖子

RBA 全称REDO BYTE ADDRESS.
如名字的描述,redo log中任何位置都是一个RBA。
回复

使用道具

P6 | 发表于 2010-11-25 18:22:41
RAB只是日志的地址的缩写
LRBA说的是checkpoint queue中的最旧块的RBA地址。
回复

使用道具

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈