ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 关于Oracle块的一些总结

关于Oracle块的一些总结

原创 Linux操作系统 作者:regonly1 时间:2009-09-15 15:35:14 0 删除 编辑

以下关于Oracle的一些描述都是个人总结而成,由于个人知识的限制,在本地管理表空间部分及dump数据块的部分的描述在某些方面会不准确,与实际情况不符合。
Oracle的表空间由若干的数据文件(OS级)所组成。一个表空间最多可以有1024个数据文件组成。
数据文件的大小受块大小的限制可以有不同的大小。假设一个块大小为8k。
8i后的rowid组成结构如下:OOOOOO FFF BBBBBB RRR
共有10个字节组成(1字节×10=8bit×10=80bit)
OOOOOO是data_object_id(32bit)
FFF是rfile#(10bit)
BBBBBB是block_id(22bit)
RRR是row_id(16bit)
因此可以看到对应的rowid可以表示的最大文件数为2^10=1024,每个文件可表示的最大的block数为2^22=4194304 假设每个block size=8k,则有8*1024*2^22/1024/1024/1024 = 32G,即如果block的大小为8k,则一个数据文件的最大大小为32G。由于一个表空间最多有1024个数据文件,则一个块大小为8k的表空间最大可以为32T。
计算公式:
select "block_size(K)", "block_size(K)" * block_num / 1024 / 1024 "file_size(G)"
  from (select power(2, rownum) "block_size(K)", power(2, 22) block_num
          from dual
        connect by rownum <= 4)
以上说明的都只是smallfile tablespace, Oracle 10g开始还支持一种bigfile tablespace。这种表空间只能有一个数据文件,该数据文件最大可以达到4G个block大小。
理论上的 BFT 可以达到下面所列的值:
数据块大小(单位:K) BFT 最大值(单位:T)
2k                      8T
4k                      16T
8k                      32T
16k                     64T
32k                     128T
默认情况下创建的表空间都是smallfile表空间。要创建大文件表空间,则可以通过指定bigfile参数来指定。
查看当前表空间的默认创建类型,可以通过下面查询来查看:
select * from database_properties dp where dp.property_name = 'DEFAULT_TBS_TYPE'

下面介绍表空间的逻辑组成
一个表空间在逻辑上是由若干个segment组成的,每个segment都对应一个object。但是并不是每个object都对应一个segment,如果function、procedure等。每个segment由若干extent组成,extent是Oracle分配空间的最小单位,当segment需要扩展时,oracle就会为该segment分配新的extent。分配extent的大小由创建表空间时uniform. size参数指定。如果指定,则每次按照指定的大小进行扩展。如果不指定,则以pctincrease参数指定的比例逐级递增。每个extent都由若干个块组成,块的多少取决于分配的extent的大小。假设一个extent为1m,则含有的block数为:1*1024/8=128个。
本地管理表空间(local management tablespace)下,每个segment的前3个块都用于存放该段的存储信息。每个数据文件的前8个块都是存放所有段的信息:
创建表空间:
create tablespace mytbs datafile 'E:\oracle\oradata\lyon\mytbs01.dbf'
size 10m uniform. size 1m extent management local segment space management auto;
在指定的表空间上创建测试表:
create table mytb(x varchar2(10), y varchar2(30)) tablespace mytbs nologging;
创建测试数据:
insert into mytb(x, y)
select 'This', dump('This',16) from dual union all
select 'is', dump('is',16) from dual union all
select 'a', dump('a',16) from dual union all
select 'dump', dump('dump',16) from dual union all
select 'test', dump('test',16) from dual union all
select '!', dump('!',16) from dual;
commit;
查看该表的extent信息:
select segment_name, tablespace_name, file_id, block_id, bytes, blocks
 from dba_extents de
where de.segment_name = 'MYTB';
lyon@ORCL> select segment_name, tablespace_name, file_id, block_id, bytes, blocks
  2   from dba_extents de
  3  where de.segment_name = 'MYTB';

SEGMENT_NAME                   TABLESPACE_NAME                   FILE_ID   BLOCK_ID      BYTES     BLOCKS
------------------------------ ------------------------------ ---------- ---------- ---------- ----------
MYTB                           MYTBS                                  21          9    1048576        128

已用时间:  00: 00: 00.32

可以看到block_id=9,且共有128个块。
查看当前实际数据所在的块:
customer21@ORCL> select dbms_rowid.rowid_relative_fno(rowid) rfile#,
  2         dbms_rowid.rowid_block_number(rowid) blknumber,
  3         dbms_rowid.rowid_row_number(rowid) rownumber
  4    from mytb;

    RFILE#  BLKNUMBER  ROWNUMBER
---------- ---------- ----------
        21         35          0
        21         35          1
        21         35          2
        21         35          3
        21         35          4
        21         35          5

已选择6行。

已用时间:  00: 00: 00.03
可以看到实际数据开始使用的块为35。
有两个问题:
1、新的表空间下创建的对象,实际object开始的块的id为9,前面的8个块呢?
2、该对象(表mytb),在表空间中开始分配的block_id=9,但是为何初始数据所在的块为35?
第一个问题比较容易回答,这8个块是本地管理表空间(LMT)情况下,用于存放对象信息的。
第二个问题实际相差了35-9=26个块。除去两端的块,还有24个块去哪里了?

ORACLE中空闲数据块可以通过FREELIST或BITMAP来维护,它们位于一个段的头部用来标识当前段中哪些数据块可以进行INSERT。在本地管理表空间中ORACLE自动管理分配给段的区的大小,只在本地管理的表空间中才能选用段自动管理,采用自动段空间管理的本地管理表空间中的段中的空闲数据块的信息就存放在段中某些区的头部,使用位图来管理(最普通的情况是一个段的第一个区的第一个块为FIRST LEVEL BITMAP BLOCK,第二个块为SECOND LEVEL BITMAP BLOCK,第三个块为PAGETABLE SEGMENT HEADER 
也就是说,每个段的第一个区的前面三个块都是存放空闲数据库信息的。那还剩下24-3=21个块。
alter system dump datafile 21 block min 12 block max 34
alter system dump datafile 21 block 35
dump 35号块,取出一段如下:
col  0: [ 4]  54 68 69 73
这个与
select * from mytb
Typ=96 Len=4: 54,68,69,73的结果是一样的。
说明了这个值的长度为4,每个字节对应的acsii码是54,68,69,73(16进制),转换为字符即为:This。
drop index idx_mytb_x
create index idx_mytb_x on mytb(x) tablespace mytbs nologging;
select * from dba_extents de where de.segment_name = 'IDX_MYTB_X'
alter system dump datafile 21 block 141
索引dump信息
row#0[8025] flag: ------, lock: 0, len=11
col 0; len 1; (1):  21
col 1; len 6; (6):  05 40 00 23 00 05
row#1[8011] flag: ------, lock: 0, len=14
col 0; len 4; (4):  54 68 69 73
col 1; len 6; (6):  05 40 00 23 00 00
row#2[8000] flag: ------, lock: 0, len=11
col 0; len 1; (1):  61
col 1; len 6; (6):  05 40 00 23 00 02
row#3[7986] flag: ------, lock: 0, len=14
col 0; len 4; (4):  64 75 6d 70
col 1; len 6; (6):  05 40 00 23 00 03
row#4[7974] flag: ------, lock: 0, len=12
col 0; len 2; (2):  69 73
col 1; len 6; (6):  05 40 00 23 00 01
row#5[7960] flag: ------, lock: 0, len=14
col 0; len 4; (4):  74 65 73 74
col 1; len 6; (6):  05 40 00 23 00 04

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12932950/viewspace-614688/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-05-10

  • 博文量
    257
  • 访问量
    1022012