Oracle_管理表空间

 

                                 Oracle_管理表空间

1

本地管理表空间

 

一、概述

 

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

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

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

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

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

 

二、名词解释与约定

 

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

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

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

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

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

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

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

 

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

 

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

 

语法:CREATE TABLESPACE 表空间名字     DATAFILE '数据文件详细信息'

[EXTENT MANAGEMENT { LOCAL

{AUTOALLOCATE | UNIFORM [SIZE INTETER [K|M] ] } } ]

 

查看表空间

 SYS @ cuug > select TABLESPACE_NAME, EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces;

 

TABLESPACE_NAME                EXTENT_MAN SEGMEN

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

SYSTEM                         LOCAL      MANUAL

UNDOTBS1                   LOCAL      MANUAL

SYSAUX                         LOCAL      AUTO

TEMP                           LOCAL      MANUAL

USERS                          LOCAL      AUTO

 

---DBCA自动创建库

 

SYS @ cuug >select TABLESPACE_NAME, EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces;

 

TABLESPACE_NAME                EXTENT_MAN SEGMEN

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

SYSTEM                         DICTIONARY MANUAL

UNDOTBS1                   LOCAL      MANUAL

SYSAUX                         LOCAL      AUTO

TEMP                           LOCAL      MANUAL

USERS                          LOCAL      AUTO

 

---手工建库

 

关键字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$(空闲空间):

 

SYS @ cuug > 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

 

SYS @ cuug >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方式的本地管理表空间

SYS @ cuug > create tablespace demo  datafile '/u01/app/oracle/oradata/cuug/demo.dbf' size 30m extent management local uniform size 64k;

Tablespace created.

 

SYS @ cuug >create table demotab ( x number ) tablespace demo  storage ( initial 1000K next 1000k );

Table created.

 

我们通过查询该表

SYS @ cuug >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我们从该查询就也可以看到如下情况

 

SYS @ cuug >select count(*) from user_extents where segment_name = 'DEMOTAB';

 

COUNT(*)

----------

16

 

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

 

SYS @ cuug > col name format a30 trunc

 

SYS @ cuug > select file#, name from v$datafile;

 

 

     FILE# NAME

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

         1 /u01/app/oracle/oradata/cuug/system01.dbf

         2 /u01/app/oracle/oradata/cuug/undotbs01.dbf

         3 /u01/app/oracle/oradata/cuug/sysaux01.dbf

         4 /u01/app/oracle/oradata/cuug/users02.dbf

         5 /u01/app/oracle/oradata/cuug/users03.dbf

         6 /u01/app/oracle/oradata/cuug/demo.dbf

 

我们可以检查uet$fet$

 

 

SYS @ cuug > select count(*) from uet$ where file# = 6; COUNT(*)

----------

0

 

 

SYS @ cuug >select count(*) from fet$ where file# = 6; COUNT(*)

 

----------

0

 

 

SYS @ cuug >alter system dump datafile 6 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

FFFF000000000000 0000000000000000 0000000000000000 0000000000000000

0000000000000000 0000000000000000 0000000000000000 0000000000000000

.....

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

 

1111,1111,1111,1111,0000,0000

 

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

 

SYS @ cuug >alter table demotab allocate extent;

 

Table altered.

 

SYS @ cuug alter table demotab allocate extent;

 

Table altered.

 

SYS @ cuug 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

 

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是同样大小的,尽管你可能自定义了不同的存储参数。

 

 

 

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

 

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

 

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

 

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

 

Autoallocate的本地管理表空间

 

在自动分配的本地管理的表空间中,区间尺寸可能由以下尺寸组成64k, 1m, 8m, 64m 甚至是256m。但是不管多大,都有一个通用尺寸64k,所以64K就是该表空间的位大小。

 

SYS @ cuug > create tablespace dummy datafile '/u01/app/oracle/oradata/cuug/dummy.dbf' size 100m  autoallocate;

 

Tablespace created.

 

SYS @ cuug >create table x1 (x number) tablespace dummy     storage (initial 50M);

 

Table created.

 

 

SYS @ cuug > select file# from v$datafile where name like '%dummy%';

 

     FILE#

----------

         7 

 

SYS @ cuug > select extents from user_segments where segment_name = 'X1' ; 

 

EXTENTS

----------

50

 

SYS @ cuug >alter system dump datafile 7 block 3;

 

System altered.

 

*** SESSION ID11.59) 2002-11-22 10:37:35.000

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

buffer tsn: 19 rdba: 0x03000003 (12/3)

scn: 0x0000.00f2959b seq: 0x01 flg: 0x00 tail: 0x959b1e01

frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap

File Space Bitmap Block:

BitMap Control:

RelFno: 12, BeginBlock: 9, Flag: 0, First: 800, Free: 62688

FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF

FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF

FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFF

FFFFFFFF00000000 0000000000000000 0000000000000000 0000000000000000

0000000000000000 0000000000000000 0000000000000000 0000000000000000

0000000000000000 0000000000000000 0000000000000000 0000000000000000

0000000000000000 0000000000000000 0000000000000000 0000000000000000

0000000000000000 0000000000000000 0000000000000000 0000000000000000

0000000000000000 0000000000000000 0000000000000000 0000000000000000

 

可以看到该表实际只有50个区间(extent),但是有800个位(bit)

50*1024=800*64

还可以看出,位大小并不等于extent大小。

 

 

 

 

五、迁移到本地管理表空间

 

在很多情况下,如果你想在字典表空间与本地表空间之间转换是很难的,你可能需要转出该表空间所有的数据,从新创建表空间,再加载该数据。但是在816以后,有一个叫dbms_space_admin的包使两类表空间的互相转换变成可能,体现在如下两个过程:

DBMS_SPACE_ADMIN.TABLESPACE_MIGRATE_TO_LOCAL

DBMS_SPACE_ADMIN.TABLESPACE_MIGRATE_FROM_LOCAL

 

但是在你想利用这个过程进行转换的时候,你必须注意两件事:

 

1 数据库版本必须是816以上,兼容版本(compatible)必须是8.1以上

2 如果是转换成为本地管理,必须有足够的空闲空间做本地位图空间(8个块)

 

当从字典管理到本地管理的过程中,全部转换其实基本上是不可能发生的,实际情况是,对于已经存在的数据和空间,该过程是没有任何办法的,仅仅是简单把空间取整并标记。所以说,这种转换后的表空间可以减缓UET$FET$的压力,但并不能解决碎片问题。从查询DBA_TABLESPACES你还可以看到,转换之后的表空间管理方式是LOCAL,但实际段分配是USER(不是uniformautomatic)。

很显然,在字典管理的表空间中,存在许多大小不同的区间(extent)尺寸,所以转换为本地管理的时候,ORACLE怎么样把这些已经存在的空间转换为通用大小了?为了做到这一点,ORACLE必须扫描该表空间的每个数据文件,主要是检查以下三个问题:

 

文本框: 1、 所有的已经存在的区间
2、 所有的以前用过,但是现在空闲的空间
3、 由表空间MINIMUM EXTENT语句标记的大小

 

 

 

 

 

 

在转换的时候,ORACLE试图发现一个适合于以上三个标准的最大的区间的尺寸作为本地管理的区间尺寸,也就是说,在最坏的情况下,这个最大的区间可能就是单个块(如果说一个表的区间尺寸是7个块,另外一个表的区间尺寸是8个块)

我们看一个从字典管理表空间到本地管理表空间的例子

 

SYS @ cuug > create tablespace blah  datafile '/u01/app/oracle/oradata/cuug/blah.dbf' size 10m reuse;

 

Tablespace created. 

 

SYS @ cuug > col bytes format 999,999,999

 

SYS @ cuug >select * from dba_free_space where tablespace_name = 'BLAH';

 

TABLESPACE_NAME                   FILE_ID   BLOCK_ID        BYTES     BLOCKS     RELATIVE_FNO

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

BLAH                                               8               9                10,420,224       1272            8

 

 

 

SYS @ cuug > create table t1 ( x number ) storage ( initial 400k) tablespace blah;

 

Table created.

 

SYS @ cuug >create table t2 ( x number ) storage ( initial 800k) tablespace blah;

 

Table created.

 

SYS @ cuug >create table t3 ( x number ) storage ( initial 1200k) tablespace blah;

 

Table created.

 

SYS @ cuug > select * from dba_free_space where tablespace_name = 'BLAH';

 

TABLESPACE_NAME                   FILE_ID   BLOCK_ID        BYTES     BLOCKS RELATIVE_FNO

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

BLAH                                    8        169      786,432         96            8

BLAH                                    8        521    6,225,920        760            8

 

SYS @ cuug >select bytes from dba_extents where tablespace_name = 'BLAH';

 

       BYTES

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

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

 

       BYTES

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

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

      65,536

   1,048,576

   1,048,576

 

22 rows selected. 

 

3、现在我们开始转换该表空间为本地管理的表空间,假定每个位图大小400K,也就是50个块。

SQL> exec dbms_space_admin.TABLESPACE_MIGRATE_TO_LOCAL('BLAH',50);

 

BEGIN dbms_space_admin.TABLESPACE_MIGRATE_TO_LOCAL('BLAH',50); END;

*

ERROR at line 1:

ORA-03241: Invalid unit size

ORA-06512: at "SYS.DBMS_SPACE_ADMIN", line 0

ORA-06512: at line 1

 

如果我们设置表空间的minimum extent语句为400K

 

SYS @ cuug > alter tablespace blah minimum extent 400k;

 

Tablespace altered.

 

SYS @ cuug > exec dbms_space_admin.TABLESPACE_MIGRATE_TO_LOCAL('BLAH',50);

 

PL/SQL procedure successfully completed.

 

Conversion goes through with no problems.

 

从以上可以看到,转换成功,但实际情况远远比这么复杂,或许你根本就不知道表空间里面的公用尺寸是多大。而且通过这种转换后的表空间,并没有消除碎片,也不一定有优化的作用。所以建议不要用该方法进行转换,而是使用alter table move的办法进行表空间的转换将可能是最好的办法。(End)

 

源文档 <http://epub.itpub.net/9/6.htm>

 

  • 我们在上面创建三个表,最小公用尺寸是400K
  • 首先,我们创建一个字典管理表空间
  •  
  •  
  • 同样我们dump该数据文件第9个块,则有
  •  
  • 可以看到,ORACLE没有在这两个表中保存任何信息,现在我们dump该数据文件的第三个块。
  •  
  • 获取该数据文件的文件ID
  •  
  • 在该表空间中创建一个表
  •  
  •  
  • 先创建了一个本地管理的表空间,区间统一大小分配为64K

2

表空间转换

 

首先要知道本地管理表空间和字典管理表空间的区别。 

字典管理表空间每当表或其他对象需要扩大的时候都检查其数据字典以确保有可用的空间分配给对象,然后给对象分配一个新区段并更新其可用空间信息。 

本地管理表空间保存数据文件本身的空间管理信息,而且表空间自动跟踪每个数据文件块的可用或已用状态。 

在事务比较多的数据库中显然字典管理每次插入数据时都会检查数据字典,这就使得数据库性能有所损耗。 

 

转换: 

 

第一种方法---命令方式转移。 

 

文本框: 首先你要新建一个oracle表空间,在oracle 10g以后默认都是采用本地管理表空间的。 
对于表空间的转移使用命令 

ALTER TABLE temp MOVE TABLESPACE new_temp; 
对于索引你需要重建 
ALTER TABLE index REBUILD TABLESPACE new_index;

 

 

 

 

 

 

 

 

 

 

 

或许你可以采用oracle提供的PL/SQL数据包中的DBMS_SPACE_ADMIN 

 

显然上面的方法并不适用于对system表进行转换,因为你不能建立2个同名的system表。 

在转换system表前,你必须把所有的其他表空间转换为本地管理。 

 

SYS @ cuug >EXECUTE dbms_space_admin.tablespace_migrate_to_local('SYSTEM');     ---转换表空间 

 

然后同样的方法将system表空间也进行转换. 

 

EXECUTE dbms_space_admin.tablespace_migrate_to_local(system); 

 

使用这种方法很好,但是它建立的表空间没有automatic segment space managerment选项,所有字典管理表空间都是用默认手动段空间管理,而且在转换为本地管理的表空间是不能进行修改. 

还有一个缺点,就是表空间如果存在空间碎片的话,此方法也不能解决碎片问题. 

所以oracle建议你,采用第一种方法.

 

源文档 <http://www.javaeye.com/topic/437409>

 

3

表空间管理脚本

 

SYS @ cuug >select tablespace_name,count(*),sum(blocks),sum(bytes)/1024/1024     from dba_data_files      group by tablespace_name;

 

TABLESPACE_NAME                  COUNT(*) SUM(BLOCKS) SUM(BYTES)/1024/1024

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

DEMO                                    1        3840                   30

SYSAUX                                  1       30720                  240

UNDOTBS1                                1      268160                 2095

DUMMY                                   1       12800                  100

USERS                                   2       38400                  300

SYSTEM                                  1       75520                  590

BLAH                                    1        1280                   10 

 

 

2:表空间使用情况

 

 

SYS @ cuug >select df.tablespace_name TBS_NAME ,totalspace TOTAL_SIZE ,freespace REMAIND ,round((1-freespace/totalspace)*100,2) RAIT

  2  From (select tablespace_name,round(sum(bytes)/1024/1024) totalspace

  3  from dba_data_files

  4  group by tablespace_name) df,

  5  (select tablespace_name,round(sum(bytes)/1024/1024) freespace

  6  from dba_free_space

  7  group by tablespace_name) fs

  8  where df.tablespace_name=fs.tablespace_name;

 

TBS_NAME                       TOTAL_SIZE    REMAIND       RAIT

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

DEMO                                   30         29       3.33

UNDOTBS1                             2095       2048       2.24

SYSAUX                                240          1      99.58

DUMMY                                 100         50         50

USERS                                 300        300          0

SYSTEM                                590          8      98.64

BLAH                                   10          7         30 

 

3:删除表空间

 

-- SYS @ cuug >select t.name,d.name from v$tablespace t,v$datafile d where t.name='USERS' and t.ts#=d.ts#;

 

NAME                                               NAME

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

USERS                                              /u01/app/oracle/oradata/cuug/users02.dbf

USERS                                              /u01/app/oracle/oradata/cuug/users03.dbf

 

 

--alter tablespace DATA_HOST_A offline;

 

--drop tablespace DATA_HOST_A including contents;

 

 

4:为这个表空间增加一个数据文件

 

--SQL> alter tablespace    tablespace_name  add datafile '/u1/oradata/userdata_002.ora' size 50m;--Unix

 

--SQL> alter tablespace 表空间名 add datafile 'c:\oradata\userdata_002.ora' size 50m; --Windows NT

 

5:重新调整数据文件的大小

 

--SQL> alter database datafile '/u1/oradata/userdata_001.ora' resize 50M; --Unix

--SQL> alter database datafile 'c:\oradata\userdata_002.ora' resize 50M;--Windows NT

 

 

6:查看数据库的大小,和空间使用情况 

 

SYS @ cuug >select b.file_id,  b.tablespace_name, b.file_name,     b.bytes,b.bytes-sum(nvl(a.bytes,0)),  sum(nvl(a.bytes,0)) ,sum(nvl(a.bytes,0))/(b.bytes)*100  from   dba_free_space a,dba_data_files b   where a.file_id=b.file_id    group by b.tablespace_name,b.file_name,b.file_id,b.bytes    order by b.tablespace_name;

 

   FILE_ID TABLESPACE FILE_NAME       TOLAL_SIZE  USED_SIZE  FREE_SIZE    HAIT

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

         1 SYSTEM     system01.dbf           590   582.0625     7.9375    1.35

         2 UNDOTBS1   undotbs01.dbf         2095    40.3125  2054.6875   98.08

         3 SYSAUX     sysaux01.dbf           240     239.25        .75     .31

         5 USERS      users03.dbf            300       .125    299.875   99.96

         6 DEMO       demo.dbf                30      1.125     28.875   96.25

         7 DUMMY      dummy.dbf              100    50.0625    49.9375   49.94

         8 BLAH       blah.dbf                10     3.3125     6.6875   66.88

 

 

源文档 <http://blog.csdn.net/yuzhic/archive/2008/01/20/2054490.aspx>

 

 

4

今天在研究HWM时候要研究本地管理与字典管理表空间不同时候,发现了一个问题,要创建一个字典管理的表空间时候,报错!具体请看下述!

 

1:创建一个字典管理的表空间:

SQL>

create tablespace exitgogo datafile ''/free/oracle/oradata/orcl/exitgogodb.dbf'' size 50m

2 extent management dictionary;

create tablespace exitgogo datafile ''/free/oracle/oradata/orcl/exitgogodb.dbf'' size 50m

*ERROR at line 1:

ORA-12913: Cannot create dictionary managed tablespace

 

2:查看系统表空间属性:

 

www.ixdba.net

 

SQL> select TABLESPACE_NAME,EXTENT_MANAGEMENT from dba_tablespaces;

 

TABLESPACE_NAME EXTENT_MAN

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

SYSTEM LOCAL

UNDOTBS1 LOCAL

TEMP LOCAL

CWMLITE LOCAL

DRSYS LOCAL

EXAMPLE LOCAL

INDX LOCAL

ODM LOCAL

TOOLS LOCAL

USERS LOCAL

XDB LOCAL

HWM LOCAL

 

系统表空间是本地管理的。看来如果system是本地管理表空间的话,就不能在这个数据库中创建字典管理的表空间。

 

3:创建一个字典管理的system表空间数据库:

 

用如下脚本创建:

 

CREATE DATABASE $db_name

LOGFILE

GROUP 1 ''$path_oradata/redo01.log'' SIZE 50M,

GROUP 2 ''$path_oradata/redo02.log'' SIZE 50M,

GROUP 3 ''$path_oradata/redo03.log'' SIZE 50M

MAXINSTANCES 8

MAXLOGHISTORY 100

MAXLOGMEMBERS 3

MAXLOGFILES 16

MAXDATAFILES 254

NOARCHIVELOG

CHARACTER SET AL32UTF8

NATIONAL CHARACTER SET AL16UTF16

DATAFILE ''$path_oradata/system01.dbf'' SIZE 200M

AUTOEXTEND ON NEXT 5M MAXSIZE UNLIMITED

UNDO TABLESPACE UNDOTBS1

DATAFILE ''$path_oradata/undotbs01.dbf'' SIZE 200M

DEFAULT TEMPORARY TABLESPACE TEMP

TEMPFILE ''$path_oradata/temp01.dbf'' SIZE 100M;

 

以上脚本中,没有指定system表空间的管理方式,先创建再说!

 

4:创建数据库完毕,查看system表空间属性:

 

[oracle@localhost createDB]$ sqlplus "/as sysdba"

 

SQL*Plus: Release 9.2.0.1.0 - Production on Mon Oct 23 16:55:57 2006

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

Connected to:

Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production

With the Partitioning, OLAP and Oracle Data Mining options

JServer Release 9.2.0.1.0 Production

 

SQL> select TABLESPACE_NAME,EXTENT_MANAGEMENT from dba_tablespaces;

 

TABLESPACE_NAME EXTENT_MAN

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

SYSTEM DICTIONARY

UNDOTBS1 LOCAL

TEMP LOCAL

USERS LOCAL

TOOLS LOCAL

INDX LOCAL

GAOJF LOCAL

 

可以看到,如果没有指定上面脚本中system表空间创建属性的话,默认system表空间为DICTIONARY管理方式。

 

5:在新的数据库中创建字典管理的表空间(systemDICTIONARY时)

SQL> create tablespace exitgogo datafile ''/free/oracle/oradata/orcl/exitgogodb.dbf'' size 50m

 extent management dictionary;

Tablespace created.

 

SQL> select TABLESPACE_NAME,EXTENT_MANAGEMENT from dba_tablespaces;

 

TABLESPACE_NAME EXTENT_MAN

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

SYSTEM DICTIONARY

UNDOTBS1 LOCAL

TEMP LOCAL

USERS LOCAL

TOOLS LOCAL

INDX LOCAL

GAOJF LOCAL

EXITGOGO DICTIONARY

 

8 rows selected.

 

可以创建成功。这样问题就清楚了。

 

总结:

1oracle9i/10g中,如果system表空间是字典管理的话,那么可以在这个数据库中创建local管理的表空间,也可以创建字典管理的表空间。

 

04:33:11 SQL>  select TABLESPACE_NAME, EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces;

 

TABLESPACE_NAME                EXTENT_MAN SEGMEN

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

SYSTEM                         DICTIONARY MANUAL

UNDO01                         LOCAL      MANUAL

SYSAUX                         LOCAL      AUTO

TEMP                           LOCAL      MANUAL

USERS                          LOCAL      AUTO

 

05:30:13   2  datafile '/disk3/oradata/cuug/test01.dbf' size 10m

05:30:39   3   extent management dictionary;

 

Tablespace created.

 

05:34:59 SQL> select TABLESPACE_NAME, EXTENT_MANAGEMENT,SEGMENT_SPACE_MANAGEMENT from dba_tablespaces;

 

tablespacename                 EXTENT_MAN SEGMEN

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

SYSTEM                         DICTIONARY MANUAL

UNDO01                         LOCAL      MANUAL

SYSAUX                         LOCAL      AUTO

TEMP                           LOCAL      MANUAL

USERS                          LOCAL      AUTO

TEST                           DICTIONARY MANUAL

 

6 rows selected.

 

2:如果systemlocal管理的,那么只能创建local管理的表空间.这样情况下不能创建DMT,但是可以通过 transport imp DMT 的表空间,只是这样的表空间只能read only 而不能read write

 

源文档 <http://database.e800.com.cn/articles/2008/114/1225744133806982443_1.html>

 

5

表空间管理

 

 

说明: 计算机生成了可选文字: 0raCle中,本人很喜欢Oracle表空间,在工作中也很喜欢总结关于Oracle表空间的经验教训,下面就这个问题来详
细说说吧.Oracle表空间是数据管理的基本方法,所有用户的对象要存放在表空间中,也就是用户有空间的使用权,才
能创建用户对象.否则是不充许创建对象,因为就是想创建对象,如表,索弓}等,也没有地方存放,0racle会提示!没有
存储配额.因此,在创建对象之前,首先要分配存储空l'ed。分配存储,就要创建表空I'al:
创建Oracle表空间示例如下:
C尺EATETABLESPACE''SAMPLE',LOGGINGOATAF!LE'O:\O尺ACLE\O尺八OATA\O尺A92\LUNTANOFa'SIZESM
…EXTENTMANAGEMENTLDCA弓卜EGMENTSPACEMANAGEMENTAUTo}
上面的语句分以下几部分:
第一C尺EA丁E丁A日LESpACE',SAM尸LE",创建一个名为”SAMpLE',的表空l'ed.对表空间的命名,遵守Oracle的命名
规范就可了.
0raCle可以创建的表空间有三种类型
(1)丁EMpo尺A尺丫临时表空间,用于临时数据的存放;创建临时表空间的语法如下:C尺EA丁E丁EMpo尺A尺丫
TABLESPACE",SAMPLE”。
(2)UNOO:还原表空间.用于存入重做日志文件.创建还原表空间的语法如下:C尺EATEuNOO下A日LESpACE
IISAMpLE',。

 

 

说明: 计算机生成了可选文字: (3)用户表空l'ed:最重要,也是用于存放用户数据表空间可以直接写成:c尺EA丁E
丁A日LESpACE',SAMpLE'"TEMpO尺A尺丫和UNOO表空间是Oracle管理的特殊的表空l'ed.只用于存放系统相关数据.
第二:LOGGING
有NOLOGGING和LOGGING两个选项,}NOLOGGING创建表空间时,不创建重做日刹.
表空I'ed的创建较快,但是没能日志,数据丢失后,不能恢复,
做法,是建完表空l'ed,并导入数据后,是要对数据做备份的,
用NOLOGGING时,好处在于创建时不用生成日志,这样
但是一般我们在创建表空I'ed时,是没有数据的,按通常的
所以通常不需要表空间的创建日志,
第三OA丁AFILE用于指定数据文件的具体位置和大小。
如:DATAFILE'D:\Qracle\QRADATA\QPA92\LUNTAN.ora'SIZESM说明文件的存放位置
是’D:、Oracle、ORAOATA\ORA92\LUN丁AN.ora',文件的大小为SM.如果有多个文件,可以用逗号隔开!
DATAFILE"D:\ORACLE\ORADATA\DRA92\LUNTAN.ora'SIZESM.'D:\ORACLE\DRADATA\DRA92\ddora"SIZE
5M
但是每个文件都需要指明大小.单位以指定的单位为准如SM或500代。对具体的文件,可以根据不同的需要,存
放大不同的介质上,如磁盘阵列,以减少旧竟争。指定文件名时,必须为绝对地址,不能使用相对地址.

 

说明: 计算机生成了可选文字: 第四:EX丁EN下MANAGEMEN下LOCAL存储区管理方法
在oraclesi以前,可以有两种选择,一种是在字典中管理(DlcTIONA尺Y),另一种是本地管理(LOCAL),从91开始,
只“泛是本地管理方式·因为LOCAL管理方式有,良多优点·}在字典中管理(。‘C丁‘。NAR丫):1各数据文件中的每一个存储单元}
恤为一条记录,所以在做。M操作时,就会产生大量的,寸这个管理表的。e.ete和update操作.}做大量数据管理时,1,会产
生很多的OM操作,严得的影响性能,同时,长时间对表数据的操作,会产生很多的磁盘碎片,这就是为什么要做磁盘整
理的原因.本地管理(LOCAL):用二进制的方式管理磁盘,有很高的效率,同进能最大限度的使用磁盘.同时能够自动
跟踪记录临近空闲空l'ed的情况,避免进行空闲区的合并操作.
第五:SEGMENTSPACEMANAGEMENT
磁盘扩展管理方法
令5EGMEN丁SpACEMANAGEMENT:使用该选项时区大小由系统自动确定.由于Oracle可确定各区的最佳大小,
所以区大小是可变的.
第六:段空I'ed的管理方式
使用LOCAL管理Oracle表空间时,数据块中的空闲空l'ed增加或减少
其新状态都会刊位图亚反映出来.位图使or。。le管理空闲空间的行为更加自动化,并为管理空闲空l'ed提供了更好的
但对含有LO日字段的表不能自动管理.
后性

 

说明: 计算机生成了可选文字: .MANUA七目前已不用,主要是为向后兼容.
第七:指定块大小.可以具体指定表空间数据块的大小。

 

6

存储管理参数

 

 

 

  1. INITIAL

 

对于字典管理表空间来说,INITIAL用于指定段所分配的第一个区的尺寸。对于本地管理表空间来说,如果MINEXTENTS等于1,数据库会使用INITIAL和区尺寸确定段的初始尺寸。假定本地管理表空间的区尺寸为5M,如果INITIAl1M,那么会分配一个5M的区。如果INITIAL7M,则分配两个5M的区。INITIAL只能在建立对象时设置,不能使用ALTER语句进行修改

 

CREATE TABLE t1(cola INT) TABLESPACE user01

STORAGE(INITIAL 500k);

 

说明:使用user01表空间,假定user01创建时使用UNIFORM选项,并且区尺寸为128K.t1表的段初始尺寸为500K

 

 

2. NEXT

 

对于本地管理表空间来说,因为数据库可以自动管理区,所以该参数没有太大意义。对于字典管理表空间来说,NEXT用于指定为段所分配的第二个区的尺寸。

 

 

 

3. PCTINCREASE

 

对于本地管理表空间来说,因为数据库可以自动管理区,所以该参数没有太大意义。对于字典管理表空间来说,该参数可以指定从第三个区开始,每个区比前一个区所增长的百分比。

 

 

 

4. MINEXTENTS

 

对于本地管理表空间来说,因为数据库可以自动管理区,所以该参数没有太大意义。对于字典管理表空间来说,MINEXTENTS用于指定为段所分配的初始区个数。

 

 

5. MAXEXTENTS

 

对于本地管理表空间来说,因为数据库可以自动管理区,所以该参数没有太大意义。对于字典管理表空间来说,MINEXTENTS用于指定段可包含的最大区个数。

 

 

 

6. FREELIST GROUPS

 

FREELIST GROUPS用于指定对象的空闲列表组个数,每个空闲列表组会占用一个数据块。Oracle建议为Oracle Real application Cluster的每个例程指定一个空闲列表组。需要注意,FREELIST GROUPS只能在段级指定。

 

 

7. FREELISTS

 

FREELISTS用于指定每个空闲列表组上的空闲列表个数,空闲列表用于维护可插入数据的数据块。需要注意,FREELISTS只能在段级指定。

 

 

8.

 

假定建立字典管理表空间user02时,指定默认存储参数INITIALNEXT均为10KPCTINCREASE50.下面以建立表t2为例,说明在字典管理表空间上这些存储参数的作用。

 

CREATE TABLE t2(cola int) TABLESPACE user02

STORAGE(NEXT 20K MINEXTENTS 4);

 

执行以上语句后,Oracle会建立表T1,并且为其分配尺寸为110K的表段t2。因为MINEXTENTS4,所以段T1包含四个区;因为建表时未指定INITIAL,所以第一个区会使用表空间的默认存储参数:10K。第二个区区20K,第三区:30K,第四区:50K

 

 

 

9. 显示已分配区

 

建立数据对象时,Oracle会为数据对象分配相应的段。段是由一个或多个区组成的,并且一个区只能存放在一个数据文件上,而同一个段的不同区可以放在不同数据文件上。通过查询数据字典视图dba_extents,可以取得已分配区的详细信息。

 

 

SELECT extent_id,file_id,block_id,bytes

FROM dba_extents

WHERE owner=SYS AND segment_name=T1;

 

 

10. 显示空闲区

 

当在表空间上建立数据对象时,Oracle会在表空间的剩余空间中位相应段分配空间。当段不足以容纳更多数据时,Oracle会通过分配区来扩展段。随着时间的推移,将导致表空间的剩余空间越来越少。

 

SELECT sumbytesFROM dba_free_space

WHERE tablespace_name=USER01;

 

源文档 <http://www.examda.com/oracle/zonghe/20110225/12061037.html>

 

 

 

 

 

创建时间:2022-03-30 20:45
浏览量:0