通过名字很显然是用来进行checkpoint的动态性能表
SQL> desc x$kcccp
Name Null? Type
----------------------------------------- -------- ----------------------------
ADDR RAW(4)
INDX NUMBER
INST_ID NUMBER
CPTNO NUMBER
CPSTA NUMBER
CPFLG NUMBER
CPDRT NUMBER
CPRDB NUMBER
CPLRBA_SEQ NUMBER
CPLRBA_BNO NUMBER
CPLRBA_BOF NUMBER
CPODR_SEQ NUMBER
CPODR_BNO NUMBER
CPODR_BOF NUMBER
CPODS VARCHAR2(16)
CPODT VARCHAR2(20)
CPODT_I NUMBER
CPHBT NUMBER /*ckpt三秒心跳一次,这里是心跳信息,三秒更新一次*/
CPRLS VARCHAR2(16)
CPRLC NUMBER
CPMID NUMBER
CPSDR_SEQ NUMBER
CPSDR_BNO NUMBER
CPSDR_ADB NUMBER
其中主要的字段包括:
·CPLRBA_SEQ:最后一次增量检查点对应LRBA的第一部分--日志序列号;
·CPLRBA_BNO:最后一次增量检查点对应LRBA的第二部分--日志块数;
·CPLRBA_BOF:最后一次增量检查点对应LRBA的第三部分--日志偏移量;
·CPODR_SEQ:已写入日志文件的最后一个RBA的第一部分--日志序列号;
·CPODR_BNO:已写入日志文件的最后一个RBA的第二部分--日志块数;
·CPODR_BOF:已写入日志文件的最后一个RBA的第二部分--日志偏移量;
·CPHBT:每三秒更新一次,并写入控制文件的heartbeat部分。表示这时的SCN号。
换句话所,当进行实例恢复时,需要应用的redo entry从CPLRBA_*到CPODR_*为止。
完全检查点
SQL> select CPLRBA_SEQ as cur_seq#,
2 CPLRBA_BNO as cur_blk#,
3 CPODR_SEQ as stop_seq#,
4 CPODR_BNO as stop_blk#
5 from x$kcccp
6 where CPODR_SEQ>0;
CUR_SEQ# CUR_BLK# STOP_SEQ# STOP_BLK#
---------- ---------- ---------- ----------
37 97550 37 97778
SQL> select count(*) from v$bh where dirty='Y';
COUNT(*)
----------
63
SQL> alter system checkpoint;
系统已更改。
SQL> select count(*) from v$bh where dirty='Y';
COUNT(*)
----------
0
很明显,发出该命令以后,内存里所有脏块都被写入了数据文件,于是内存里就没有脏块了。
打开跟踪文件,可以看到:
Beginning global checkpoint up to RBA [0x25.17df2.10], SCN: 662364
Completed checkpoint up to RBA [0x25.17df2.10], SCN: 662364
SQL> select to_number('25','xx') from dual;
TO_NUMBER('25','XX')
--------------------
37
SQL> select to_number('17df2','xxxxxxxx') from dual;
TO_NUMBER('17DF2','XXXXXXXX')
-----------------------------
97778
将其与x$kcccp的查询结果比较一下,也可以看到,在完全检查点中,截至写入数据文件的脏块所对应的redo entry对应到STOP_SEQ#和STOP_BLK#所指明的redo entry为止。
记一下先,以后再来补充