ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 本地管理表空间(zt)

本地管理表空间(zt)

原创 Linux操作系统 作者:tolywang 时间:2005-02-17 00:00:00 0 删除 编辑

http://epub.itpub.net/9/6.htm 

一、概述

1、理解本地管理表空间的由来

2、理解什么是字典管理表空间及工作原理

3、理解本地管理表空间的优势(为什么要使用本地管理表空间)

4、理解本地管理表空间的内部结构

5、理解字典管理表空间与本地管理表空间的转换



二、名词解释与约定

表空间(Tablespace——为数据库提供使用空间的逻辑结构,其对应物理结构是数据文件,一个表空间可以包含多个数据文件。

本地管理表空间(Locally Managed Tablespace简称LMT——8i以后出现的一种新的表空间的管理模式,通过本地位图来管理表空间的空间使用。

字典管理表空间(Dictionary-Managed Tablespace简称DMT——8i以前包括以后都还可以使用的一种表空间管理模式,通过数据字典管理表空间的空间使用。

段(Segment——数据库一种逻辑结构,如表段,索引段,回滚段等,段存在于表空间中,并对应一定的存储空间。

区间,可以简称区(Extent——段的存储可以分成一个或多个区间,每个区间占用一定数量的数据块(block),在本地管理的表空间中,表空间的Extent就对应段的Extent

块(Block——数据库最小的存储单位,在本文中Block的大小约定为8192字节。

位(Bit——本地管理表空间的空间管理单位,一个位可能等于一个区间,也可能多个位组成一个区间。


三、本地管理表空间的由来

Oracle8I的版本中,Oracle推出了一种全新的表空间管理方式:本地化管理的表空间。所谓本地化管理,就是指Oracle不再利用数据字典表来记录Oracle表空间里面的区的使用状况,而是在每个表空间的数据文件的头部加入了一个位图区,在其中记录每个区的使用状况。每当一个区被使用,或者被释放以供重新使用时,Oracle都会更新数据文件头部的这个记录,反映这个变化。本地化管理的表空间的创建过程:

语法:CREATE TABLESPACE 表空间名字
          DATAFILE '数据文件详细信息'
          
[EXTENT MANAGEMENT { LOCAL
          {AUTOALLOCATE | UNIFORM [SIZE INTETER [K|M] ] } } ]

关键字EXTENT MANAGEMENT LOCAL 指定这是一个本地化管理的表空间。对于系统表空间,只能在创建数据库的时候指定EXTENT MANGEMENT LOCAL,因为它是数据库创建时建立的第一个表空间。

8i中,字典管理还是默认的管理方式,当选择了LOCAL关键字,即表明这是一个本地管理的表空间。当然还可以继续选择更细的管理方式:是AUTOALLOCATE 还是 UNIFORM.。若为AUTOALLOCATE,则表明让Oracle来决定区块的使用办法;若选择了UNIFORM,则还可以详细指定每个区块的大小,若不加指定,则为每个区使用1M大小。

Oracle之所以推出了这种新的表空间管理方法,让我们来看一下这种表空间组织方法的优点:

1. 本地化管理的表空间避免了递归的空间管理操作。而这种情况在数据字典管理的表空间是经常出现的,当表空间里的区的使用状况发生改变时,数据字典的表的信息发生改变,从而同时也使用了在系统表空间里的回滚段。

2. 本地化管理的表空间避免了在数据字典相应表里面写入空闲空间、已使用空间的信息,从而减少了数据字典表的竞争,提高了空间管理的并发性。

3. 区的本地化管理自动跟踪表空间里的空闲块,减少了手工合并自由空间的需要。

4. 表空间里的区的大小可以选择由Oracle系统来决定,或者由数据库管理员指定一个统一的大小,避免了字典表空间一直头疼的碎片问题。

5. 从由数据字典来管理空闲块改为由数据文件的头部记录来管理空闲块,这样避免产生回滚信息,不再使用系统表空间里的回滚段。因为由数据字典来管理的话,它会把相关信息记在数据字典的表里,从而产生回滚信息。

由于这种表空间的以上特性,所以它支持在一个表空间里边进行更多的并发操作,并减少了对数据字典的依赖。


四、本地管理表空间管理机制

表空间是一种为段(表,索引等)提供空间的逻辑结构,所以,当在表空间中增加,删除段的时候,数据库就必须跟踪这些空间的使用。

如下例所示,假定一个新创建的表空间包含了五个表

表一……表二……表三……表四……表五……未用空间

当我们删除表四的时候,就有如下结果

表一……表二……表三……空闲空间段……表五……未用空间

很明显,ORACLE需要有一个机制来管理表空间中各数据文件的这些分配的或未分配的空间,为了跟踪这些可以使用的空间(包括未分配使用的和可以重复使用的),对于每一个空间,我们必须知道:

1、这个可用空间位于什么数据文件

2、这个空间的尺寸是多大

3、如果它在用了,是哪一个段占用的这个空间

直到8i之前,所有的表空间都是采用字典管理模式,为了确保能保存以上的信息,ORACLE用了两个数据字典表:UET$(已使用的区间)或FET$(空闲空间):

SQL> desc UET$
Name Null? Type
----------------- ----------- -----------
SEGFILE# NOT NULL NUMBER
SEGBLOCK# NOT NULL NUMBER | The segment that uses this space
EXT# NOT NULL NUMBER
TS# NOT NULL NUMBER | The tablespace ID and the file
FILE# NOT NULL NUMBER | ID for that tablespace
BLOCK# NOT NULL NUMBER
LENGTH NOT NULL NUMBER | The location and size of the chunk

SQL> desc FET$
Name Null? Type
----------------- ----------- -----------
TS# NOT NULL NUMBER | The tablespace ID and the file
FILE# NOT NULL NUMBER | ID for that tablespace
BLOCK# NOT NULL NUMBER
LENGTH NOT NULL NUMBER | The location and size of the chunk

查询该表可以看到,每个使用空间或空闲空间(不一定是一个extent,可以是多个extent)都在该表中对应了一行。它的工作方式是当一个段被删除的时候,ORACLE就移动UET$中相应的行到FET$,这个过程的发生是连续的,而且可能发生等待。当并发性很高的时候,数据字典的争用就来了。另外有一个问题就是,当表的空间很不连续或表空间有大量的碎片引起这两个表的增大,那么也就会引起数据库性能上的下降。

本地管理表空间正是为了解决这一问题来的,在表空间的空间管理上,ORACLE将存储信息保存在表空间的头部的位图中,而不是保存在数据字典中。通过这样的方式,在分配回收空间的时候,表空间就可以独立的完成操作也不用与其它对象关系。

下面就让我们进入到本地管理表空间的内部,看看ORACLE是怎么实现这一工作的。

Uniform方式的本地管理表空间

1、 先创建了一个本地管理的表空间,区间统一大小分配为64K

SQL> create tablespace demo
datafile '/ora01/oem/oemdemo01.dbf' size 10m
extent management local uniform size 64k;

2、 在该表空间中创建一个表

SQL>create table demotab ( x number ) tablespace demo
storage ( initial 1000K next 1000k );
我们通过查询该表

SQL> select t.table_name,t.initial_extent,t.next_extent from user_tables t where t.table_name = 'DEMOTAB';
TABLE_NAME INITIAL_EXTENT NEXT_EXTENT
------------------------------ -------------- -----------
DEMOTAB 1024000 65536

可以发现,该表的存储参数并不是我们指定的参数INITIAL_EXTENT,而是uniform size的整数倍,NEXT_EXTENT则等于uniform size。我们从该查询就也可以看到如下情况

SQL>select count(*) from user_extents where segment_name = 'DEMOTAB';
COUNT(*)
----------
16

也就是说,该表在该表空间中已经存在16extent,而不是一个extent(这是与字典管理的差别,如果是字典管理的表空间,如果创建以上的表,该查询的结果是1)。

3、 获取该数据文件的文件ID

SQL> col name format a30 trunc
SQL> select file#, name from v$datafile;

File# NAME
----- --------------------
1 /oras1/oem/oemsystem01.dbf
2 /oras3/oem/oemundo01.dbf
3 /ora01/oem/oemoem_repository01
4 /ora01/oem/oemrcat01.dbf
5 /ora01/oem/oemdemo01.dbf
我们可以检查uet$
fet$
SQL> select count(*) from uet$ where file# = 5;
COUNT(*)
----------
0

SQL> select count(*) from fet$ where file# = 5;
COUNT(*)
----------
0

4、 可以看到,ORACLE没有在这两个表中保存任何信息,现在我们dump该数据文件的第三个块。

SQL> alter system dump datafile 5 block 3;
System altered.


查看DUMP文件,有如下信息
Start dump data blocks tsn: 5 file#: 5 minblk 3 maxblk 3
buffer tsn: 5 rdba: 0x01400003 (5/3)
scn: 0x0000.202f7a6f seq: 0x01 flg: 0x00 tail: 0x7a6f1e01
frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap
File Space Bitmap Block:
BitMap Control:
RelFno: 5, BeginBlock: 9, Flag: 0, First: 16, Free: 63472
FFFF00
0000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
.....

注意其中的FFFF00,,这是16进制的表现方法,我们转换为二进制,有
1111,1111,1111,1111,0000,0000

发现这里有161,每一个1就是一个位(bit),代表64K,也就代表了该表空间有已经分配了的16extent,如果我们将该表扩展,将又有什么结果呢?

SQL> alter table demotab allocate extent;
Table altered.

SQL> alter table demotab allocate extent;
Table altered.

SQL> alter table demotab allocate extent;
Table altered.

这样之后,我们应该有19extent了,再dump第三个块

Start dump data blocks tsn: 5 file#: 5 minblk 3 maxblk 3
buffer tsn: 5 rdba: 0x01400003 (5/3)
scn: 0x0000.202f7c64 seq: 0x01 flg: 0x00 tail: 0x7c641e01
frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap
File Space Bitmap Block:
BitMap Control:
RelFno: 5, BeginBlock: 9, Flag: 0, First: 19, Free: 63469

FFFF07 0000000000 0000000000000000 0000000000000000 0000000000000000

除了以前的FFFF,现在多了07,怎么解释呢?

07转换为二进制为0000,0111,但是还是不够解释以上的情况,这里我们没有考虑到字节交换的情况,因为以上FF交换后还是FF,但是如果是07,我们就必须考虑字节交换(因为计算机是一个字节一个字节的写,一个字节占两位当然是先写后面了,如从010FFF为止。 如果我们明白了,那么FFFF07转换为二进制为 1111,1111,1111,1111,0000,0111
每个字节交换得

1111,1111,1111,1111,1110,0000

可以发现,这里有191,也就是19个位(bit),代表了现在的19extent

5、 同样我们dump该数据文件第9个块,则有

Start dump data blocks tsn: 5 file#: 5 minblk 9 maxblk 9
buffer tsn: 5 rdba: 0x01400003 (5/3)
scn: 0x0000.202f7c64 seq: 0x01 flg: 0x00 tail: 0x7c641e01
frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap

Extent Control Header
-----------------------------------------------------------------
Extent Header:: spare1: 0 space2: 0 #extents: 16 #blocks: 127
last map 0x00000000 #maps: 0 offset: 4128
Highwater:: 0x01c0000a
ext#: 0 blk#: 0 ext size: 7
#blocks in seg. hdr's freelists: 0
#blocks below: 0
mapblk 0x00000000 offset: 0
Disk Lock:: Locked by scn: 0x0006.012.00000017
Map Header:: next 0x00000000 #extents: 16 obj#: 3090 flag: 0x40000000
Extent Map
-----------------------------------------------------------------
0x01c0000a length: 7
0x01c00011 length: 8
0x01c00019 length: 8
0x01c00021 length: 8
0x01c00029 length: 8
0x01c00031 length: 8
0x01c00039 length: 8
0x01c00041 length: 8
0x01c00049 length: 8
0x01c00051 length: 8
0x01c00059 length: 8
0x01c00061 length: 8
0x01c00069 length: 8
0x01c00071 length: 8
0x01c00079 length: 8
0x01c00081 length: 8

nfl = 1, nfb = 1 typ = 1 nxf = 0
SEG LST:: flg: UNUSED lhd: 0x00000000 ltl: 0x00000000 End dump data blocks tsn: 5 file#: 5 minblk 9 maxblk 9


  
这是该数据文件中表DEMOTAB的表头(一个块)信息, 从这里可以看到,该表从第9个块开始使用Highwater:: 0x01c0000a已经是第10个块了,从以上列表,我们也能清楚的看到,该表耗费了16个区间。

由于该表是数据文件的第一个表,所以位图区占用从386个块,加上前面两个文件头,也就是说,在数据文件头部共8个块用于系统消耗。如果我们的db_block_size8192,那么很明显,占用的空间为64K(注意:对于不同的块大小,文件头部的块个数与大小可能会不一样)。

也因为仅仅操作数据文件头部几个块,不用操作数据字典,所以ORACLE在本地管理的表空间中添加,删除段的时候,效率要比字典管理的表空间快。特别是在并发性很强的空间请求中。

ORACLE通过强制性的手段使本地管理表空间中的所有Extent是同样大小的,尽管你可能自定义了不同的存储参数。

6、 补充一些字典管理表空间的不同

a. 如果是字典管理,表空间中的表的区间的大小取决于表的存储参数,如果没有定义,则取表空间的通用存储参数。所以每个表的区间大小可以不一样。

b. 如果不指定表的最少区间数,那么默认创建的时候,该表只有一个区间,而不是多个区间。

c. 字典管理的文件头只占用一个块,第一个表的HWM应当是Highwater:: x01c00003,关于这个可以自己 

 

 

 

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

上一篇: 配置透明网关
请登录后发表评论 登录
全部评论
Oracle , MySQL, SAP IQ, SAP HANA, PostgreSQL, Tableau 技术讨论,希望在这里一起分享知识,讨论技术,畅谈人生 。

注册时间:2007-12-10

  • 博文量
    5595
  • 访问量
    13403455