Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1705736
  • 博文数量: 136
  • 博客积分: 10021
  • 博客等级: 上将
  • 技术积分: 3261
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-22 11:26
文章分类

全部博文(136)

文章存档

2010年(1)

2009年(26)

2008年(109)

我的朋友

分类: Oracle

2008-05-30 13:42:19

 创建测试表:

 

SQL> create table test_block as select * from dba_objects where 1 = 0;

 

表已创建。

 

SQL> select OWNER, SEGMENT_NAME, HEADER_FILE, HEADER_BLOCK, BLOCKS, EXTENTS, FREELISTS
  2    from dba_segments
  3   where segment_name = 'TEST_BLOCK';

 

SEGMENT_NAME  HEADER_FILE HEADER_BLOCK  BLOCKS   EXTENTS
------------- ----------- ------------ ------- ---------
TEST_BLOCK             11          193       8         1

 

 

SQL> select EXTENT_ID, FILE_ID, BLOCK_ID, BYTES, BLOCKS, RELATIVE_FNO
  2    from dba_extents
  3   where segment_name = 'TEST_BLOCK';

 

 EXTENT_ID    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
---------- ---------- ---------- ---------- ---------- ------------
         0         11        193      65536          8           11

 

SQL> insert into test_block select * from dba_objects where rownum < 12;

 

已创建 11 行。

 

SQL> select dbms_rowid.rowid_relative_fno(rowid) file#,
  2         dbms_rowid.rowid_block_number(rowid) block#
  3    from test_block;

 

     FILE#     BLOCK#
---------- ----------
        11        194
        11        194
        11        194
        11        194
        11        194
        11        194
        11        194
        11        194
        11        194
        11        194

        11        194

 

已选择11行。

 

 

数据插入到了第194块。那么,被称为 HEADER_BLOCK 的第193块是做什么的呢?
 

SQL> alter system dump datafile 11 block 193;

 

系统已更改。

 

SQL> select p.value||'\'||i.instance_name||'_ora_'||p.spid||'.trc' trace_path
  2  from v$process p, v$instance i, v$parameter p
  3  where p.addr = (
  4  select paddr from v$session
  5  where sid = ( select sid from v$mystat where rownum = 1)
  6  )
  7  and p.name='user_dump_dest';

 

TRACE_PATH
-------------------------------------------------------------------
D:\oracle\admin\ora\udump\orasid_ora_3376.trc

 

 

我们看看193块中的信息:
 

*** 2008-05-30 11:24:07.000
Start dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193
buffer tsn: 11 rdba: 0x02c000c1 (11/193)
scn: 0x0000.1bf3af2f seq: 0x01 flg: 0x00 tail: 0xaf2f1001
frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER - UNLIMITED
  Extent Control Header
  -----------------------------------------------------------------
  Extent Header:: spare1: 0      spare2: 0      #extents: 1      #blocks: 7    
                  last map  0x00000000  #maps: 0      offset: 4128 
      Highwater::  0x02c000c3  ext#: 0      blk#: 1      ext size: 7    
  #blocks in seg. hdr's freelists: 1    
  #blocks below: 1    
  mapblk  0x00000000  offset: 0    
                   Unlocked
     Map Header:: next  0x00000000  #extents: 1    obj#: 31997  flag: 0x40000000
  Extent Map
  -----------------------------------------------------------------
   0x02c000c2  length: 7    
 
  nfl = 1, nfb = 1 typ = 1 nxf = 0 ccnt = 1
  SEG LST:: flg: USED   lhd: 0x02c000c2 ltl: 0x02c000c2
End dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

 

从 type 中,可以看到第一个块是数据段的头信息。我们看一下这里的高水位标识(Highwater):
 

SQL> select to_number('c3', 'xxxxxxxxxx') Highwater
  2    from dual;

 

 HIGHWATER
----------
       195

 
现在高水位是在195块,我再插入一条数据看看:

 

SQL> insert into test_block select * from dba_objects where rownum = 1;

 

已创建 1 行。

 

SQL> select dbms_rowid.rowid_block_number(rowid) block# from test_block;

 

    BLOCK#

----------

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

 

已选择12行。

 

SQL> rollback;

 

回退已完成。

 

SQL> insert/*+ append */ into test_block select * from dba_objects where rownum = 1;

 

已创建 1 行。

 

SQL> select dbms_rowid.rowid_block_number(rowid) block# from test_block;

select dbms_rowid.rowid_block_number(rowid) block# from test_block

                                                        *

ERROR 位于第 1 :

ORA-12838: 无法在并行模式下修改之后读/修改对象

 

SQL> alter system dump datafile 11 block 193;

 

系统已更改。

 

此时193块信息如下: 

 

*** 2008-05-30 11:48:21.000

*** SESSION ID:(11.7) 2008-05-30 11:48:21.000

Start dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

buffer tsn: 11 rdba: 0x02c000c1 (11/193)

scn: 0x0000.1bf3af2f seq: 0x01 flg: 0x04 tail: 0xaf2f1001

frmt: 0x02 chkval: 0x2339 type: 0x10=DATA SEGMENT HEADER - UNLIMITED

  Extent Control Header

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

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

                  last map  0x00000000  #maps: 0      offset: 4128 

      Highwater::  0x02c000c3  ext#: 0      blk#: 1      ext size: 7    

  #blocks in seg. hdr's freelists: 1    

  #blocks below: 1    

  mapblk  0x00000000  offset: 0    

                   Unlocked

     Map Header:: next  0x00000000  #extents: 1    obj#: 31997  flag: 0x40000000

  Extent Map

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

   0x02c000c2  length: 7    

 

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

  SEG LST:: flg: USED   lhd: 0x02c000c2 ltl: 0x02c000c2

End dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

 

append 一条数据后,在提交前高水位并没有发生变化,但此时所插入的数据已经保存在第195块了。此时第195块信息如下:

 

*** 2008-05-30 11:55:44.000

Start dump data blocks tsn: 11 file#: 11 minblk 195 maxblk 195

buffer tsn: 11 rdba: 0x02c000c3 (11/195)

scn: 0x0000.1bf3c156 seq: 0x02 flg: 0x04 tail: 0xc1560602

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

Block header dump:  0x02c000c3

 Object id on Block? Y

 seg/obj: 0x7cfd  csc: 0x00.1bf3c155  itc: 3  flg: -  typ: 1 - DATA

     fsl: 0  fnx: 0x0 ver: 0x01

 

 Itl           Xid                  Uba         Flag  Lck        Scn/Fsc

0x01   0x0009.025.00005240  0x00000000.0000.00  ----    0  fsc 0x0000.00000000

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

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

 

data_block_dump,data header at 0x3051074

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

tsiz: 0x1f88

hsiz: 0x14

pbl: 0x03051074

bdba: 0x02c000c3

     76543210

flag=--------

ntab=1

nrow=1

frre=-1

fsbo=0x14

fseo=0x1f28

avsp=0x1f14

tosp=0x1f14

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

0x12:pri[0]     offs=0x1f28

block_row_dump:

tab 0, row 0, @0x1f28

tl: 96 fb: --H-FL-- lb: 0x0  cc: 13

col  0: [ 3]  53 59 53

col  1: [22]

 2f 31 30 30 35 62 64 33 30 5f 4c 6e 6b 64 43 6f 6e 73 74 61 6e 74

col  2: *NULL*

col  3: [ 4]  c3 02 49 57

col  4: *NULL*

col  5: [10]  4a 41 56 41 20 43 4c 41 53 53

col  6: [ 7]  78 6b 08 1f 18 28 1d

col  7: [ 7]  78 6b 08 1f 18 28 1d

col  8: [19]  32 30 30 37 2d 30 38 2d 33 31 3a 32 33 3a 33 39 3a 32 38

col  9: [ 5]  56 41 4c 49 44

col 10: [ 1]  4e

col 11: [ 1]  4e

col 12: [ 1]  4e

end_of_block_dump

End dump data blocks tsn: 11 file#: 11 minblk 195 maxblk 195

 

 我们继续刚才的操作,提交数据,看此时数据在数据块中的分布:

 

SQL> commit;

 

提交完成。

 

SQL> select dbms_rowid.rowid_block_number(rowid) block# from test_block;

 

    BLOCK#

----------

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       195

 

已选择12行。

 
看看此时的高水位:

 

SQL> alter system dump datafile 11 block 193;

 

系统已更改。

 

193块的内容如下:

 

*** 2008-05-30 13:13:54.000

Start dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

buffer tsn: 11 rdba: 0x02c000c1 (11/193)

scn: 0x0000.1bf3c7bf seq: 0x01 flg: 0x04 tail: 0xc7bf1001

frmt: 0x02 chkval: 0x233e type: 0x10=DATA SEGMENT HEADER - UNLIMITED

  Extent Control Header

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

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

                  last map  0x00000000  #maps: 0      offset: 4128 

      Highwater::  0x02c000c4  ext#: 0      blk#: 2      ext size: 7    

  #blocks in seg. hdr's freelists: 1    

  #blocks below: 2    

  mapblk  0x00000000  offset: 0    

                   Unlocked

     Map Header:: next  0x00000000  #extents: 1    obj#: 31997  flag: 0x40000000

  Extent Map

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

   0x02c000c2  length: 7    

 

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

  SEG LST:: flg: USED   lhd: 0x02c000c2 ltl: 0x02c000c2

End dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

  

 

SQL> select to_number('c4', 'xxx') from dual;

 

TO_NUMBER('C4','XXX')

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

                  196

 

提交后,高水位移动到了第196块。

 

 

使用直接路径插入时,会将数据插入到高水位以上的数据块中,不会扫描 freelist 中的空闲块。此时我再正常插入一条数据呢?应该插入到 194 块,因为此时 194 块还没有装满。测试一下:

 

SQL> insert into test_block select * from dba_objects where rownum = 1;

 

已创建 1 行。

 

SQL> select dbms_rowid.rowid_block_number(rowid) block# from test_block;

 

    BLOCK#

----------

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       195

 

已选择13行。

 

SQL> rollback;

 

回退已完成。

 

如果直接路径插入后,再回滚呢?高水位会发生什么样的变化?

 

SQL> insert/*+ append */ into test_block select * from dba_objects where rownum = 1;

 

已创建 1 行。

 

SQL> rollback;

 

回退已完成。

 

SQL> alter system dump datafile 11 block 193;

 

系统已更改。

 

 

*** 2008-05-30 13:21:06.000

Start dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

buffer tsn: 11 rdba: 0x02c000c1 (11/193)

scn: 0x0000.1bf3c7bf seq: 0x01 flg: 0x04 tail: 0xc7bf1001

frmt: 0x02 chkval: 0x233e type: 0x10=DATA SEGMENT HEADER - UNLIMITED

  Extent Control Header

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

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

                  last map  0x00000000  #maps: 0      offset: 4128 

      Highwater::  0x02c000c4  ext#: 0      blk#: 2      ext size: 7    

  #blocks in seg. hdr's freelists: 1    

  #blocks below: 2    

  mapblk  0x00000000  offset: 0    

                   Unlocked

     Map Header:: next  0x00000000  #extents: 1    obj#: 31997  flag: 0x40000000

  Extent Map

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

   0x02c000c2  length: 7    

 

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

  SEG LST:: flg: USED   lhd: 0x02c000c2 ltl: 0x02c000c2

End dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

 
高水位没有发生变化,仍然在第196块。而 append 一条数据后提交,高水位会再移动到第197块:
 

SQL> insert/*+ append */ into test_block select * from dba_objects where rownum = 1;

 

已创建 1 行。

 

SQL> commit;

 

提交完成。

 

SQL> alter system dump datafile 11 block 193;

 

系统已更改。

 

 

*** 2008-05-30 13:30:30.000

Start dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

buffer tsn: 11 rdba: 0x02c000c1 (11/193)

scn: 0x0000.1bf4000f seq: 0x02 flg: 0x00 tail: 0x000f1002

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

  Extent Control Header

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

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

                  last map  0x00000000  #maps: 0      offset: 4128 

      Highwater::  0x02c000c5  ext#: 0      blk#: 3      ext size: 7    

  #blocks in seg. hdr's freelists: 1    

  #blocks below: 3    

  mapblk  0x00000000  offset: 0    

      Disk Lock:: Locked by xid:  0x0001.001.000051ed

     Map Header:: next  0x00000000  #extents: 1    obj#: 31997  flag: 0x40000000

  Extent Map

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

   0x02c000c2  length: 7    

 

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

  SEG LST:: flg: USED   lhd: 0x02c000c2 ltl: 0x02c000c2

End dump data blocks tsn: 11 file#: 11 minblk 193 maxblk 193

 

看看此时表 test_block 的数据分布:

 

SQL> select dbms_rowid.rowid_block_number(rowid) block# from test_block;

 

    BLOCK#

----------

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       194

       195

       196

 

已选择13行。

 

小结:
1. append 数据时,会从 Highwater 之后的数据块开始直接插入数据。
2. append 数据后,在提交之前不会升高 Highwater 的位置,提交后才升高 Highwater。
阅读(2329) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~