April 2009 Archives

关于ASSM的段头

| No Comments

什么是ASSM的段头?这里是指ASSM里的一个表在刚建立的时候就有的,也就是其初始metadata所在的block。有人曾经提到说ASSM的段头是有3block,其实这是不准确的,这里也有可能是4blockdba_segments里的HEADER_FILEHEADER_BLOCKASSM里指的就是PAGETABLE SEGMENT HEADER

 

我们来看两个例子,例一中段头有3block,例二中段头有4block

 

例一:

SQL> create tablespace testtbs datafile '/iprat02/ipratest/testtbs_01.dbf' size 1M;

 

Tablespace created

 

SQL> select EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces where tablespace_name='TESTTBS1';

 

EXTENT_MANAGEMENT SEGMENT_SPACE_MANAGEMENT

----------------- ------------------------

LOCAL             AUTO

 

SQL> create table t1 (id number, name varchar2(30)) tablespace testtbs storage (initial 896K);

 

Table created

 

SQL> create table t2 (id number, c1 char(2000), c2 char(2000), c3 char(2000)) tablespace testtbs storage (initial 64K);

 

Table created

 

SQL> insert into t2 VALUES (1, 'A', 'A', 'A');

 

1 row inserted

 

SQL> insert into t2 VALUES (2, 'A', 'A', 'A');

 

1 row inserted

 

SQL> insert into t2 VALUES (3, 'A', 'A', 'A');

 

1 row inserted

 

SQL> insert into t2 VALUES (4, 'A', 'A', 'A');

 

1 row inserted

 

SQL> insert into t2 VALUES (5, 'A', 'A', 'A');

 

1 row inserted

 

SQL> commit;

 

Commit complete

 

SQL> insert into t2 VALUES (6, 'A', 'A', 'A');

 

insert into t2 VALUES (6, 'A', 'A', 'A')

 

ORA-01653: unable to extend table SYS.T2 by 8 in tablespace TESTTBS

 

SQL> select file_id,block_id from dba_extents where segment_name='T2';

 

   FILE_ID   BLOCK_ID

---------- ----------

        19        121

 

SQL> select header_file,header_block from dba_segments where segment_name='T2';

 

HEADER_FILE HEADER_BLOCK

----------- ------------

         19          123

 

我们分别dump 19-12119-12219-123这三个block

19-121的内容:

Start dump data blocks tsn: 12 file#: 19 minblk 121 maxblk 121

buffer tsn: 12 rdba: 0x04c00079 (19/121)

scn: 0x0009.1523a924 seq: 0x07 flg: 0x04 tail: 0xa9242007

frmt: 0x02 chkval: 0x31b2 type: 0x20=FIRST LEVEL BITMAP BLOCK

......中间内容省略

Dump of First Level Bitmap Block

 --------------------------------

   nbits : 4 nranges: 1         parent dba:  0x04c0007a   poffset: 0    

   unformatted: 0       total: 8         first useful block: 3     

   owning instance : 1

   instance ownership changed at 04/21/2009 15:30:35

   Last successful Search 04/21/2009 15:30:35

   Freeness Status:  nf1 0      nf2 5      nf3 0      nf4 0     

 

   Extent Map Block Offset: 4294967295

   First free datablock : 3     

   Bitmap block lock opcode 0

   Locker xid:     :  0x0000.000.00000000

   Inc #: 0 Objd: 66787

  HWM Flag: HWM Set

      Highwater::  0x04c00081  ext#: 0      blk#: 8      ext size: 8    

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 5    

  mapblk  0x00000000  offset: 0    

  --------------------------------------------------------

  DBA Ranges :

  --------------------------------------------------------

   0x04c00079  Length: 8      Offset: 0     

 

   0:Metadata   1:Metadata   2:Metadata   3:25-50% free

   4:25-50% free   5:25-50% free   6:25-50% free   7:25-50% free

  --------------------------------------------------------

End dump data blocks tsn: 12 file#: 19 minblk 121 maxblk 121

 

19-122的内容:

Start dump data blocks tsn: 12 file#: 19 minblk 122 maxblk 122

buffer tsn: 12 rdba: 0x04c0007a (19/122)

scn: 0x0009.1523a924 seq: 0x01 flg: 0x04 tail: 0xa9242101

frmt: 0x02 chkval: 0x17d7 type: 0x21=SECOND LEVEL BITMAP BLOCK

Hex dump of block: st=0, typ_found=1

......中间内容省略

Dump of Second Level Bitmap Block

   number: 1       nfree: 1       ffree: 0      pdba:     0x04c0007b

   Inc #: 0 Objd: 66787

  opcode:0

 xid:

  L1 Ranges :

  --------------------------------------------------------

   0x04c00079  Free: 3 Inst: 1

 

  --------------------------------------------------------

End dump data blocks tsn: 12 file#: 19 minblk 122 maxblk 122

 

19-123的内容:

Start dump data blocks tsn: 12 file#: 19 minblk 123 maxblk 123

buffer tsn: 12 rdba: 0x04c0007b (19/123)

scn: 0x0009.1523a981 seq: 0x01 flg: 0x04 tail: 0xa9812301

frmt: 0x02 chkval: 0x3ec3 type: 0x23=PAGETABLE SEGMENT HEADER

Hex dump of block: st=0, typ_found=1

......中间内容省略

  Extent Control Header

  -----------------------------------------------------------------

  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 8    

                  last map  0x00000000  #maps: 0      offset: 2716 

      Highwater::  0x04c00081  ext#: 0      blk#: 8      ext size: 8    

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 5    

  mapblk  0x00000000  offset: 0    

                   Unlocked

  --------------------------------------------------------

  Low HighWater Mark :

      Highwater::  0x04c00081  ext#: 0      blk#: 8      ext size: 8    

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 5    

  mapblk  0x00000000  offset: 0    

  Level 1 BMB for High HWM block: 0x04c00079

  Level 1 BMB for Low HWM block: 0x04c00079

  --------------------------------------------------------

  Segment Type: 1 nl2: 1      blksz: 8192   fbsz: 0     

  L2 Array start offset:  0x00001434

  First Level 3 BMB:  0x00000000

  L2 Hint for inserts:  0x04c0007a

  Last Level 1 BMB:  0x04c00079

  Last Level II BMB:  0x04c0007a

  Last Level III BMB:  0x00000000

     Map Header:: next  0x00000000  #extents: 1    obj#: 66787  flag: 0x10000000

  Inc # 0

  Extent Map

  -----------------------------------------------------------------

   0x04c00079  length: 8    

 

  Auxillary Map

  --------------------------------------------------------

   Extent 0     :  L1 dba:  0x04c00079 Data dba:  0x04c0007c

  --------------------------------------------------------

 

   Second Level Bitmap block DBAs

   --------------------------------------------------------

   DBA 1:   0x04c0007a

 

End dump data blocks tsn: 12 file#: 19 minblk 123 maxblk 123

 

从结果里可以看到对于表T2,它的段头是有3block。这个从19-121dump内容中可以很清晰的看出来,里面有如下的内容:

first useful block: 3

0:Metadata   1:Metadata   2:Metadata   3:25-50% free

4:25-50% free   5:25-50% free   6:25-50% free   7:25-50% free

 

 

例二:

SQL> select tablespace_name from dba_tables where table_name='SYSQFI';

 

TABLESPACE_NAME

------------------------------

IPRATBS

 

SQL> select EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces where tablespace_name='IPRATBS';

 

EXTENT_MANAGEMENT SEGMENT_SPACE_MANAGEMENT

----------------- ------------------------

LOCAL             AUTO

 

SQL> select file_id,block_id from dba_extents where segment_name='SYSQFI';

 

   FILE_ID   BLOCK_ID

---------- ----------

        10     157321

 

SQL> select header_file,header_block from dba_segments where segment_name='SYSQFI';

 

HEADER_FILE HEADER_BLOCK

----------- ------------

         10       157324

 

我们分别dump 10-15732110-15732210-15732310-1573244block

10-157321的内容:

Start dump data blocks tsn: 8 file#: 10 minblk 157321 maxblk 157321

buffer tsn: 8 rdba: 0x02826689 (10/157321)

scn: 0x0002.e9c77e31 seq: 0x01 flg: 0x04 tail: 0x7e312001

frmt: 0x02 chkval: 0xfffb type: 0x20=FIRST LEVEL BITMAP BLOCK

Hex dump of block: st=0, typ_found=1

......中间内容省略

Dump of First Level Bitmap Block

 --------------------------------

   nbits : 4 nranges: 1         parent dba:  0x0282668b   poffset: 0    

   unformatted: 12      total: 64        first useful block: 4     

   owning instance : 1

   instance ownership changed at 05/21/2008 14:36:54

   Last successful Search 05/21/2008 14:36:54

   Freeness Status:  nf1 0      nf2 0      nf3 0      nf4 48    

 

   Extent Map Block Offset: 4294967295

   First free datablock : 4     

   Bitmap block lock opcode 0

   Locker xid:     :  0x0000.000.00000000

   Inc #: 0 Objd: 66347

  HWM Flag: Not Set

      Highwater::  0x028266c9  ext#: 0      blk#: 64     ext size: 128  

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 60   

  mapblk  0x00000000  offset: 0    

  --------------------------------------------------------

  DBA Ranges :

  --------------------------------------------------------

   0x02826689  Length: 64     Offset: 0     

 

   0:Metadata   1:Metadata   2:Metadata   3:Metadata

   4:unformatted   5:unformatted   6:unformatted   7:unformatted

   8:unformatted   9:unformatted   10:unformatted   11:unformatted

   12:unformatted   13:unformatted   14:unformatted   15:unformatted

   16:75-100% free   17:75-100% free   18:75-100% free   19:75-100% free

   20:75-100% free   21:75-100% free   22:75-100% free   23:75-100% free

   24:75-100% free   25:75-100% free   26:75-100% free   27:75-100% free

   28:75-100% free   29:75-100% free   30:75-100% free   31:75-100% free

   32:75-100% free   33:75-100% free   34:75-100% free   35:75-100% free

   36:75-100% free   37:75-100% free   38:75-100% free   39:75-100% free

   40:75-100% free   41:75-100% free   42:75-100% free   43:75-100% free

   44:75-100% free   45:75-100% free   46:75-100% free   47:75-100% free

   48:75-100% free   49:75-100% free   50:75-100% free   51:75-100% free

   52:75-100% free   53:75-100% free   54:75-100% free   55:75-100% free

   56:75-100% free   57:75-100% free   58:75-100% free   59:75-100% free

   60:75-100% free   61:75-100% free   62:75-100% free   63:75-100% free

  --------------------------------------------------------

End dump data blocks tsn: 8 file#: 10 minblk 157321 maxblk 157321

 

10-157322的内容:

Start dump data blocks tsn: 8 file#: 10 minblk 157322 maxblk 157322

buffer tsn: 8 rdba: 0x0282668a (10/157322)

scn: 0x0002.d2628ee7 seq: 0x02 flg: 0x04 tail: 0x8ee72002

frmt: 0x02 chkval: 0x8357 type: 0x20=FIRST LEVEL BITMAP BLOCK

Hex dump of block: st=0, typ_found=1

......中间内容省略

Dump of First Level Bitmap Block

 --------------------------------

   nbits : 4 nranges: 1         parent dba:  0x0282668b   poffset: 1    

   unformatted: 64      total: 64        first useful block: 0     

   owning instance : 1

   instance ownership changed at

   Last successful Search

   Freeness Status:  nf1 0      nf2 0      nf3 0      nf4 0     

 

   Extent Map Block Offset: 4294967295

   First free datablock : 0     

   Bitmap block lock opcode 9

   Locker xid:     :  0x0005.005.0000319a

   Inc #: 0 Objd: 66347

  --------------------------------------------------------

  DBA Ranges :

  --------------------------------------------------------

   0x028266c9  Length: 64     Offset: 0     

 

   0:unformatted   1:unformatted   2:unformatted   3:unformatted

   4:unformatted   5:unformatted   6:unformatted   7:unformatted

   8:unformatted   9:unformatted   10:unformatted   11:unformatted

   12:unformatted   13:unformatted   14:unformatted   15:unformatted

   16:unformatted   17:unformatted   18:unformatted   19:unformatted

   20:unformatted   21:unformatted   22:unformatted   23:unformatted

   24:unformatted   25:unformatted   26:unformatted   27:unformatted

   28:unformatted   29:unformatted   30:unformatted   31:unformatted

   32:unformatted   33:unformatted   34:unformatted   35:unformatted

   36:unformatted   37:unformatted   38:unformatted   39:unformatted

   40:unformatted   41:unformatted   42:unformatted   43:unformatted

   44:unformatted   45:unformatted   46:unformatted   47:unformatted

   48:unformatted   49:unformatted   50:unformatted   51:unformatted

   52:unformatted   53:unformatted   54:unformatted   55:unformatted

   56:unformatted   57:unformatted   58:unformatted   59:unformatted

   60:unformatted   61:unformatted   62:unformatted   63:unformatted

  --------------------------------------------------------

End dump data blocks tsn: 8 file#: 10 minblk 157322 maxblk 157322

 

10-157323的内容:

Start dump data blocks tsn: 8 file#: 10 minblk 157323 maxblk 157323

buffer tsn: 8 rdba: 0x0282668b (10/157323)

scn: 0x0002.d2628f06 seq: 0x01 flg: 0x04 tail: 0x8f062101

frmt: 0x02 chkval: 0xd0e8 type: 0x21=SECOND LEVEL BITMAP BLOCK

Hex dump of block: st=0, typ_found=1

......中间内容省略

Dump of Second Level Bitmap Block

   number: 2       nfree: 2       ffree: 0      pdba:     0x0282668c

   Inc #: 0 Objd: 66347

  opcode:0

 xid:

  L1 Ranges :

  --------------------------------------------------------

   0x02826689  Free: 5 Inst: 1

   0x0282668a  Free: 5 Inst: 1

 

  --------------------------------------------------------

End dump data blocks tsn: 8 file#: 10 minblk 157323 maxblk 157323

 

10-157324的内容:

Start dump data blocks tsn: 8 file#: 10 minblk 157324 maxblk 157324

buffer tsn: 8 rdba: 0x0282668c (10/157324)

scn: 0x0002.d2628f06 seq: 0x01 flg: 0x04 tail: 0x8f062301

frmt: 0x02 chkval: 0xfe79 type: 0x23=PAGETABLE SEGMENT HEADER

Hex dump of block: st=0, typ_found=1

......中间内容省略

  Extent Control Header

  -----------------------------------------------------------------

  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 128  

                  last map  0x00000000  #maps: 0      offset: 2716 

      Highwater::  0x028266c9  ext#: 0      blk#: 64     ext size: 128  

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 60   

  mapblk  0x00000000  offset: 0    

                   Unlocked

  --------------------------------------------------------

  Low HighWater Mark :

      Highwater::  0x0282668d  ext#: 0      blk#: 4      ext size: 128  

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 0    

  mapblk  0x00000000  offset: 0    

  Level 1 BMB for High HWM block: 0x02826689

  Level 1 BMB for Low HWM block: 0x02826689

  --------------------------------------------------------

  Segment Type: 1 nl2: 1      blksz: 8192   fbsz: 0     

  L2 Array start offset:  0x00001434

  First Level 3 BMB:  0x00000000

  L2 Hint for inserts:  0x0282668b

  Last Level 1 BMB:  0x0282668a

  Last Level II BMB:  0x0282668b

  Last Level III BMB:  0x00000000

     Map Header:: next  0x00000000  #extents: 1    obj#: 66347  flag: 0x10000000

  Inc # 0

  Extent Map

  -----------------------------------------------------------------

   0x02826689  length: 128  

 

  Auxillary Map

  --------------------------------------------------------

   Extent 0     :  L1 dba:  0x02826689 Data dba:  0x0282668d

  --------------------------------------------------------

 

   Second Level Bitmap block DBAs

   --------------------------------------------------------

   DBA 1:   0x0282668b

 

End dump data blocks tsn: 8 file#: 10 minblk 157324 maxblk 157324

 

从结果里可以看到对于表SYSQFI,它的段头是有4block,这 4block里有两个FIRST LEVEL BITMAP BLOCK,第二个FIRST LEVEL BITMAP BLOCK里全部是空块。这个从10-15732110-157322dump内容中可以很清晰的看出来,10-157321里面有如下的内容:

first useful block: 4

0:Metadata   1:Metadata   2:Metadata   3:Metadata

   4:unformatted   5:unformatted   6:unformatted   7:unformatted

   8:unformatted   9:unformatted   10:unformatted   11:unformatted

   12:unformatted   13:unformatted   14:unformatted   15:unformatted

   16:75-100% free   17:75-100% free   18:75-100% free   19:75-100% free

   20:75-100% free   21:75-100% free   22:75-100% free   23:75-100% free

   24:75-100% free   25:75-100% free   26:75-100% free   27:75-100% free

   28:75-100% free   29:75-100% free   30:75-100% free   31:75-100% free

   32:75-100% free   33:75-100% free   34:75-100% free   35:75-100% free

   36:75-100% free   37:75-100% free   38:75-100% free   39:75-100% free

   40:75-100% free   41:75-100% free   42:75-100% free   43:75-100% free

   44:75-100% free   45:75-100% free   46:75-100% free   47:75-100% free

   48:75-100% free   49:75-100% free   50:75-100% free   51:75-100% free

   52:75-100% free   53:75-100% free   54:75-100% free   55:75-100% free

   56:75-100% free   57:75-100% free   58:75-100% free   59:75-100% free

   60:75-100% free   61:75-100% free   62:75-100% free   63:75-100% free

 

有兴趣的朋友可以仔细的去看一下上面dump文件的内容,看完后对ASSM的了解当会更进一步。

什么是未格式化的块

| 2 Comments

什么是oracle中未格式化的块?

 

让我们来看一下熊哥对上述问题的精彩解释:"未格式化,意思就是这个块,已经是属于这个段了,但是还保留着原来的样子没动。格式化就是把块中的数据清除掉,并把块头改为这个对象的。MSSM表空间中的段,只有一个高水位,高水位下的块都是格式化了的。但是ASSM表空间中的段,有两个高水位,低高水位和高高水位,低高水位下的块全部是格式化了的,但是低高水位和高高水位之间的块,则可能是格式化了的,也可能没有"

 

解释的再清晰不过了,我们现在来看一个未格式化的块的例子:

 

SQL> select HEADER_FILE,HEADER_BLOCK from dba_segments where segment_name='SYSQFI';

 

HEADER_FILE HEADER_BLOCK

----------- ------------

         10       157324

 

SYSQFI所在的段头dump出来:

Extent Control Header

  -----------------------------------------------------------------

  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 128  

                  last map  0x00000000  #maps: 0      offset: 2716 

      Highwater::  0x028266c9  ext#: 0      blk#: 64     ext size: 128  

  #blocks in seg. hdr's freelists: 0    

  #blocks below: 60   

  mapblk  0x00000000  offset: 0    

                   Unlocked

  --------------------------------------------------------

  Low HighWater Mark :

      Highwater::  0x0282668d  ext#: 0      blk#: 4      ext size: 128

 

可以看到高高水位是0x028266c9,低高水位是0x0282668d

SQL> exec sys.cdba('028266c9','H');

.

The file is 10

The block is 157385

 

PL/SQL procedure successfully completed

 

SQL> exec sys.cdba('0282668d','H');

.

The file is 10

The block is 157325

 

PL/SQL procedure successfully completed

 

也就是说SYSQFI的高高水位是file 10,block 157385;其低高水位是file 10,block 157325

 

我们现在再来看一下SYSQFI现在data object number是多少:

SQL> select object_id,data_object_id from dba_objects where object_name='SYSQFI';

 

 OBJECT_ID DATA_OBJECT_ID

---------- --------------

     65795          66347

 

这里明显SYSQFIdata object number大于其object number,也就是说在SYSQFI上曾经发生过truncate或者move操作。注意对于truncate操作而言,truncate后其data object number不一定就是在原先的data object number上加1

 

SQL> select to_char('66347','XXXXXXXX') from dual;

 

TO_CHAR('66347','XXXXXXXX')

---------------------------

    1032B

 

SQL> select to_char('65795','XXXXXXXX') from dual;

 

TO_CHAR('65795','XXXXXXXX')

---------------------------

10103

 

换句话说,SYSQFI中现在在其低高水位(file 10,block 157325)和其高高水位(file 10,block 157385)之间的block,只要这个block上记录的data object number不等于1032B,那这个block就是一个未格式化的块!

 

我们现在来看file 10block 157330

Start dump data blocks tsn: 8 file#: 10 minblk 157330 maxblk 157330

buffer tsn: 8 rdba: 0x02826692 (10/157330)

scn: 0x0002.d25fa5bd seq: 0x01 flg: 0x06 tail: 0xa5bd0601

frmt: 0x02 chkval: 0x8d34 type: 0x06=trans data

Hex dump of block: st=0, typ_found=1

......中间内容省略

Block header dump:  0x02826692

 Object id on Block? Y

 seg/obj: 0x10103  csc: 0x02.d25fa591  itc: 2  flg: E  typ: 1 - DATA

     brn: 0  bdba: 0x2826689 ver: 0x01 opc: 0

     inc: 0  exflg: 0

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0006.02c.00009afa  0x0080098a.07a4.39  --U-   36  fsc 0x0048.d25fa5bd

0x02   0x0002.02a.000030e8  0x00800542.0591.27  C---    0  scn 0x0002.d25f9bc8

 

data_block_dump,data header at 0x110572064

===============

tsiz: 0x1f98

hsiz: 0xe8

pbl: 0x110572064

bdba: 0x02826692

     76543210

flag=--------

ntab=1

nrow=107

frre=36

fsbo=0xe8

fseo=0x220

avsp=0x14f6

tosp=0x153e

0xe:pti[0] nrow=107       offs=0

0x12:pri[0]      offs=0x269

0x14:pri[1]      offs=0x220

......中间内容省略

0xe4:pri[105]  sfll=106

0xe6:pri[106]  sfll=-1

block_row_dump:

tab 0, row 0, @0x269

tl: 71 fb: --H-FL-- lb: 0x1  cc: 11

col  0: [ 4]  c3 0e 34 46

col  1: [ 2]  c1 56

col  2: [14]  bd e8 cf ee cd a8 d6 aa b5 a5 d5 c5 ca fd

col  3: [ 6]  53 41 4c 42 54 48

col  4: [ 6]  53 42 54 44 4d 54

col  5: [ 1]  4e

col  6: *NULL*

col  7: *NULL*

col  8: [ 5]  c4 15 09 06 0a

col  9: [ 3]  46 45 57

col 10: [16]  53 41 4c 42 54 48 46 4f 52 4d 31 32 33 33 33 33

tab 0, row 1, @0x220

tl: 71 fb: --H-FL-- lb: 0x1  cc: 11

col  0: [ 4]  c3 0e 34 47

col  1: [ 2]  c1 57

col  2: [14]  b4 fb cf ee cd a8 d6 aa b5 a5 d5 c5 ca fd

col  3: [ 6]  53 41 4c 42 54 48

col  4: [ 6]  53 42 54 43 4d 54

col  5: [ 1]  4e

col  6: *NULL*

col  7: *NULL*

col  8: [ 5]  c4 15 09 06 0a

col  9: [ 3]  46 45 57

col 10: [16]  53 41 4c 42 54 48 46 4f 52 4d 31 32 33 33 33 33

......中间内容省略

tab 0, row 34, @0x2b2

tl: 74 fb: --H-FL-- lb: 0x1  cc: 11

col  0: [ 4]  c3 0e 35 04

col  1: [ 2]  c1 21

col  2: [17]  c6 e4 cb fb d2 b5 ce f1 ca d5 c8 eb c0 e0 d0 cd 32

col  3: [ 6]  53 41 4c 42 54 48

col  4: [ 6]  53 42 54 49 43 32

col  5: [ 1]  43

col  6: *NULL*

col  7: *NULL*

col  8: [ 5]  c4 15 09 06 0a

col  9: [ 3]  46 45 57

col 10: [16]  53 41 4c 42 54 48 46 4f 52 4d 31 32 33 33 33 33

tab 0, row 35, @0x1652

tl: 66 fb: --H-FL-- lb: 0x1  cc: 11

col  0: [ 4]  c3 0e 35 05

col  1: [ 2]  c1 22

col  2: [17]  c6 e4 cb fb d2 b5 ce f1 ca d5 c8 eb bd f0 b6 ee 32

col  3: [ 6]  53 41 4c 42 54 48

col  4: [ 6]  53 42 54 49 41 32

col  5: [ 1]  4e

col  6: *NULL*

col  7: *NULL*

col  8: *NULL*

col  9: *NULL*

col 10: [16]  53 41 4c 42 54 48 46 4f 52 4d 31 32 33 33 33 33

end_of_block_dump

End dump data blocks tsn: 8 file#: 10 minblk 157330 maxblk 157330

 

从上述dump出来的内容中我们可以看到上述blockfile 10block 157330)就是一个未格式化的块!因为它的data object number0x10103,已经和SYSQFI现在的data object number不一致了。而且这个block的块头记录的数据和实际的数据并不一致,从块头里看这个block107行记录,但实际上这个block只有36行记录。

如何在长文本上建索引

| 1 Comment

这个礼拜,我的直属领导老袁给我布置了几项任务,其中有一项就是让我去看一下如何在长文本上建立有效的索引?

如果数据量很大的情况下,直接在一个长文本上建索引肯定是不太现实的,因为数据量很大且文本太长的话,如果直接在上面建索引,索引的键值也就相当于是一个长文本,这样一来会浪费存储空间,二来oracle再去search索引的时候需要去一个一个键值的去比对长文本,这样效率必然是不高的!

怎么办?

我当天晚上坐公车回家的时候偶然想到oracleshared pool里面找共享sql的执行计划的时候不是直接根据sql的文本去找的,而是先计算一个hash值,然后再根据这个hash值去检索shared pool。那其实我们这里可以照葫芦画瓢。

 

所以处理上述问题的大致思路是:

1、如果是要完全匹配,我们可以考虑在存长文本的时候同时调用一个公共的hash算法把这个长文本的hash值也存下来,然后在hash值上建索引。查找长文本的时候,先调用同样的hash算法把要检索的长文本的hash值算出来,然后再以这个hash值去检索数据库。

2、如果是要部分匹配,可以考虑用oracle的全文检索。

 

这篇文章只针对完全匹配这种情况。

 

公共的hash算法可以考虑调用oracle自带的函数DBMS_UTILITY.GET_HASH_VALUE,如下是这个函数的定义:

DBMS_UTILITY.GET_HASH_VALUE (

   name      VARCHAR2,

   base      NUMBER,

   hash_size NUMBER)

  RETURN NUMBER;

 

A hash value based on the input string. For example, to get a hash value on a string where the hash value should be between 1000 and 3047, use 1000 as the base value and 2048 as the hash_size value. Using a power of 2 for the hash_size parameter works best.

 

针对上述思路,有一些地方需要我们注意:

1、可以考虑在目标表上建insert triggerupdate trigger,维护长文本的hash值就在上述两个trigger中实现,这样就可以不用改动前台DML操作的代码。

 

2、决定DBMS_UTILITY.GET_HASH_VALUE 中的hash_size的时候应该根据目标表的数据量来定,比如如果你的目标表的数据量有1000万,那么你的hash_size就应该是超过1000万的一个整数,且这个整数应该是2n次方,比如224次方,也就是16777216

 

3、前台针对长文本做完全匹配查询的时候,传到数据库之前将where条件中的

   长文本字段='用户输入的查询值'

   转变成

   存放hash值的字段 DBMS_UTILITY.GET_HASH_VALUE('用户输入的查询值',1,16777216)

   如果前台传入的长文本字段的值是null,那应该将where条件中的

   长文本字段 is null

   转变成

   存放hash值的字段 DBMS_UTILITY.GET_HASH_VALUE('',1,16777216)

 

4、如果你的数据库要升级,你应该事先考察一下不同的数据库版本中DBMS_UTILITY.GET_HASH_VALUE针对长文本算出来的hash值是否相同?如果不同,应该写运维程序去修改。据我测试,在9.2.0.610.2.0.1以及10.2.0.4这三个版本中DBMS_UTILITY.GET_HASH_VALUE的算法并未改变,如下所示:

SQL> conn dras/astca@astcatest;

Connected to Oracle9i Enterprise Edition Release 9.2.0.6.0

Connected as dras

 

SQL> select DBMS_UTILITY.GET_HASH_VALUE('目标:为未来分摊、审核(或者高并发、高性能)转移到开放平台进行技术储备,AIXC/C++程序设计能力;前端.NET应用借助于中间件(如taxedo)与unix上应用的通信;',1,16777216) hashvalue from dual;

 

 HASHVALUE

----------

   6101134

 

SQL> conn ipra/acca@ipradev;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.1.0

Connected as ipra

 

SQL> select DBMS_UTILITY.GET_HASH_VALUE('目标:为未来分摊、审核(或者高并发、高性能)转移到开放平台进行技术储备,AIXC/C++程序设计能力;前端.NET应用借助于中间件(如taxedo)与unix上应用的通信;',1,16777216) hashvalue from dual;

 

 HASHVALUE

----------

   6101134

 

SQL> conn caipra/acca@ipratest;

Connected to Oracle Database 10g Enterprise Edition Release 10.2.0.4.0

Connected as caipra

 

SQL> select DBMS_UTILITY.GET_HASH_VALUE('目标:为未来分摊、审核(或者高并发、高性能)转移到开放平台进行技术储备,AIXC/C++程序设计能力;前端.NET应用借助于中间件(如taxedo)与unix上应用的通信;',1,16777216) hashvalue from dual;

 

 HASHVALUE

----------

   6101134

解决Multibyte character error一例(续2)

| 1 Comment

在"解决Multibyte character error一例"和"解决Multibyte character error一例(续)"这两篇文章里,我们最后用到的解决方法是:

NLS_LANG设成AMERICAN_AMERICA.WE8ISO8859P1,目的就是告诉oracle我这里A5不是ANSI编码,WE8ISO8859P1A5,你帮我在WE8ISO8859P1ZHS16GBK之间做一个转换吧。并且我们可以看到,当用了上述方法发生了字符转换后oracle实际上是把A5转成了A3A4

 

现在我们用Locale Builder来验证一下上述结论。

Locale Builderoracle提供的查看字符的字符集编码的工具。

这个工具在9iR210gR2里的位置不一样。

windows10gR2下,路径在E:\oracle\product\10.2.0\db_1\nls\lbuilder,这里我的$ORACLE_HOMEE:\oracle\product\10.2.0\db_1

unix10gR2下,路径是在$ORACLE_HOME/nls/lbuilder

unix9iR2下,路径是在$ORACLE_HOME/ocommon/nls/lbuilder

 

以我所在的aix-64为例,在10.2.0.1里执行Locale Builder的时候会报错:

$ ./lbuilder

/u01/app/oracle/product/10.2.0/jre/1.4.2/bin/java[3]: /u01/app/oracle/product/10.2.0/jre/1.4.2/bin/java.bin: 0403-006 Execute permission denied.

解决方法就是按提示把可执行权限加上就可以了。

 

注意,在10.2.0.4里同样执行Locale Builder,就不会报上述错误。

 

我们现在用Locale Builderwindows上来看一下WE8ISO8859P1ZHS16GBK里到底有没有A5,如果有,A5代表什么?以及ZHS16GBKA3A4表示什么?

 

1、观察WE8ISO8859P1里有没有A5,如果有,那A5表示什么?

 

  0xa5-WE8ISO8859P1-resize.jpg 

 

2、观察ZHS16GBK里有没有A5

  0xa5-ZHS16GBK-resize.jpg 

 

 

3、观察ZHS16GBKA3A4表示什么?

  0xa3a4-ZHS16GBK-resize.jpg 

 

我们从结果里可以一目了然的看到,我们观察到的结果完全符合我们之前的结论!

cursor和绑定变量配合使用的标准模板

| No Comments

下个礼拜要给部门同事讲一下cursor和绑定变量的用法,我总结了cursor和绑定变量配合使用的4个标准模板,我这里把最有用的两个模板paste出来。

 

比如,现在我要把scott用户下的表emp中的sal字段都在其原先值的基础上加1,那么应用上述两个标准模板后写出来的存储过程就是下面的模样:

 

create or replace procedure p_demo_cursor_bind_template1 is

/*

用于演示当cursor所对应的数据量未知的情况下的标准处理方式,这里演示的是一条一条处理的方式

*/

 

  --定义批量fetch的数量,我这个例子里是10,建议值是1000

  CN_BATCH_SIZE constant pls_integer := 10;

 

  --定义存放fetch出来的结果集的数组,我这里例子里数组的大小是10,建议值是1000

  type typ_result is record(empno emp.empno%type,

                            ename emp.ename%type,

                            job emp.job%type,

                            mgr emp.mgr%type,

                            hiredate emp.hiredate%type,

                            sal emp.sal%type,

                            comm emp.comm%type,

                            deptno emp.deptno%type,

                            rid urowid);

  type typ_results is varray(10) of typ_result;

  results typ_results;

 

  --定义cursor,这里有三种定义方式

  --第一种方式,显式cursor

  /*cursor cur_emp

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;

  cursor cur_emp(n_empno_input number)

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>n_empno_input order by empno;*/

 

  --第二种方式,不带绑定变量的ref cursor

  /*cur_emp sys_refcursor;*/

 

  --第三种方式,带绑定变量的ref cursor,相当于带参数的显式cursor

  cur_emp sys_refcursor;

  vc_sql varchar2(200) := 'select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>:1 order by empno';

 

begin

 

  --同样的,对应上述三种cursor有三种不同的打开方式

  --显式cursor的打开方式

  /*open cur_emp;

  open cur_emp(7000);*/

 

  --不带绑定变量的ref cursor的打开方式

  /*open cur_emp for select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;*/

 

  --带绑定变量的ref cursor的打开方式

  open cur_emp for vc_sql using 7000;

 

  --第一种处理方式,一条一条处理

  loop

    fetch cur_emp bulk collect into results limit CN_BATCH_SIZE;

    for i in 1..results.count loop

   

      execute immediate 'update emp set sal=sal+1 where rowid = :1' using results(i).rid;

   

    end loop;

    exit when results.count < CN_BATCH_SIZE;

  end loop;

  close cur_emp;

 

  commit; 

 

end p_demo_cursor_bind_template1;

/

 

 

create or replace procedure p_demo_cursor_bind_template2 is

/*

用于演示当cursor所对应的数据量未知的情况下的标准处理方式,这里演示的是批量处理的方式

*/

 

  --定义批量fetch的数量,我这个例子里是10,建议值是1000

  CN_BATCH_SIZE constant pls_integer := 10;

 

  --定义存放fetch出来的结果集的数组

  type typ_empno is table of emp.empno%type index by binary_integer;

  empnos typ_empno;

  type typ_ename is table of emp.ename%type index by binary_integer;

  enames typ_ename;

  type typ_job is table of emp.job%type index by binary_integer;

  jobs typ_job;

  type typ_mgr is table of emp.mgr%type index by binary_integer;

  mgrs typ_mgr;

  type typ_hiredate is table of emp.hiredate%type index by binary_integer;

  hiredates typ_hiredate;

  type typ_sal is table of emp.sal%type index by binary_integer;

  sals typ_sal;

  type typ_comm is table of emp.comm%type index by binary_integer;

  comms typ_comm;

  type typ_deptno is table of emp.deptno%type index by binary_integer;

  deptnos typ_deptno;

  type typ_rid is table of urowid index by binary_integer;

  rids typ_rid;

 

  --定义cursor,这里有三种定义方式

  --第一种方式,显式cursor

  /*cursor cur_emp

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;

  cursor cur_emp(n_empno_input number)

    is select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>n_empno_input order by empno;*/

 

  --第二种方式,不带绑定变量的ref cursor

  /*cur_emp sys_refcursor;*/

 

  --第三种方式,带绑定变量的ref cursor,相当于带参数的显式cursor

  cur_emp sys_refcursor;

  vc_sql varchar2(200) := 'select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>:1 order by empno';

 

begin

 

  --同样的,对应上述三种cursor有三种不同的打开方式

  --显式cursor的打开方式

  /*open cur_emp;

  open cur_emp(7000);*/

 

  --不带绑定变量的ref cursor的打开方式

  /*open cur_emp for select empno,ename,job,mgr,hiredate,sal,comm,deptno,rowid from emp where empno>7000 order by empno;*/

 

  --带绑定变量的ref cursor的打开方式

  open cur_emp for vc_sql using 7000;

 

  --第二种处理方式,批量处理

  loop

    fetch cur_emp bulk collect into empnos,enames,jobs,mgrs,hiredates,sals,comms,deptnos,rids limit CN_BATCH_SIZE;

    for i in 1..rids.count loop    

      sals(i) := sals(i) + 1;

    end loop;

   

    forall i in 1..rids.count

      execute immediate 'update emp set sal=:1 where rowid = :2' using sals(i),rids(i);

     

    exit when rids.count < CN_BATCH_SIZE;

  end loop;

  close cur_emp;

 

  commit; 

 

end p_demo_cursor_bind_template2;

/

 

有兴趣的朋友可以看一下我上述两个存储过程里的注释。

关于AWR

| No Comments

10g里从catsvrm.sql里可以了解AWR11g里则是catawrbt.sql

catsvrm.sql里的脚本catawrtb.sqlcatawrvw.sql可以全面了解AWR所涉及到的基表和视图,有兴趣的话可以看一下里面的注释!

当你要重建AWR的时候,你需要执行脚本catnoawr.sql。但是这个脚本在某些平台上10.2.0.3以下版本里是没有的。

以我所在的aix-64为例,10.2.0.1就没有catnoawr.sql10.2.0.4就有。

catnoawr.sql里你可以了解AWR所涉及到的基表的分类,如下所示:

Rem ******************************************************

Rem  Remove the local DBID from the WRM$_WR_CONTROL table

Rem ******************************************************

BEGIN

  dbms_swrf_internal.remove_wr_control;

END;

/

 

Rem ****************************************************

Rem  Drop the types used for AWR reporting

Rem ****************************************************

 

drop type AWRRPT_TEXT_TYPE_TABLE

/

drop type AWRRPT_TEXT_TYPE

/

drop type AWRRPT_HTML_TYPE_TABLE

/

drop type AWRDRPT_TEXT_TYPE_TABLE

/

drop type AWRDRPT_TEXT_TYPE

/

drop type AWRRPT_HTML_TYPE

/

drop type AWRRPT_ROW_TYPE

/

drop type AWRRPT_NUM_ARY

/

drop type AWRRPT_VCH_ARY

/

drop type AWRRPT_CLB_ARY

/

 

Rem **************************************************************

Rem ... Dropping the Workload Repository History (WRH$) Tables ...

Rem **************************************************************

 

drop table WRH$_FILESTATXS

/

drop table WRH$_FILESTATXS_BL

/

drop table WRH$_TEMPSTATXS

/

drop table WRH$_DATAFILE

/

drop table WRH$_TEMPFILE

/

drop table WRH$_COMP_IOSTAT

/

 

Rem *************************************************************************

Rem ---------------------- SQL Statistics ----------------------------------

Rem *************************************************************************

 

drop table WRH$_SQLSTAT

/

drop table WRH$_SQLSTAT_BL

/

drop table WRH$_SQLTEXT

/

drop table WRH$_SQL_SUMMARY

/

drop table WRH$_SQL_PLAN

/

drop table WRH$_SQL_BIND_METADATA

/

drop table WRH$_OPTIMIZER_ENV

/

Rem *************************************************************************

Rem ---------------------- Concurrency Statistics ---------------------------

Rem *************************************************************************

 

drop table WRH$_SYSTEM_EVENT

/

drop table WRH$_SYSTEM_EVENT_BL

/

drop table WRH$_EVENT_NAME

/

drop table WRH$_LATCH_NAME

/

drop table WRH$_BG_EVENT_SUMMARY

/

drop table WRH$_WAITSTAT

/

drop table WRH$_WAITSTAT_BL

/

drop table WRH$_ENQUEUE_STAT

/

drop table WRH$_LATCH

/

drop table WRH$_LATCH_BL

/

drop table WRH$_LATCH_CHILDREN

/

drop table WRH$_LATCH_CHILDREN_BL

/

drop table WRH$_LATCH_PARENT

/

drop table WRH$_LATCH_PARENT_BL

/

drop table WRH$_LATCH_MISSES_SUMMARY

/

drop table WRH$_LATCH_MISSES_SUMMARY_BL

/

 

Rem *************************************************************************

Rem ---------------------- Instance Statistics ------------------------------

Rem *************************************************************************

 

drop table WRH$_LIBRARYCACHE

/

drop table WRH$_DB_CACHE_ADVICE

/

drop table WRH$_DB_CACHE_ADVICE_BL

/

drop table WRH$_BUFFER_POOL_STATISTICS

/

drop table WRH$_SGA

/

drop table WRH$_SGASTAT

/

drop table WRH$_SGASTAT_BL

/

drop table WRH$_PGASTAT

/

drop table WRH$_PROCESS_MEMORY_SUMMARY

/

drop table WRH$_ROWCACHE_SUMMARY

/

drop table WRH$_ROWCACHE_SUMMARY_BL

/

drop table WRH$_RESOURCE_LIMIT

/

drop table WRH$_SHARED_POOL_ADVICE

/

drop table WRH$_STREAMS_POOL_ADVICE

/

drop table WRH$_SQL_WORKAREA_HISTOGRAM

/

drop table WRH$_PGA_TARGET_ADVICE

/

drop table WRH$_INSTANCE_RECOVERY

/

drop table WRH$_JAVA_POOL_ADVICE

/

drop table WRH$_THREAD

/

drop table WRH$_SGA_TARGET_ADVICE

/

 

Rem *************************************************************************

Rem --------------------- General System Statistics -------------------------

Rem *************************************************************************

 

drop table WRH$_SYSSTAT

/

drop table WRH$_SYSSTAT_BL

/

drop table WRH$_SYS_TIME_MODEL

/

drop table WRH$_SYS_TIME_MODEL_BL

/

drop table WRH$_OSSTAT

/

drop table WRH$_OSSTAT_BL

/

drop table WRH$_PARAMETER

/

drop table WRH$_PARAMETER_BL

/

drop table WRH$_STAT_NAME

/

drop table WRH$_OSSTAT_NAME

/

drop table WRH$_PARAMETER_NAME

/

 

Rem *************************************************************************

Rem ------------------------- Undo Statistics -------------------------------

Rem *************************************************************************

 

drop table WRH$_UNDOSTAT

/

 

Rem *************************************************************************

Rem ----------------------- Segment Statistics ------------------------------

Rem *************************************************************************

 

drop table WRH$_SEG_STAT

/

drop table WRH$_SEG_STAT_BL

/

drop table WRH$_SEG_STAT_OBJ

/

 

Rem *************************************************************************

Rem ---------------------- Metrics Tables -----------------------------------

Rem *************************************************************************

drop table WRH$_METRIC_NAME

/

drop table WRH$_SYSMETRIC_HISTORY

/

drop table WRH$_SYSMETRIC_SUMMARY

/

drop table WRH$_SESSMETRIC_HISTORY

/

drop table WRH$_FILEMETRIC_HISTORY

/

drop table WRH$_WAITCLASSMETRIC_HISTORY

/

 

Rem *************************************************************************

Rem ---------------------- Tablespace Statistics ----------------------------

Rem *************************************************************************

drop table WRH$_TABLESPACE_SPACE_USAGE

/

 

Rem *************************************************************************

Rem -------------------------- RAC Statistics -------------------------------

Rem *************************************************************************

 

drop table WRH$_DLM_MISC

/

drop table WRH$_DLM_MISC_BL

/

drop table WRH$_CR_BLOCK_SERVER

/

drop table WRH$_CURRENT_BLOCK_SERVER

/

drop table WRH$_INST_CACHE_TRANSFER

/

drop table WRH$_INST_CACHE_TRANSFER_BL

/

 

Rem *************************************************************************

Rem ---------------------Active Session History -----------------------------

Rem *************************************************************************

drop table  WRH$_ACTIVE_SESSION_HISTORY

/

drop table  WRH$_ACTIVE_SESSION_HISTORY_BL

/

 

Rem *************************************************************************

Rem -------------------------- Tablespace Statistics ------------------------

Rem *************************************************************************

drop table WRH$_TABLESPACE_STAT

/

drop table WRH$_TABLESPACE_STAT_BL

/

 

Rem *************************************************************************

Rem -------------------------- WRH$_LOG Statistics ------------------------

Rem *************************************************************************

drop table WRH$_LOG

/

 

Rem *************************************************************************

Rem -------------------------- MTTR Target Advice ---------------------------

Rem *************************************************************************

drop table WRH$_MTTR_TARGET_ADVICE

/

 

Rem *************************************************************************

Rem ----------------------- Service Statistics ------------------------------

Rem *************************************************************************

 

drop table WRH$_SERVICE_NAME

/

drop table WRH$_SERVICE_STAT

/

drop table WRH$_SERVICE_STAT_BL

/

drop table WRH$_SERVICE_WAIT_CLASS

/

drop table WRH$_SERVICE_WAIT_CLASS_BL

/

 

Rem *************************************************************************

Rem ----------------------- Session Time Stats ------------------------------

Rem *************************************************************************

 

drop table WRH$_SESS_TIME_STATS

/

 

Rem *************************************************************************

Rem ----------------------- STREAMS Stats Table -----------------------------

Rem *************************************************************************

 

drop table WRH$_STREAMS_CAPTURE

/

drop table WRH$_STREAMS_APPLY_SUM

/

drop table WRH$_BUFFERED_QUEUES

/

drop table WRH$_BUFFERED_SUBSCRIBERS

/

drop table WRH$_RULE_SET

/

 

Rem *************************************************************************

Rem -------- Tables For Maintenance Window Auto Tasks Schedules -------------

Rem *************************************************************************

 

drop table WRI$_SCH_CONTROL

/

drop table WRI$_SCH_VOTES

/

 

Rem ************************

Rem Drop the Metadata Tables

Rem ************************

 

drop table WRM$_BASELINE

/

drop table WRM$_WR_CONTROL

/

drop table WRM$_SNAPSHOT

/

drop table WRM$_SNAP_ERROR

/

drop table WRM$_DATABASE_INSTANCE

/

我的结婚照

| 4 Comments

今天和BOSON聊天的时候,他问我是不是mm?

我彻底晕死了,我MSN上的图片是我老婆和我闺女,但这并不代表我是女的,呵呵。

这样,我paste一张我和我老婆的结婚照:

DPP_012_COMPRESS.jpg

利用BBED修改block内数据的一个例子

| 1 Comment

这个例子并没有什么实际意义,只是我在了解block结构的过程中顺便做的一个例子。

用好BBED最关键的就是要了解block的结构,一个0x06block大致有如下结构:

kcbh {
ub1 type_kcbh;
ub1 frmt_kcbh;
ub1 spare1_kcbh;
ub1 spare2_kcbh;
krdba rdba_kcbh;
ub4 bas_kcbh; /* base of SCN */
ub2 wrp_kcbh; /* wrap of SCN */
ub1 seq_kcbh; /* seq# of changes at same scn, KCBH_NLCSEQ */
ub1 flg_kcbh; /* see KCBHFNEW etc below */
ub2 chkval_kcbh;
ub2 spare3_kcbh;
}

 

ktbbh { /* 10201 struct ktbbh block header */

ub1 ktbbhtyp; /* block type */
ub4 ktbbhsid;
kscn ktbbhcsc; /* effective time of last cleanout */
b2 ktbbhict; /* number of itl entries mask 0x00ff*/

ub1 ktbbhflg; /* flags */

ub1 ktbbhfsl; /* free space lock */

krdba ktbbhfnx; /* next block in free list */
}

 

ktbit {

kxid ktbitxid; /* transaction id */
kuba ktbituba; /* undo address for last change */
b2 ktbitflg; /* num of locks in block */
ktbitun_t _ktbitun;
ub4 ktbitbas; /* sys commit num base */
}

 

kdbh {
ub1 kdbhflag; /* FLAGs */
ktno kdbhntab; /* Number of TABles in the table index */
ub2 kdbhnrow; /* Number of ROWs in the row index */
sb2 kdbhfrre; /* first FRee Row index Entry */
sb2 kdbhfsbo; /* Free Space Beginning Offset */
sb2 kdbhfseo; /* Free Space Ending Offset */
b2 kdbhavsp; /* AVailable SPace in the block */
b2 kdbhtosp; /* TOtal Space that will be available */
}

 

kdbt {
b2 kdbtoffs; /* OFFSet in the block from kdbpri */
b2 kdbtnrow; /* Number of Rows in the table */
}

 

kdrh {
ub1 kdrhflag; /* the flag byte for the piece being inserte
ub1 kdrhlock; /* locking itl index */
ub1 kdrhccnt; /* the column count for the row piece */

}

 

SQL_astca>create table dras.t2(c1 number,c2 varchar2(5)) tablespace testtbs;

 

Table created.

 

SQL_astca>insert into dras.t2 values(1,'a'); 

 

1 row created.

 

SQL_astca>insert into dras.t2 values(2,'b');

 

1 row created.

 

SQL_astca>insert into dras.t2 values(3,'c');

 

1 row created.

 

SQL_astca>commit;

 

Commit complete.

 

SQL_astca>select tablespace_name,extent_management,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces where tablespace_name='TESTTBS';

 

TABLESPACE_NAME                EXTENT_MAN SEGMEN

------------------------------ ---------- ------

TESTTBS                        LOCAL      MANUAL

 

SQL_astca>alter system checkpoint;

 

System altered.

 

SQL_astca>select FILE_ID,RELATIVE_FNO,BLOCK_ID from dba_extents where owner='DRAS' and segment_name='T2';

 

   FILE_ID RELATIVE_FNO   BLOCK_ID

---------- ------------ ----------

       133          133         33

 

MSSM段头的下一个block就是数据块:

SQL_astca>ALTER SYSTEM DUMP DATAFILE 133 BLOCK 34;

 

System altered.

 

SQL_astca>oradebug setmypid

Statement processed.

 

SQL_astca>oradebug tracefile_name

/cadrasu01/app/oracle/admin/astca/udump/astca_ora_1060992.trc

 

上述trace file中有如下内容:

Start dump data blocks tsn: 84 file#: 133 minblk 34 maxblk 34

buffer tsn: 84 rdba: 0x21400022 (133/34)

scn: 0x0008.a9e7d1b7 seq: 0x01 flg: 0x06 tail: 0xd1b70601

frmt: 0x02 chkval: 0x39da type: 0x06=trans data

Block header dump:  0x21400022

 Object id on Block? Y

 seg/obj: 0x1505c  csc: 0x08.a9e7d1aa  itc: 2  flg: O  typ: 1 - DATA

     fsl: 0  fnx: 0x0 ver: 0x01

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x000a.014.0000c212  0x12c0001b.2c44.2f  --U-    3  fsc 0x0000.a9e7d1b7

0x02   0x0000.000.00000000  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

 

data_block_dump,data header at 0x11027405c

===============

tsiz: 0x1fa0

hsiz: 0x18

pbl: 0x11027405c

bdba: 0x21400022

     76543210

flag=--------

ntab=1

nrow=3

frre=-1

fsbo=0x18

fseo=0x1f88

avsp=0x1f6d

tosp=0x1f6d

0xe:pti[0]      nrow=3  offs=0

0x12:pri[0]     offs=0x1f98

0x14:pri[1]     offs=0x1f90

0x16:pri[2]     offs=0x1f88

block_row_dump:

tab 0, row 0, @0x1f98

tl: 8 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 2]  c1 02

col  1: [ 1]  61

tab 0, row 1, @0x1f90

tl: 8 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 2]  c1 03

col  1: [ 1]  62

tab 0, row 2, @0x1f88

tl: 8 fb: --H-FL-- lb: 0x1  cc: 2

col  0: [ 2]  c1 04

col  1: [ 1]  63

end_of_block_dump

End dump data blocks tsn: 84 file#: 133 minblk 34 maxblk 34

从上面可以看到,这里第二行的offset0x1f90,这是一个相对地址,需要加上一个BASEBASE的计算方法为:

对于ASSM76+itc-1)*24

对于MSSM68+itc-1)*24

所以我们这里BBED实际用到的offset0x1f90+68+(2-1)*24=8172

 

好了,我们的准备工作已经就绪。

SQL_astca>select * from dras.t2;

 

        C1 C2

---------- -----

         1 a

         2 b

         3 c

 

现在我们来用BBED把上述第二条记录的C2的值由b改成d

$ bbed parfile=par.bbd

Password:

 

BBED: Release 2.0.0.0.0 - Limited Production on Thu Apr 2 11:25:05 2009

 

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

 

************* !!! For Oracle Internal Use only !!! ***************

 

BBED> set file 133

        FILE#           133

 

BBED> set block 34

        BLOCK#          34

 

BBED> set offset 8172

        OFFSET          8172

 

BBED> dump

 File: /dras20/astca/test01.dbf (133)

 Block: 34               Offsets: 8172 to 8191           Dba:0x21400022

------------------------------------------------------------------------

 2c010202 c1030162 2c010202 c1020161 d1b70601

 

 <32 bytes per line>

 

这里的2c0102是行头,就是我上面提到的kdrh,这里2c表示是行头的开始,01表示对应1ITL02表示这行有2个字段的值。

后面的02 c1030162就是我要修改的内容,02表示第一个字段的长度为2byte,后面紧跟的c103就是这两个byte的具体值;后面紧跟着的01表示第二个字段的长度为1byte,后面紧跟的62就是这个byte的具体值。

 

我们现在是想把t2中第二条记录的C2字段的值由b改成dd所对应的存储格式为:

SQL> select dump('d',16) from dual;

 

DUMP('D',16)

----------------

Typ=96 Len=1: 64

 

所以这里我们只需要把62改成64就可以了。

BBED> set offset 8179

        OFFSET          8179

 

BBED> dump

 File: /dras20/astca/test01.dbf (133)

 Block: 34               Offsets: 8179 to 8191           Dba:0x21400022

------------------------------------------------------------------------

 622c0102 02c10201 61d1b706 01

 

 <32 bytes per line>

 

BBED> modify /x 0x64

Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y

 File: /dras20/astca/test01.dbf (133)

 Block: 34               Offsets: 8179 to 8191           Dba:0x21400022

------------------------------------------------------------------------

 642c0102 02c10201 61d1b706 01

 

 <32 bytes per line>

 

BBED> sum apply

Check value for File 133, Block 34:

current = 0x39dc, required = 0x39dc

 

好了,现在我们已经改完了,最后我们来看一下改过之后的效果:

BBED> exit

 

$ sqlplus '/ as sysdba';

 

SQL*Plus: Release 9.2.0.6.0 - Production on Thu Apr 2 11:53:11 2009

 

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

 

Connected to an idle instance.

 

 

SQL_astca>startup

ORACLE instance started.

 

Total System Global Area  824150304 bytes