MSSM的段头中CCNT的含义(续)
Posted: December 16, 2011 | Author: Cui Hua | Filed under: Oracle | Tags: CCNT | Leave a comment »其实这篇文章的结论并不重要,最关键的是当你碰到一个在google、baidu、MOS甚至Oracle内部的webiv上都查不到相关内容的时候,你处理的思路是什么。
经过简单的测试,我们猜测——MSSM的段头中CCNT的含义就是Change CouNT的缩写,它的含义是Oracle对MSSM中段头的free list的修改次数,一次修改通常会包括move hwm+link block+unlink block这一组动作。
我们现在来证明一下上述结论:
SQL> create table t1 as select * from dba_objects where rownum<100;
Table created
SQL> insert into t1 select * from dba_objects where rownum<1000;
999 rows inserted
SQL> commit;
Commit complete
SQL> select header_file,header_block from dba_segments where segment_name=’T1′;
HEADER_FILE HEADER_BLOCK
———– ————
1 51065
表t1之前的段头内容为:
buffer tsn: 0 rdba: 0x
scn: 0×0000.000ec812 seq: 0×04 flg: 0×00 tail: 0xc8121004
frmt: 0×02 chkval: 0×0000 type: 0×10=DATA SEGMENT HEADER – UNLIMITED
Extent Control Header
—————————————————————–
Extent Header:: spare1: 0 spare2: 0 #extents: 10 #blocks: 79
last map 0×00000000 #maps: 0 offset: 4128
Highwater:: 0x
#blocks in seg. hdr’s freelists: 3
#blocks below: 76
mapblk 0×00000000 offset: 9
Unlocked
Map Header:: next 0×00000000 #extents: 10 obj#: 30547 flag: 0×40000000
Extent Map
—————————————————————–
0x
0x
0x
0x
0x
0x
0x
0x
0x
0x
nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 21
SEG LST:: flg: USED lhd: 0x
当我对t1执行insert大量数据的操作时,Oracle必然要去修改t1段头中的freelist:
SQL> insert into t1 select * from t1 where rownum<1000;
999 rows inserted
SQL> commit;
Commit complete
执行完上述插入操作后,t1的段头中内容如下所示,从结果里我们可以看到ccnt从21变成了25:
Start dump data blocks tsn: 0 file#: 1 minblk 51065 maxblk 51065
buffer tsn: 0 rdba: 0x
scn: 0×0000.000ed214 seq: 0×02 flg: 0×00 tail: 0xd2141002
frmt: 0×02 chkval: 0×0000 type: 0×10=DATA SEGMENT HEADER – UNLIMITED
Extent Control Header
—————————————————————–
Extent Header:: spare1: 0 spare2: 0 #extents: 12 #blocks: 95
last map 0×00000000 #maps: 0 offset: 4128
Highwater:: 0x
#blocks in seg. hdr’s freelists: 5
#blocks below: 92
mapblk 0×00000000 offset: 11
Unlocked
Map Header:: next 0×00000000 #extents: 12 obj#: 30547 flag: 0×40000000
Extent Map
—————————————————————–
0x
0x
0x
0x
0x
0x
0x
0x
0x
0x
0x
0x
nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 25
SEG LST:: flg: USED lhd: 0x
现在的关键问题是,这个ccnt的修改之后的值25是如何来的?只有在我们清楚了这个25的来历,我们才算真正的对上述问题有了一个初步的了解。
这时候我们的思路就是dump一下redo,然后看看redo的内容我们就什么都清楚了,dump之后的redo中清晰的显示出了ccnt的值的变化过程:
过程1:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: LUPD_UNLBLK (unlink block)
Slot no: 0, Count: 1
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000015 Head: 0x
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LCLR (lock clear)
Next dba: 0×00000000 itli: 0
过程2:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: LUPD_UNLBLK (unlink block)
Slot no: 0, Count: 1
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000015 Head: 0x
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LCLR (lock clear)
Next dba: 0×00000000 itli: 0
过程3:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: LUPD_UNLBLK (unlink block)
Slot no: 0, Count: 1
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000015 Head: 0×00000000 Tail: 0×00000000
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LCLR (lock clear)
Next dba: 0×00000000 itli: 0
过程4:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LWRT (lock write)
Next dba: 0×00000000 itli: 0
CHANGE #2 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: HWMMV (move hwm)
NBK: 3
Opcode: LUPD_LLIST (link a list)
Slot no: 0, Count: 3
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000016 Head: 0x
过程5:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: LUPD_UNLBLK (unlink block)
Slot no: 0, Count: 1
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000016 Head: 0x
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LCLR (lock clear)
Next dba: 0×00000000 itli: 0
过程6:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: LUPD_UNLBLK (unlink block)
Slot no: 0, Count: 1
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000016 Head: 0x
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LCLR (lock clear)
Next dba: 0×00000000 itli: 0
过程7:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed210 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: LUPD_UNLBLK (unlink block)
Slot no: 0, Count: 1
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000016 Head: 0×00000000 Tail: 0×00000000
CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LCLR (lock clear)
Next dba: 0×00000000 itli: 0
过程8:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed212 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LWRT (lock write)
Next dba: 0×00000000 itli: 0
CHANGE #2 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: HWMMV (move hwm)
NBK: 5
Opcode: LUPD_LLIST (link a list)
Slot no: 0, Count: 5
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000017 Head: 0x
……省略显示其他类似过程
过程18:
REDO RECORD – Thread:1 RBA: 0x
SCN: 0×0000.000ed214 SUBSCN: 1 05/16/2011 17:07:29
CHANGE #1 TYP:0 CLS: 1 AFN:1 DBA:0x
KTSFRBLNK (block link modify) redo: Opcode: LWRT (lock write)
Next dba: 0×00000000 itli: 0
CHANGE #2 TYP:0 CLS: 4 AFN:1 DBA:0x
KTSFRGRP (fgb/shdr modify freelist) redo:
Opcode: HWMMV (move hwm)
NBK: 5
Opcode: LUPD_LLIST (link a list)
Slot no: 0, Count: 5
Flag: = 1 xid or slot0 ccnt: 0×0000.000.00000019 Head: 0x
从上述过程1一直到过程18,非常完整的显示了Oracle是如何将ccnt的值从21(0×15)递增到25(0×19)的。
现在我们来尝试解释一下上述过程的含义:
上述过程1、2、3为一组,清晰的表示了Oracle在insert大量数据后是如何开始修改MSSM的段头的freelist的,从t1在insert之前的段头的dump内容中我们可以看到如下内容:
nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 21
SEG LST:: flg: USED lhd: 0x
即表明t1的main freelist已经存在且header指向0x
那么现在当Oracle插入大量数据的时候,因为freelist上已经存在3个block(分别是0x
等到过程1、过程2、过程3都执行完了,现在t1的main freelist上已经不存在可用的block,所以Oracle这时候要扩展高水位线,给t1的main freelist先分配一些可用的free block,也就是过程4所表明的含义。在过程4里,Oracle额外分配了3个block(分别是0x
后续的分析与上面类似,最后的结果就是ccnt递增到0×19就终止了,即这次insert操作做完了后,t1的main free list中的free block变成了5个(从0x
所以,从上面的分析我们可以得出结论:ccnt其实记录的是在MSSM下Oracle对段头的freelist的一组修改操作所对应的sequence number,相邻的组与组之间的ccnt会递增1。
一组修改操作的含义是如下三种情况之一:
1、 单纯的unlink block(例如过程1、2、3);
2、 link block + unlink block (例如过程4、5、6、7)
3、 单纯的link block (例如过程18)
简单总结一下:MSSM的段头中CCNT我猜是Change CouNT的缩写,它的含义是Oracle对MSSM中段头的free list的修改次数,一次修改通常会包括move hwm+link block+unlink block这一组动作。

Recent Comments