MSSM的段头中CCNT的含义(续)

其实这篇文章的结论并不重要,最关键的是当你碰到一个在googlebaiduMOS甚至Oracle内部的webiv上都查不到相关内容的时候,你处理的思路是什么。

经过简单的测试­,我们猜测——MSSM的段头中CCNT的含义就是Change CouNT的缩写,它的含义是OracleMSSM中段头的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: 0x0040c779 (1/51065)

scn: 0x0000.000ec812 seq: 0x04 flg: 0x00 tail: 0xc8121004

frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER – UNLIMITED

  Extent Control Header

  —————————————————————–

  Extent Header:: spare1: 0      spare2: 0      #extents: 10     #blocks: 79   

                  last map  0x00000000  #maps: 0      offset: 4128 

      Highwater::  0x0040c7d6  ext#: 9      blk#: 5      ext size: 8    

  #blocks in seg. hdr’s freelists: 3    

  #blocks below: 76   

  mapblk  0x00000000  offset: 9    

                   Unlocked

     Map Header:: next  0x00000000  #extents: 10   obj#: 30547  flag: 0x40000000

  Extent Map

  —————————————————————–

   0x0040c77a  length: 7    

   0x0040c781  length: 8    

   0x0040c791  length: 8    

   0x0040c799  length: 8    

   0x0040c7a1  length: 8    

   0x0040c7a9  length: 8    

   0x0040c7b9  length: 8    

   0x0040c7c1  length: 8    

   0x0040c7c9  length: 8    

   0x0040c7d1  length: 8    

 

  nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 21

  SEG LST:: flg: USED   lhd: 0x0040c7d3 ltl: 0x0040c7d5

 

当我对t1执行insert大量数据的操作时,Oracle必然要去修改t1段头中的freelist

SQL> insert into t1 select * from t1 where rownum<1000;

 

999 rows inserted

 

SQL> commit;

 

Commit complete

 

执行完上述插入操作后,t1的段头中内容如下所示,从结果里我们可以看到ccnt21变成了25

Start dump data blocks tsn: 0 file#: 1 minblk 51065 maxblk 51065

buffer tsn: 0 rdba: 0x0040c779 (1/51065)

scn: 0x0000.000ed214 seq: 0x02 flg: 0x00 tail: 0xd2141002

frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER – UNLIMITED

  Extent Control Header

  —————————————————————–

  Extent Header:: spare1: 0      spare2: 0      #extents: 12     #blocks: 95   

                  last map  0x00000000  #maps: 0      offset: 4128 

      Highwater::  0x0040c7e6  ext#: 11     blk#: 5      ext size: 8    

  #blocks in seg. hdr’s freelists: 5    

  #blocks below: 92   

  mapblk  0x00000000  offset: 11   

                   Unlocked

     Map Header:: next  0x00000000  #extents: 12   obj#: 30547  flag: 0x40000000

  Extent Map

  —————————————————————–

   0x0040c77a  length: 7    

   0x0040c781  length: 8    

   0x0040c791  length: 8    

   0x0040c799  length: 8    

   0x0040c7a1  length: 8    

   0x0040c7a9  length: 8    

   0x0040c7b9  length: 8    

   0x0040c7c1  length: 8    

   0x0040c7c9  length: 8    

   0x0040c7d1  length: 8    

   0x0040c7d9  length: 8    

   0x0040c7e1  length: 8    

 

  nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 25

  SEG LST:: flg: USED   lhd: 0x0040c7e1 ltl: 0x0040c7e5

 

现在的关键问题是,这个ccnt的修改之后的值25是如何来的?只有在我们清楚了这个25的来历,我们才算真正的对上述问题有了一个初步的了解。

 

这时候我们的思路就是dump一下redo,然后看看redo的内容我们就什么都清楚了,dump之后的redo中清晰的显示出了ccnt的值的变化过程:

过程1

REDO RECORD – Thread:1 RBA: 0x00000a.00000041.004c LEN: 0x0070 VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ec812 SEQ:  4 OP:13.7

KTSFRGRP (fgb/shdr modify freelist) redo:

 Opcode: LUPD_UNLBLK (unlink block)

Slot no: 0, Count: 1

Flag: = 1 xid or slot0 ccnt:  0x0000.000.00000015 Head:  0x0040c7d4 Tail:  0x0040c7d5

CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d3 SCN:0x0000.000ed210 SEQ:  2 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LCLR (lock clear)

Next dba: 0x00000000 itli: 0

 

过程2

REDO RECORD – Thread:1 RBA: 0x00000a.00000051.0098 LEN: 0x0070 VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed210 SEQ:  1 OP:13.7

KTSFRGRP (fgb/shdr modify freelist) redo:

 Opcode: LUPD_UNLBLK (unlink block)

Slot no: 0, Count: 1

Flag: = 1 xid or slot0 ccnt:  0x0000.000.00000015 Head:  0x0040c7d5 Tail:  0x0040c7d5

CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d4 SCN:0x0000.000ed210 SEQ:  2 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LCLR (lock clear)

Next dba: 0x00000000 itli: 0

 

过程3

REDO RECORD – Thread:1 RBA: 0x00000a.00000061.00ec LEN: 0x0070 VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed210 SEQ:  2 OP:13.7

KTSFRGRP (fgb/shdr modify freelist) redo:

 Opcode: LUPD_UNLBLK (unlink block)

Slot no: 0, Count: 1

Flag: = 1 xid or slot0 ccnt:  0x0000.000.00000015 Head:  0x00000000 Tail:  0x00000000

CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d5 SCN:0x0000.000ed210 SEQ:  2 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LCLR (lock clear)

Next dba: 0x00000000 itli: 0

 

过程4

REDO RECORD – Thread:1 RBA: 0x00000a.00000062.0098 LEN: 0x007c VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d8 SCN:0x0000.000ed210 SEQ:  3 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LWRT (lock write)

Next dba: 0x00000000 itli: 0

CHANGE #2 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed210 SEQ:  3 OP:13.7

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:  0x0000.000.00000016 Head:  0x0040c7d6 Tail:  0x0040c7d8

 

过程5

REDO RECORD – Thread:1 RBA: 0x00000a.00000072.00e8 LEN: 0x0070 VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed210 SEQ:  4 OP:13.7

KTSFRGRP (fgb/shdr modify freelist) redo:

 Opcode: LUPD_UNLBLK (unlink block)

Slot no: 0, Count: 1

Flag: = 1 xid or slot0 ccnt:  0x0000.000.00000016 Head:  0x0040c7d7 Tail:  0x0040c7d8

CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d6 SCN:0x0000.000ed210 SEQ:  5 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LCLR (lock clear)

Next dba: 0x00000000 itli: 0

 

过程6

REDO RECORD – Thread:1 RBA: 0x00000a.00000082.003c LEN: 0x0070 VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed210 SEQ:  5 OP:13.7

KTSFRGRP (fgb/shdr modify freelist) redo:

 Opcode: LUPD_UNLBLK (unlink block)

Slot no: 0, Count: 1

Flag: = 1 xid or slot0 ccnt:  0x0000.000.00000016 Head:  0x0040c7d8 Tail:  0x0040c7d8

CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d7 SCN:0x0000.000ed210 SEQ:  4 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LCLR (lock clear)

Next dba: 0x00000000 itli: 0

 

过程7

REDO RECORD – Thread:1 RBA: 0x00000a.00000092.00a8 LEN: 0x0070 VLD: 0x01

SCN: 0x0000.000ed210 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed210 SEQ:  6 OP:13.7

KTSFRGRP (fgb/shdr modify freelist) redo:

 Opcode: LUPD_UNLBLK (unlink block)

Slot no: 0, Count: 1

Flag: = 1 xid or slot0 ccnt:  0x0000.000.00000016 Head:  0x00000000 Tail:  0x00000000

CHANGE #2 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7d8 SCN:0x0000.000ed210 SEQ:  6 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LCLR (lock clear)

Next dba: 0x00000000 itli: 0

 

过程8

REDO RECORD – Thread:1 RBA: 0x00000a.00000097.0030 LEN: 0x007c VLD: 0x01

SCN: 0x0000.000ed212 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7dd SCN:0x0000.000ed212 SEQ:  3 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LWRT (lock write)

Next dba: 0x00000000 itli: 0

CHANGE #2 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed212 SEQ:  1 OP:13.7

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:  0x0000.000.00000017 Head:  0x0040c7d9 Tail:  0x0040c7dd

 

……省略显示其他类似过程

 

过程18

REDO RECORD – Thread:1 RBA: 0x00000a.0000011e.0010 LEN: 0x007c VLD: 0x01

SCN: 0x0000.000ed214 SUBSCN:  1 05/16/2011 17:07:29

CHANGE #1 TYP:0 CLS: 1 AFN:1 DBA:0x0040c7e5 SCN:0x0000.000ed214 SEQ:  3 OP:13.6

KTSFRBLNK (block link modify) redo:  Opcode: LWRT (lock write)

Next dba: 0x00000000 itli: 0

CHANGE #2 TYP:0 CLS: 4 AFN:1 DBA:0x0040c779 SCN:0x0000.000ed214 SEQ:  1 OP:13.7

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:  0x0000.000.00000019 Head:  0x0040c7e1 Tail:  0x0040c7e5

 

从上述过程1一直到过程18,非常完整的显示了Oracle是如何将ccnt的值从210x15)递增到250x19)的。

现在我们来尝试解释一下上述过程的含义:

上述过程123为一组,清晰的表示了Oracleinsert大量数据后是如何开始修改MSSM的段头的freelist的,从t1insert之前的段头的dump内容中我们可以看到如下内容:

nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 21

SEG LST:: flg: USED   lhd: 0x0040c7d3 ltl: 0x0040c7d5

即表明t1main freelist已经存在且header指向0x0040c7d3tail指向ltl: 0x0040c7d5

那么现在当Oracle插入大量数据的时候,因为freelist上已经存在3block(分别是0x0040c7d30x0040c7d40x0040c7d5),所以就直接拿来用好了,也就是过程1、过程2、过程3所对应的unlink block操作。

等到过程1、过程2、过程3都执行完了,现在t1main freelist上已经不存在可用的block,所以Oracle这时候要扩展高水位线,给t1main freelist先分配一些可用的free block,也就是过程4所表明的含义。在过程4里,Oracle额外分配了3block(分别是0x0040c7d60x0040c7d7 0x0040c7d8),把高水位线扩展到了0x0040c7d9且对这三个block执行了block link操作,以便让其处于main freelist中。接下来过程567做的事情和过程123类似,都是为了用freelist上存在的3block而执行的unlink block操作。所以过程4567其实是另外一组操作,注意看,过程4567所对应的ccnt已经递增了1

 

后续的分析与上面类似,最后的结果就是ccnt递增到0x19就终止了,即这次insert操作做完了后,t1main free list中的free block变成了5个(从0x0040c7e10x0040c7e5)。

 

所以,从上面的分析我们可以得出结论:ccnt其实记录的是在MSSMOracle对段头的freelist的一组修改操作所对应的sequence number,相邻的组与组之间的ccnt会递增1

一组修改操作的含义是如下三种情况之一:

1、  单纯的unlink block(例如过程123);

2、  link block unlink block (例如过程4567

3、  单纯的link block (例如过程18

 

简单总结一下:MSSM的段头中CCNT我猜是Change CouNT的缩写,它的含义是OracleMSSM中段头的free list的修改次数,一次修改通常会包括move hwm+link block+unlink block这一组动作。



Leave a Reply

Your email address will not be published. Required fields are marked *