表空间的管理-字典和本地管理

Oracle通过表空间为数据库提供使用空间,那么Oracle必然提供一种技术用于空间管理。

Oracle主要的空间管理方式有两种,一种是Oracle 8i以前的字典管理表空间(DMT)技术,一种就是Oracle 8i以后的本地管理表空间(LMT)技术。由于区间(Extent)是Oracle创建对象时的最小分配单元,所以表空间的管理实际上就是针对于区间的管理。


一.字典管理表空间

在Oracle 8i以前(不包括8i),只存在一种表空间的管理模式,这就是字典管理表空间(Dictionary Managed Tablespace,简称DMT)。之前创建表空间的主要语法为:
CREATE TABLESPACE tablespace_name
DATAFILE 'datafile_path_name' [SIZE INTETER [K|M]
|[DEFAULT STORAGE]|[PERMANENT|TEMPORARY]] 

这里关键字DEFAULT STORAGE指明了该表空间的默认存储格式,包含了INITIAL、NEXT、PCTINCREASE等相关参数的设置。如果在表空间中创建对象(如表、索引等)时不指定存储参数的话,Oracle将采用表空间的存储参数作为对象的默认参数;PERMANENT|TEMPORARY指明了该表空间的类型是永久的还是临时的。

当表空间被创建之后,可以通过查询dba_tablespaces视图来确定表空间的类型:
SQL> select tablespace_name, extent_management,allocation_type
2 from dba_tablespaces;
TABLESPACE_NAME EXTENT_MAN ALLOCATIO
------------------------------ ---------- ---------
SYSTEM DICTIONARY USER
RBS DICTIONARY USER
TEMP DICTIONARY USER
USERS LOCAL UNIFORM
4 rows selected.

EXTENT_MANAGEMENT显示为DICTIONARY的就是字典管理表空间。所谓字典管理表空间是指,当创建或删除对象时,Oracle的空间分配或回收是通过数据库中的数据字典表来记录和管理的,用于管理的两个数据字典表分别是:UET$(Used Extents,已使用的空间)和FET$(Free Extents,空闲空间)。

可以来简单看一下这两个字典表的结构:
SQL> desc uet$
名称 空? 类型
----------------------------------------- -------- ----------------------------
SEGFILE# NOT NULL NUMBER
SEGBLOCK# NOT NULL NUMBER
EXT# NOT NULL NUMBER
TS# NOT NULL NUMBER
FILE# NOT NULL NUMBER
BLOCK# NOT NULL NUMBER
LENGTH NOT NULL NUMBER

SQL> desc fet$
名称 空? 类型
----------------------------------------- -------- ----------------------------
TS# NOT NULL NUMBER
FILE# NOT NULL NUMBER
BLOCK# NOT NULL NUMBER
LENGTH NOT NULL NUMBER

可以清晰地看到,这两个字典表基本上是通过文件号(file#)、数据块号(block#)等信息来管理空间的分配和回收的。

字典管理表空间的工作方式是--当建立一个新的段或者段在表空间中请求新的空间时,Oracle通过执行一系列的SQL语句来完成这个工作,这些工作包括从FET$中找到可用的自由空间,移动或增加相应的行到UET$中,并在FET$中删除相应的记录;当删除一个段的时候,Oracle则移动UET$中相应的行到FET$。

这个过程的发生是连续的、串行的,在繁忙的数据库中,这类操作极可能导致竞争和等待,产生数据字典的争用;另一方面,当数据字典的表的信息被修改时,系统同样要记录undo和redo信息,频繁的修改又不可避免地对整个数据库的性能产生影响。

在繁忙的数据库中,字典管理的表空间可能会成为灾难,下面展示一段Statspack报告,在这个采样周期为1小时的报告中:
DB Name DB Id Instance Inst Num Release OPS Host
------------ ----------- ------------ -------- ----------- --- ------------
TEAM 2757346 ss7 1 8.1.7.4.0 NO db-server

Snap Id Snap Time Sessions
------- ------------------ --------
Begin Snap: 2716 28-10月-03 08:15:03 20
End Snap: 2718 28-10月-03 09:15:31 20
Elapsed: 60.47 (mins)

注意到在根据Buffer Gets排序的Top SQL中,有大量的SQL是在进行字典表的空间维护操作,这已经成为了这个数据库的性能瓶颈,下面报告中的SQL语句很好地展示了字典管理表空间的空间维护方式:
Buffer Gets Executions Gets per Exec % Total Hash Value
--------------- ------------ -------------- ------- ------------
4,800,073 10,268 467.5 51.0 2913840444
select length from fet$ where file#=:1 and block#=:2 and ts#=:3

803,187 10,223 78.6 8.5 528349613
delete from uet$ where ts#=:1 and segfile#=:2 and segblock#=:3 a
nd ext#=:4

454,444 10,300 44.1 4.8 1839874543
select file#,block#,length from uet$ where ts#=:1 and segfile#=:
2 and segblock#=:3 and ext#=:4

23,110 10,230 2.3 0.2 3230982141
insert into fet$ (file#,block#,ts#,length) values (:1,:2,:3,:4)

21,201 347 61.1 0.2 1705880752
select file# from file$ where ts#=:1

9,505 12 792.1 0.1 1714733582
select f.file#, f.block#, f.ts#, f.length from fet$ f, ts$ t whe
re t.ts#=f.ts# and t.dflextpct!=0 and t.bitmapped=0

6,426 235 27.3 0.1 1877781575
delete from fet$ where file#=:1 and block#=:2 and ts#=:3

1,267 37 34.2 0.0 904892542
select file#,block#,length from fet$ where length>=:1 and
ts#=:2 and file#=:3

901 235 3.8 0.0 3687396716
insert into uet$ (segfile#,segblock#,ext#,ts#,file#,block#,lengt
h)values (:1, :2, :3, :4, :5, :6, :7)


字典管理表空间面临的另外一个严重问题是:空间碎片。

       在字典管理表空间中,我们经常会遇到这样的悖论,一个表空间中的自由空间(可以通过dba_free_space视图来计算)还有几百MB,但是一个请求几百KB空间的表可能都已经无法扩展。这是因为表空间中的自由空间并不连续,每块自由空间都很小,已经不能满足一个表的扩展需要,这在Oracle 8的年代常常成为困扰DBA的难题。

在字典管理表空间中,当要满足一个空间要求时,数据库要寻找表空间中的自由空间来使用,如果自由空间大于请求空间,那么自由空间就将被细分,这样将逐渐形成越来越多的离散的、分隔的、小块的自由空间,即空间碎片。

随着时间推移,应用系统的广泛使用,数据中所产生的碎片也会越来越多,这些碎片将对数据库产生以下几点主要影响。

导致系统性能衰减,如上所述,当要满足一个空间扩展要求时,数据库将首先查找当前最大的自由空间,经过分割,自由空间将逐渐变小,要找到一个满足扩展需求的自由空间已经变得越来越难,从而导致空间分配中的速度问题。

大量空间被浪费,尽管有一部分自由空间(如表空间的PCTINCREASE设置为非0值)将会被SMON(系统监控)后台进程周期性地合并,但始终有一部分自由空间无法得以自动合并,从而浪费了大量的宝贵空间,并且非0的PCTINCREASE更容易导致更多的碎片。

空间释放成为难题,在DMT管理的表空间中,你也许听说过DROP一个大表或删除一个表空间往往要花费数十小时甚至几天的时间,同时会导致严重的性能问题。这是因为当需要删除一个表或表空间时,Oracle同样要维护其空间分配,这样fet$和uet$表同样要被维护,这样的维护耗时将超乎想象。

这里简单地引用一个维护字典管理表空间的案例,以便给大家一些直观的印象。在以下的案例中,我们需要删除一个字典管理的表空间,在删除表空间时,Oracle需要递归地删除表空间里所有的Extent,包括使用的和未使用的。下面以fet$为例,ts#=3的是目标表空间,在fet$中存在44万左右的Extents:
SQL>select ts#,count(*) from fet$ group by ts#;
TS# COUNT(*)
---------- ----------
0 817
1 12160
3 440932
4 15775
5 5300
6 314997
6 rows selected.

在DROP表空间时,可以反复查询这个视图,根据Extent减少的速度来评估Oracle完成删除所需要的时间。在这个案例中,Oracle每秒仅能清除3个Extent。

那么完成这个操作大约需要40多个小时,可以看到,这个时间消耗是相当惊人的:
SQL> select 440932/3/3600 from dual;
440932/3/3600
-------------
40.827037

最终Oracle认识到字典表空间已经成为影响数据库性能的严重问题,于是Oracle在Oracle 8i中开始引入了本地管理表空间(Local Management Tablespace)的技术。


.本地管理表空间

从Oracle 8i开始,Oracle引入了一种全新的表空间管理方式:本地化管理表空间(Local Management Tablespace,简称LMT)。所谓本地化管理,就是指Oracle不再利用数据字典表来记录Oracle表空间里面的区间的使用状况,而是在每个表空间的数据文件的头部加入了一个位图区域,在其中记录每个Extent的使用状况。每当一个Extent被使用,或者被释放以供重新使用时,Oracle都会更新数据文件头部的这个记录,反映这个变化。

本地化管理的表空间的主要创建语法如下:
CREATE TABLESPACE tablespace_name
DATAFILE 'datafile_path_name'
[EXTENT MANAGEMENT { LOCAL
{AUTOALLOCATE | UNIFORM [SIZE INTETER [K|M] ] } } ]

其中关键字EXTENT MANAGEMENT LOCAL指定这是一个本地化管理的表空间。

在Oracle 8i中,创建表空间时字典管理还是默认的管理方式,在Oracle 9iR2中,本地管理表空间成为了默认的选项。需要记住的是,字典管理表空间作为一种过时的技术已经渐渐远去,本地管理表空间是一种更为高效的表空间管理技术。以上对于字典管理表空间的介绍是为了让大家更好地了解Oracle空间管理技术的来龙去脉。

需要注意的是,在创建本地管理表空间时,还可以选择更具体的空间分配方式:是选择自动分配(AUTOALLOCATE)还是统一尺寸(UNIFORM)。若为自动分配,则表明让Oracle来决定区块的使用办法,缺省地Oracle会按照递增算法来分配空间;如果选择统一尺寸,则还可以详细指定每个区间(Extent)的大小。

注意如果不指定Uniform Size的大小,Oracle默认为每个区分配1MB大小:
SQL> CREATE TABLESPACE eygle
2 DATAFILE '/opt/oracle/oradata/eygle/eygle01.dbf' SIZE 10 m
3 EXTENT MANAGEMENT LOCAL UNIFORM;

Tablespace created.
SQL> SELECT tablespace_name, extent_management, allocation_type
2 FROM dba_tablespaces where tablespace_name='EYGLE';
TABLESPACE_NAME EXTENT_MAN ALLOCATIO
------------------------------ ---------- ---------
EYGLE LOCAL UNIFORM

这里介绍一个重要视图DBA_EXTENTS:
SQL> desc dba_extents
Name Null? Type
----------------------------------------- -------- ----------------------------
OWNER VARCHAR2(30)
SEGMENT_NAME VARCHAR2(81)
PARTITION_NAME VARCHAR2(30)
SEGMENT_TYPE VARCHAR2(18)
TABLESPACE_NAME VARCHAR2(30)
EXTENT_ID NUMBER
FILE_ID NUMBER
BLOCK_ID NUMBER
BYTES NUMBER
BLOCKS NUMBER
RELATIVE_FNO NUMBER

这个视图记录了每个对象分配的区间(Extent),通过查询这个视图可以看到哪些对象分配了多少区间,以及区间具体位于的文件等信息:
SQL> select extent_id,block_id,blocks
2 from dba_extents where segment_name='TEST' and tablespace_name='EYGLE';
EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------
0 9 128

在本地管理表空间的空间管理上,Oracle将存储信息保存在表空间头部的位图中,而不是保存在数据字典中。通过这样的方式,在分配或者回收空间的时候,表空间就可以独立地在数据文件头部完成操作而无需与其他对象打交道。

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

注意到上面的测试数据,当初始创建第一张数据表时,分配的Block_ID是从第9个Block开始的,也就是说前8个Block都被系统保留了:
SQL> select extent_id,block_id,blocks
2 from dba_extents where segment_name='TEST' and tablespace_name='EYGLE';
EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ----------
0 9 128

在本地管理的表空间中,如果数据库块大小(db_block_size)为16KB或16KB以下,数据文件头保留64KB空间;若是32KB的块大小,则保留128KB。即数据块大小和文件头保留的数据块块数之间的对应关系为:

db_block_size=2 KB,文件头会保留32个数据块;

db_block_size=4 KB,文件头会保留16个数据块;

db_block_size=8 KB,文件头会保留8个数据块;

db_block_size=16 KB,文件头会保留4个数据块;

db_block_size=32 KB,文件头会保留4个数据块。

对于默认8KB块大小的表空间,Oracle保留8个块用于管理,其中数据块1和2用于记录数据文件头信息,数据块3~8用于记录区间的位图信息。

可以通过DUMP方式来简单了解一下保留块所记录的内容。转储数据块信息可以使用如下命令:
alter system dump datafile x block max block_id block min block_id;


使用之前创建的表空间进行测试:
SQL> alter system dump datafile 3 block min 1 block max 3;
System altered.

通过gettrcname.sql脚本获得跟踪文件名称(11g中不再需要使用这个脚本):

SQL> SELECT a.VALUE || b.symbol || c.instance_name ||
'_ora_' || d.spid || '.trc' TRACE_FILE_NAME
2 FROM (SELECT VALUE FROM v$parameter WHERE NAME = 'user_dump_dest') a,
3 (SELECT SUBSTR (VALUE, -6, 1) symbol FROM v$parameter
4 WHERE NAME = 'user_dump_dest') b,
5 (SELECT instance_name FROM v$instance) c,
6 (SELECT spid FROM v$session s, v$process p, v$mystat m
7 WHERE s.paddr = p.addr AND s.SID = m.SID AND m.statistic# = 0) d
8 /
TRACE_FILE_NAME
----------------------------------------------------
----------------------------------
/opt/oracle/admin/eygle/udump/eygle_ora_1301.trc

检查生成的跟踪文件,可以发现,前两个Block记录的是文件头信息:
Start dump data blocks tsn: 4 file#: 3 minblk 1 maxblk 3
Block 1 (file header) not dumped: use dump file header command
buffer tsn: 4 rdba: 0x00c00002 (3/2)
scn: 0x0004.6c1e0b8a seq: 0x02 flg: 0x04 tail: 0x0b8a1d02
frmt: 0x02 chkval: 0x7648 type: 0x1d=KTFB Bitmapped File Space Header
File Space Header Block:
Header Control:
RelFno: 3, Unit: 128, Size: 1280, Flag: 1
AutoExtend: NO, Increment: 0, MaxSize: 0
Initial Area: 7, Tail: 1160, First: 1, Free: 8
Header Opcode:
Save: No Pending Op

注意这里oracle提示我们对于数据文件的第一个块应该用dump file header command,意思就是告诉我们应该用如下的专用于dump datafile header的命令来dump数据文件的第一个块:
alter session set events 'immediate trace name file_hdrs level <n>';

这里的level我们通常用10,意思为dump的内容会包含以下内容:
Control file's datafile entry + generic file header + datafile header

这里摘录一段用上述dump命令dump出来的datafile header block(数据文件的第一个块)的具体内容:
DATA FILE #1:
(name #7) /iprat01/oradata/ipra/system01.dbf
creation size=0 block size=8192 status=0xe head=7 tail=7 dup=1
tablespace 0, index=1 krfil=1 prev_file=0
unrecoverable scn: 0x0000.00000000 01/01/1988 00:00:00
Checkpoint cnt:7030 scn: 0x076e.6ba74f65 05/31/2010 03:00:40
Stop scn: 0xffff.ffffffff 05/28/2010 21:56:50
Creation Checkpointed at scn: 0x0000.00000008 07/22/2005 00:42:44
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
……省略显示部分内容
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
Offline scn: 0x0000.00086982 prev_range: 0
Online Checkpointed at scn: 0x0000.00086983 11/14/2007 16:18:40
thread:1 rba:(0x1.2.0)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
……省略显示部分内容
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
Hot Backup end marker scn: 0x0000.00000000
aux_file is NOT DEFINED
V10 STYLE FILE HEADER:
Compatibility Vsn = 169869568=0xa200100
Db ID=622427550=0x25197d9e, Db Name='IPRA'
Activation ID=0=0x0
Control Seq=193563=0x2f41b, File size=61440=0xf000
File Number=1, Blksiz=8192, File Type=3 DATA
Tablespace #0 - SYSTEM rel_fn:1
Creation at scn: 0x0000.00000008 07/22/2005 00:42:44
Backup taken at scn: 0x0000.00000000 01/01/1988 00:00:00 thread:0
reset logs count:0x2610e3e0 scn: 0x0000.00086983 reset logs
terminal rcv data:0x0 scn: 0x0000.00000000
prev reset logs count:0x21a23e71 scn: 0x0000.00000001 prev
reset logs terminal rcv data:0x0 scn: 0x0000.00000000
recovered at 05/16/2008 11:47:40
status:0x2004 root dba:0x00400179 chkpt cnt: 7030 ctl cnt:7029
begin-hot-backup file size: 0
Checkpointed at scn: 0x076e.6ba74f65 05/31/2010 03:00:40
thread:1 rba:(0x1a0a.2.10)
enabled threads: 01000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
……省略显示部分内容
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
Backup Checkpointed at scn: 0x0000.00000000
thread:0 rba:(0x0.0.0)
enabled threads: 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
……省略显示部分内容
00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
External cache id: 0x0 0x0 0x0 0x0
Absolute fuzzy scn: 0x0000.00000000
Recovery fuzzy scn: 0x0000.00000000 01/01/1988 00:00:00
Terminal Recovery Stamp 01/01/1988 00:00:00
Platform Information: Creation Platform ID: 6
Current Platform ID: 6 Last Platform ID: 6


从第3个块开始,Oracle记录了位图信息:
buffer tsn: 4 rdba: 0x00c00003 (3/3)
scn: 0x0004.6c1e0b8a seq: 0x01 flg: 0x04 tail: 0x0b8a1e01
frmt: 0x02 chkval: 0x8332 type: 0x1e=KTFB Bitmapped File Space Bitmap
File Space Bitmap Block:
BitMap Control:
RelFno: 3, BeginBlock: 9, Flag: 0, First: 1, Free: 63487
0100000000000000 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 0000000000000000 0000000000000000
……

注意这里的01是十六进制,转换为二进制就是0000 0001,按照oracle看bitmap的惯例(以每个byte为一组,组与组之间是从左往右读,但组内是从右往左读),这样翻译过来就是10000000,即"used, free, free, free, free, free, free, free.",也就是代表已经分配了一个区间。

如果再分配一个区间:
SQL> alter table eygle.test allocate extent;
Table altered.
SQL> select file_id,extent_id,block_id,blocks
2 from dba_extents where segment_name='TEST' and tablespace_name='EYGLE';
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
3 0 9 128
3 1 137 128

那么此时的位图变成了:
buffer tsn: 4 rdba: 0x00c00003 (3/3)
scn: 0x0004.6c1e1858 seq: 0x01 flg: 0x00 tail: 0x18581e01
frmt: 0x02 chkval: 0x0000 type: 0x1e=KTFB Bitmapped File Space Bitmap
File Space Bitmap Block:
BitMap Control:
RelFno: 3, BeginBlock: 9, Flag: 0, First: 2, Free: 63486
0300000000000000 0000000000000000 0000000000000000 0000000000000000

这里的03代表0000 0011,经过转换也就是1100 0000,正是代表已经分配了2个区间,所以oracle这里需要free extent的时候是从第3个extent开始扫描(0、1都已经被用了),这也和我们从dba_extents里看到的结果一致。

通过进一步的测试来看一下空间的回收等记录信息,再创建一个测试表,并分配3个区间:
SQL> create table eygle.test2 as select * from dba_objects;
Table created.
SQL> alter table eygle.test2 allocate extent;
Table altered.
SQL> alter table eygle.test2 allocate extent;
Table altered.
SQL> alter table eygle.test2 allocate extent;
Table altered.

加上初始创建分配的一个区间,此时对象test2紧跟test对象共占有4个区间:
SQL> select file_id,extent_id,block_id,blocks
2 from dba_extents where file_id=3;
FILE_ID EXTENT_ID BLOCK_ID BLOCKS
---------- ---------- ---------- ----------
3 0 9 128
3 1 137 128
3 0 265 128
3 1 393 128
3 2 521 128
3 3 649 128

6 rows selected.

这时转储一下文件头可以发现区间位图已经变化为:
RelFno: 3, BeginBlock: 9, Flag: 0, First: 6, Free: 63482
3F00000000000000 0000000000000000 0000000000000000 0000000000000000

3F转换为二进制是0011 1111,经过位交换结果是1111 1100,也就是对应了前6个已经分配的区间。继续创建第三个对象test3:
SQL> create table eygle.test3 as select * from dba_objects;
Table created.


此时位图变化为:
RelFno: 3, BeginBlock: 9, Flag: 0, First: 7, Free: 63481
7F00000000000000 0000000000000000 0000000000000000 0000000000000000

7F对应二进制为0111 1111,经过位交换结果为1111 1110,也就是对应了前7个已经分配的区间。此时DROP掉第二个对象test2:
SQL> drop table eygle.test2;

Table dropped.

SQL> col segment_name for a20
SQL> select segment_name,file_id,extent_id,block_id,blocks
2 from dba_extents where file_id=3;

SEGMENT_NAME FILE_ID EXTENT_ID BLOCK_ID BLOCKS
-------------------- ---------- ---------- ---------- ----------
TEST 3 0 9 128
TEST 3 1 137 128
TEST3 3 0 777 128

此时位图变化为:
RelFno: 3, BeginBlock: 9, Flag: 0, First: 2, Free: 63485
4300000000000000 0000000000000000 0000000000000000 0000000000000000

43对应二进制为0100 0011,经过位交换的结果为1100 0010,也就是文件3的第3~6个区间已经释放。通过这样的位图变化,Oracle就将以前复杂的字典维护变为效率更高的位图维护,从而全面提升了性能。

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

Oracle推出的这种新的表空间管理方法具有一系列的优点,相应地解决了字典管理表空间技术面临的难题,从而迅速地取代了传统的DMT技术,本地管理表空间技术的主要优点如下。

通过位图代替字典管理。本地管理的表空间用数据文件头部的位图块来记录和管理空间的分配和回收,避免了递归的空间管理操作,从而避免了字典操作以及因为字典操作而带来的性能问题。

避免了碎片问题及空间浪费。本地化管理可以通过UNIFORM或AUTOALLOCATE的方式进行区间管理,通过对Extent进行UNIFORM约定,传统的空间碎片问题得以解决,进而空间的分配效率也大大提高。

正因为本地管理表空间技术的卓越性能,我们已经可以放心地将DMT称之为过去时了。


.本地管理表空间与字典管理表空间的比较

1.减少了递归空间管理
本地管理表空间是自己管理分配,而不是象字典管理表空间需要系统来管理空间分配,本地表空间是通过在表空间的每个数据文件中维持一个位图来跟踪在此文件中块的剩余空间及使用情况。并及时做更新。这种更新只对表空间的额度情况做修改而不对其他数据字典表做任何update操作,所以不会产生任何回退信息,从而大大减少了空间管理,提高了管理效率。同时由于本地管理表空间可以采用统一大小分配方式(UNIFORM),因此也大大减小了空间管理,提高了数据库性能。

2.系统自动管理extents大小或采用统一extents大小
本地管理表空间有自动分配(AUTOALLOCATE)和统一大小分配(UNIFORM)两种空间分配方式,自动分配方式(AUTOALLOCATE)是由系统来自动决定extents大小,而统一大小分配(UNIFORM)则是由用户指定extents大小。这两种分配方式都提高了空间管理效率。

3.减少了数据字典之间的竞争
因为本地管理表空间通过维持每个数据文件的一个位图来跟踪在此文件中块的空间情况并做更新,这种更新只修改表空间的额度情况,而不涉及到其他数据字典表,从而大大减少了数据字典表之间的竞争,提高了数据库性能。

4.不产生回退信息
因为本地管理表空间的空间管理除对表空间的额度情况做更新之外不修改其它任何数据字典表,因此不产生回退信息,从而大大提高了数据库的运行速度。

5.不需合并相邻的剩余空间
因为本地管理表空间的extents空间管理会自动跟踪相邻的剩余空间并由系统自动管理,因而不需要去合并相邻的剩余空间。同时,本地管理表空间的所有extents还可以具有相同的大小,从而也减少了空间碎片。

6.减少了空间碎片

7.对临时表空间提供了更好的管理

你可能感兴趣的:(oracle,sql,数据库,File,header,Dictionary)