首页 > 开发 > 综合 > 正文

数据文件internal的内部结构分析

2024-07-21 02:35:32
字体:
来源:转载
供稿:网友

  众所周知,Oracle的数据是储存在数据文件中的。那么Oracle是以什么格式来储存数据的呢?相信大家都对其内部结构很感爱好。这篇文章就帮大家来了解Oracle数据文件的内部结构。
  我们知道数据库储存的最小单位是数据块,其他如extent,segment,tablespace等都是由数据块组成,所以我们就从数据块的结构来分析。
  典型的数据块由3部分构成:
  1. 头信息区 
  这个区包括数据块的地址,数据块类型,检查点信息,scn信息,数据块版本号等。(以下是其大概的构造,稍后会做解释)
  ―――――――――――――――――――――――――――
  *** 2003-06-10 10:05:10.296
  Start dump data blocks tsn: 2 file#: 3 minblk 13107 maxblk 13107
  buffer tsn: 2 rdba: 0x00c03333 (3/13107)
  scn: 0x0000.00105d22 seq: 0x05 flg: 0x00 tail: 0x5d220605
  frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
  Block header dump: 0x00c03333
   Object id on Block? Y
   seg/obj: 0x6493 csc: 0x00.105d22 itc: 1 flg: O typ: 1 - DATA
  fsl: 0 fnx: 0x0 ver: 0x01
  ――――――――――――――――――――――――――――
  2. 事务列表区
  事务列表去包括了在这个数据块内的事务,也就是我们知道的ITL(interested transaction list),从中我们可以知道XID(transaction id),UBA(undo block address)等信息(以下是其大概的构造,稍后会做解释)
  ---------------------------------------------------------------------------------
  Itl      Xid         Uba     Flag Lck    Scn/Fsc
  0x01  xid: 0x0009.012.00000002  uba: 0x00800c84.0000.25 ----  1 fsc 0x0000.00000000
   
  ---------------------------------------------------------------------------------
  3. 数据区,尾区
  数据区顾名思义是真正存储数据的地方,在这里我们可以看到每一条记录。至于尾区,这里储存着数据块的版本号,与数据头信息区的版本号相对应,可以用来确定数据块前后是否一致。
  (以下是其大概的构造,稍后会做解释)
  ―――――――――――――――――――――――――――
  data_block_dump
  ===============
  tsiz: 0x1fb8
  hsiz: 0x14
  pbl: 0x0f3f7444
  bdba: 0x00c03333
  flag=-----------
  ntab=1
  nrow=1
  frre=-1
  fsbo=0x14
  fSEO=0x1fb2
  avsp=0x1f9b
  tosp=0x1f9b
  0xe:pti[0] nrow=1 offs=0
  0x12:PRi[0] offs=0x1fb2
  block_row_dump:
  tab 0, row 0, @0x1fb2
  tl: 6 fb: --H-FL-- lb: 0x1 cc: 1
  col 0: [ 2] c1 02(数据就在这里)
  end_of_block_dump
  End dump data blocks tsn: 2 file#: 3 minblk 13107 maxblk 13107
  ―――――――――――――――――――――――――――
  下面我们来做一个完整的实验,首先创建一个新的表空间
   
  SQL> create tablespace testblock datafile 'd:/oracle/oradata/test/testblock.ora'
   size 100m;
   
  表空间已创建。
   
  创建一个新用户并指定默认表空间为testblock,临时表空间为temp
   
  SQL> create user testblock identified by testblock default tablespace testblock
  temporary tablespace temp;
   
  用户已创建
  SQL> grant create session to testblock;
   
  授权成功。
  SQL> grant resource to testblock;
   
  授权成功。

   
  SQL> connect testblock/testblock@test
  已连接。
  SQL> create table testblock (a number);
   
  表已创建。
  SQL> insert into testblock values(1);
   
  已创建 1 行。
   
  SQL> insert into testblock values(2);
   
  已创建 1 行。
  SQL> commit;
   
  提交完成。
  SQL> connect internal/oracle@test
  已连接。
  SQL> select header_file,header_block from dba_segments where segment_name='TESTBLOCK';
   
  HEADER_FILE HEADER_BLOCK
  
  Start dump data blocks tsn: 8 file#: 11 minblk 2 maxblk 2
  buffer tsn: 8 rdba: 0x02c00002 (11/2)
  scn: 0x0000.001148eb seq: 0x01 flg: 0x00 tail: 0x48eb1001
  frmt: 0x02 chkval: 0x0000 type: 0x10=DATA SEGMENT HEADER - UNLIMITED
   
    Extent Control Header
    -----------------------------------------------------------------
    Extent Header:: spare1: 0   space2: 0   #extents: 1   #blocks: 4   
            last map 0x00000000 #maps: 0   offset: 4128 
      Highwater:: 0x02c00004 ext#: 0   blk#: 1   ext size: 4   
    #blocks in seg. hdr's freelists: 1   
    #blocks below: 1   
    mapblk 0x00000000 offset: 0   
            Unlocked
     Map Header:: next 0x00000000 #extents: 1  obj#: 25755 flag: 0x40000000
    Extent Map
    -----------------------------------------------------------------
    0x02c00003 length: 4   
    
    nfl = 1, nfb = 1 typ = 1 nxf = 0
    SEG LST:: flg: USED  lhd: 0x02c00003 ltl: 0x02c00003 
  End dump data blocks tsn: 8 file#: 11 minblk 2 maxblk 2
  ――――――――――――――――――――――――――――――――――
  这里我们看到表空间号是tsn: 8,数据文件号是file#: 11,相对数据块地址是rdba: 0x02c00002 (11/2),SCN为scn: 0x0000.001148eb(SCN Base=0011,SCN Wrap=48eb),尾区版本号为tail: 0x48eb1001(tail=SCN Wrap: 48eb + type: 0x10+ seq: 0x01),由于这个块是整个Segment的头,所以它还包含整个Segment的一些存储信息,比如extent数,block数,高水位地址Highwater:: 0x02c00004,自由列表信息hdr's freelists: 1等等。假如才用本地治理表空间,则此块的存储信息通过位图方式治理。
  真正的数据是储存在下一个块也就是0x02c00002+1=0x02c00003,我们来看看究竟。
  ――――――――――――――――――――――――――――――――――
  *** 2003-06-12 12:00:41.781
  Start dump data blocks tsn: 8 file#: 11 minblk 3 maxblk 3
  buffer tsn: 8 rdba: 0x02c00003 (11/3)
  scn: 0x0000.001148ee seq: 0x01 flg: 0x02 tail: 0x48ee0601
  frmt: 0x02 chkval: 0x0000 type: 0x06=trans data
   
  Block header dump: 0x02c00003
   Object id on Block? Y
   seg/obj: 0x649b csc: 0x00.1148eb itc: 1 flg: O typ: 1 - DATA
     fsl: 0 fnx: 0x0 ver: 0x01
   
   Itl      Xid         Uba     Flag Lck    Scn/Fsc
  0x01  xid: 0x0006.03f.000000da  uba: 0x00800ad2.00ae.04 --U-  2 fsc 0x0000.001148ee
   
  data_block_dump
  ===============
  tsiz: 0x1fb8
  hsiz: 0x16
  pbl: 0x0ec77444
  bdba: 0x02c00003
  flag=-----------
  ntab=1
  nrow=2
  frre=-1
  fsbo=0x16
  fseo=0x1fac
  avsp=0x1f90
  tosp=0x1f90
  0xe:pti[0] nrow=2 offs=0
  0x12:pri[0] offs=0x1fb2
  0x14:pri[1] offs=0x1fac
  block_row_dump:
  tab 0, row 0, @0x1fb2
  tl: 6 fb: --H-FL-- lb: 0x1 cc: 1
  col 0: [ 2] c1 02
  tab 0, row 1, @0x1fac
  tl: 6 fb: --H-FL-- lb: 0x1 cc: 1
  col 0: [ 2] c1 03
  end_of_block_dump
  End dump data blocks tsn: 8 file#: 11 minblk 3 maxblk 3
  ――――――――――――――――――――――――――――――――――
  谜团解开了,ITL,数据都呈现出来了,开始分析!
  Block header dump: 0x02c00003
   Object id on Block? Y
   seg/obj: 0x649b csc: 0x00.1148eb itc: 1 flg: O typ: 1 - DATA
     fsl: 0 fnx: 0x0 ver: 0x01
   
  数据块地址正是0x02c00002+1=0x02c00003
  segment/object id为0x649b,转成10进制为25755,可以由obj#表中得知
  SQL> select obj# from sys.obj$ where name='TESTBLOCK';
   
      OBJ#
  ----------
     25755
   
  csc(SCN at last Block CleanOut): 0x00.1148eb表示最后一次块清除(Block CleanOut)时候的SCN,关于块清除的概念可以查阅Thomas Kyte 著的”eXPert one by one Oracle”。

   
  itc: 1 表示Number of itl slots
   
  flg: O 表示此块被放置在自由列表(freelist)中
   
  typ: 1 – DATA,类型1表示数据,类

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表