第六章 表空间和数据文件的管理
6.1 Oracle引入逻辑结构的目的
Oracle数据库管理系统并没有像不少其它数据库管理系统那样直接地操作数据文件,而是引入一组逻辑结构。如图6-1所示。
图6-1 图6-1的虚线左边为逻辑结构,右边为物理结构。与计算机原理或计算机操作系统中所讲的有些不同,在Oracle数据库中,逻辑结构为Oracle引入的结构,而物理结构为操作系统所拥有的结构。
曾有不少学生问过我同样的一个问题,那就是Oracle为什么要引入逻辑结构呢? 首先可能是为了增加Oracle的可移植性。Oracle公司声称它的Oracle数据库是与IT平台无关的,即在某一厂家的某个操作系统上开发的Oracle数据库(包括应用程序等)可以几乎不加修改地移植到另一厂家的另外的操作系统上。要做到这一点就不能直接操作数据文件,因为数据文件是跟操作系统相关的。
其次可能是为了减少Oracle从业人员学习的难度。因为有了逻辑结构Oracle的从业人员就可以只对逻辑结构进行操作,而在所有的IT平台上逻辑结构的操作都几乎完全相同,至于从逻辑结构到物理结构的映射(转换)是由Oracle数据库管理系统来完成的。
6.2 Oracle数据库中存储结构之间的关系
其实图6-1类似于一个Oracle数据库的存储结构之间关系的实体-关系图。如果读者学过实体-关系模型(E-R模型)的话,从图6-1中可以很容易地得到Oracle数据库中存储结构之间的关系。为了帮助那些没有学过E-R模型的读者理解图6-1,也是为了帮助那些学过但已经忘的差不多了的读者恢复一下记忆,在下面对E-R模型和图6-1给出一些简单的解释。
在图6-1中,园角型方框为实体,实线表示关系,单线表示一的关系,三条线(鹰爪)表示多的关系。于是可以得到:
? 每个数据库是由一个或多个表空间所组成(至少一个)。 ? 每个表空间基于一个或多个操作系统的数据文件(至少一个)。 ? 每个表空间中可以存放有零个或多个段(Segment)。 ? 每个段是由一个或多个区段(Extent)所组成。
? 每个区段是由一个或多个连续的Oracle数据块所组成。
? 每个Oracle数据块是由一个或多个连续的操作系统数据块所组成。 ? 每个操作系统数据文件是由一个或多个区段(Extent)所组成。 ? 每个操作系统数据文件是由一个或多个操作系统数据块所组成。
有关段,区段,和Oracle数据块等我们在接下来的章节中要详细地介绍。
6.3 表空间和数据文件之间的关系及表空间的分类
通过前面的讨论可知:Oracle将数据逻辑地存放在表空间里,而物理地存放在数据文件里。表空间(Tablespaces)在任何一个时刻只能属于一个数据库,但是反过来并不成立,因为一个数据库一般都有多个表空间。每个表空间都是由一个或多个操作系统的数据文件所组成,但是一个操作系统的数据文件只能属于一个表空间。
表空间可以被进一步划分成一些更小的逻辑存储单位。在一个Oracle数据库中,每个数据文件(Data files)可以而且只能属于一个表空间和一个数据库。数据文件实际上是存储模式对象数据的一个容器/仓库。
在一个Oracle数据库中一般有两类表空间,他们是系统(SYSTEM)表空间和非系统(Non-SYSTEM)表空间。
系统(SYSTEM)表空间是与数据库一起建立的,在系统表空间中存有数据字典,在系统表空间中还包含了系统还原(回滚)段。虽然在系统表空间中可以存放用户数据,但考虑到Oracle系统的效率和管理上的方便,在系统表空间上不应该存放任何用户数据。非系统(Non-SYSTEM)表空间可以由数据库管理员创建,在非系统表空间中存储一些单独的段,这些段可以是用户的数据段,索引段,还原段,和临时段等。引入非系统表空间可以方便磁盘空间的管理,也可以更好地控制分配给用户磁盘空间的数量。引入非系统表空间还可以将静态数据和动态数据有效地分开,也可以按照备份的要求将数据分开存放。使用如下的命令创建一个非系统表空间:CREATE TABLESPACE表空间名 [DATAFILE子句] [MINIMUM EXTENT 正整数[K|M]] [BLOCKSIZE正整数[K]] [LOGGING|NOLOGGING] [DEFAULT 存储子句] [ONLINE|OFFLINE] [PERMANENT|TEMPORARY] [区段管理子句] [段管理子句]
在这里对以上命令中的一些子句和选项给出进一步的解释: 表空间名:所要创建的表空间名。
DATAFILE子句:组成所要创建的表空间的文件说明。
MINIMUM EXTENT:表空间中所使用的每个EXTENT都必须是该参数所指定数的整数倍。 BLOCKSIZE:为该表空间说明非标准块的大小。在使用这一子句之前,您必须先设置
DB_CACHE_SIZE参数和DB_nK_CACHE_SIZE参数,而且该子句中所说明的正整数一定与DB_nK_CACHE_SIZE参数的设定相对应。
LOGGING: 说明在该表空间中所有数据的变化都将写入重做日志文件中,这也是默认
方式。
NOLOGGING: 说明在该表空间中所有数据的变化不都写入重做日志文件中,NOLOGGING
只影响一些DML和DDL命令。
DEFAULT存储子句:说明所有在该表空间中所创建的对象的默认存储参数。 OFFLINE:说明该表空间在创建后立即被置为脱机,即不能使用。 还有一些其它的子句和选项我们将在后续的章节中陆续地介绍。
6.4 表空间中的磁盘空间管理
在Oracle8.0和更早的版本中所有表空间中的磁盘空间管理都是由数据字典来管理的。在这种表空间的管理方法中所有的空闲区由数据字典来统一管理。每当区段被分配或收回时,Oracle服务器将修改数据字典中相应的(系统)表。
在数据字典(系统)管理的表空间中所有的EXTENTS的管理都是在数据字典中进行的,而且每一个存储在同一个表空间中的段可以具有不同的存储子句。在这种表空间的管理方法中您可以按您的需要修改存储参数,所以存储管理比较灵活但系统的效率较低。还有如果使用这种表空间的管理方法,有时需要合并碎片。由于Oracle8.0对互联网的成功支持和它在其它方面的卓越表现使得Oracle的市场占有率急速地增加,同时Oracle数据库的规模也开始变的越来越大。这样在一个大型和超大型数据库中就可能有成百乃至上千个表空间。由于每个表空间的管理信息都存在数据字典中,也就是存在系统表空间中。这样系统表空间就有可能成为一个瓶颈从而使数据库系统的效率大大地下降。
正是为了克服以上弊端,Oracle公司从它的Oracle8i开始引入了另一种表空间的管理方法,叫做本地管理的表空间。
本地管理的表空间其空闲EXTENTS是在表空间中管理的,它是使用位图(Bitmap)来记录空闲EXTENTS,位图中的每一位对应于一块或一组块,而每位的值指示空闲或分配。当一个EXTENT被分配或释放时,Oracle服务器就会修改位图中相应位的值以反映该EXTENT的新的状态。位图存放在表空间所对应的数据文件的文件头中。
使用本地管理的表空间减少了数据字典表的竞争,而且当磁盘空间分配或收回时也不会产生回滚(还原),它也不需要合并碎片。在本地管理的表空间中您无法按您的需要来随意地修改存储参数,所以存储管理不像数据字典(系统)管理的表空间那样灵活但系统的效率较高。
因为在本地管理的表空间中,表空间的管理,如磁盘空间的分配与释放等已经不在需要操作数据字典了,所以系统表空间的瓶颈问题得到了很好的解决。因此Oracle公司建议用户创建的表空间应该尽可能地使用本地管理的表空间。在Oracle9i中本地管理的表空间为默认方式,但是在Oracle8i中数据字典(系统)管理的表空间为默认方式。
6.5 创建数据字典管理的表空间
曾有位著名的学者在一份非常出名的报纸上发表了一篇震撼了整个神州大地的文章,文章的题目是:“中国妇女解放运动的先驱-潘金莲”。这篇文章一发表就在社会上引发了激烈的争论,真是“一石击起千层浪”。一位考古学的博士想利用统计学的方法科学地证明潘金莲到底是不是中国妇女解放的先驱。首先他必须将大量的数据分门别类地存入数据库中。他找到了您让您在Oracle数据库方面帮他的忙。
您决定首先要为这个项目创建一个名为jinlian(金莲)的表空间。为了平衡I/O,您决定该表空间将基于两个数据文件,它们分别是J:\\DISK2\\MOON\\JINLIAN01.DBF和J:\\DISK4\\MOON\\JINLIAN02.DBF,其大小都为50M(在实际中可能几百M)。为了更有效地控制磁盘的存储分配,您决定使用数据字典管理的表空间。为了防止用户在创建对象时使用的EXTENT过小而产生过多的碎片,您决定最小的EXTENT为50K(MINIMUM EXTENT 50K)。当需要磁盘空间的自动分配时第一次分配为50K(INITIAL 50K),第二次也为50K(NEXT 50K),所分配的最大磁盘空间为100个EXTENTS(MAXEXTENTS 100)。从第三次分配开始按如下的
(n-2)
公式进行分配:NEXT * (1+PCTINCREASE/100)。其中n为分配的次数。于是你发出了如
例6-1的SQL语句来创建名为jinlian(金莲)的表空间。
例6-1SQL> CREATE TABLESPACE jinlian
2 DATAFILE 'J:\\DISK2\\MOON\\JINLIAN01.DBF' SIZE 50 M, 3 'J:\\DISK4\\MOON\\JINLIAN02.DBF' SIZE 50 M 4 MINIMUM EXTENT 50K EXTENT MANAGEMENT DICTIONARY
5 DEFAULT STORAGE (INITIAL 50K NEXT 50K MAXEXTENTS 100 PCTINCREASE 0); 表空间已创建。
紧接着为了验证所创建的表空间是不是数据字典管理的,您使用了如例6-4的SQL查询语句。但为了使该语句的显示结果更清晰,您又使用了例6-2和例6-3的SQL*Plus命令对输出进行了格式化。
例6-2
SQL>SET LINE 120 例6-3
SQL> COL TABLESPACE_NAME FOR A15 例6-4
SQL> SELECT tablespace_name, block_size, extent_management, segment_space_management 2 FROM dba_tablespaces;
TABLESPACE_NAME BLOCK_SIZE EXTENT_MAN SEGMEN --------------- ---------- ---------- ------ SYSTEM 4096 DICTIONARY MANUAL UNDOTBS 4096 LOCAL MANUAL CWMLITE 4096 LOCAL MANUAL DRSYS 4096 LOCAL MANUAL EXAMPLE 4096 LOCAL MANUAL INDX 4096 LOCAL MANUAL TEMP 4096 LOCAL MANUAL TOOLS 4096 LOCAL MANUAL USERS 4096 LOCAL MANUAL JINLIAN 4096 DICTIONARY MANUAL 已选择10行。
例6-4查询语句的结果表明表空间jinlian(金莲)确实是一个数据字典管理的表空间,因为extent_management列的显示结果为DICTIONARY。现在您可以使用如例6-5的SQL查询语句来验证其它的磁盘存储参数。
例6-5
SQL> select tablespace_name, initial_extent, next_extent, 2 max_extents, pct_increase, min_extlen 3 from dba_tablespaces;
TABLESPACE_NAME INITIAL_EXTENT NEXT_EXTENT MAX_EXTENTS PCT_INCREASE MIN_EXTLEN --------------- -------------- ----------- ----------- ------------ ---------- SYSTEM 12288 12288 249 50 0 UNDOTBS 65536 2147483645 65536 CWMLITE 65536 2147483645 65536 DRSYS 65536 2147483645 65536 EXAMPLE 65536 2147483645 65536
INDX 65536 2147483645 65536 TEMP 1048576 1048576 0 1048576 TOOLS 65536 2147483645 65536 USERS 65536 2147483645 65536 JINLIAN 53248 53248 100 0 53248 已选择10行。
从例6-5查询语句的结果显示可以清楚地看出:所有的存储参数都是按您的要求设置的,因为INITIAL_EXTENT为50K(53248字节),NEXT_EXTENT也为50K(53248字节),MIN__EXTENT(MINIMUM EXTENT)也同样为50K(53248字节),最后MAX__EXTENTS(MAXEXTENTS)为100。此时您还应使用如例6-6的SQL查询语句来验证一下与文件有关的信息。
例6-6
SQL> select file_id, file_name, tablespace_name 2 from dba_data_files 3 order by file_id;
FILE_ID FILE_NAME TABLESPACE_NAME ---------- --------------------------------------------- --------------- 1 D:\\ORACLE\\ORADATA\\ORACLE9I\\SYSTEM01.DBF SYSTEM 2 D:\\ORACLE\\ORADATA\\ORACLE9I\\UNDOTBS01.DBF UNDOTBS 3 D:\\ORACLE\\ORADATA\\ORACLE9I\\CWMLITE01.DBF CWMLITE 4 D:\\ORACLE\\ORADATA\\ORACLE9I\\DRSYS01.DBF DRSYS 5 D:\\ORACLE\\ORADATA\\ORACLE9I\\EXAMPLE01.DBF EXAMPLE 6 D:\\ORACLE\\ORADATA\\ORACLE9I\\INDX01.DBF INDX 7 D:\\ORACLE\\ORADATA\\ORACLE9I\\TOOLS01.DBF TOOLS 8 D:\\ORACLE\\ORADATA\\ORACLE9I\\USERS01.DBF USERS 9 J:\\DISK2\\MOON\\JINLIAN01.DBF JINLIAN 10 J:\\DISK4\\MOON\\JINLIAN02.DBF JINLIAN 已选择10行。
从例6-6查询语句的结果显示可以清楚地看出:表空间JINLIAN共有两个操作系统文件它们分别是J:\\DISK2\\MOON\\JINLIAN01.DBF和J:\\DISK4\\MOON\\JINLIAN02.DBF。最后您还应该利用操作系统工具,如NT资源管理器来验证一下真正的物理文件是否真的生成了。如例6-7所示。
例6-7
从例6-7的结果显示可以清楚地看出物理文件J:\\DISK2\\MOON\\JINLIAN.DBF确实已经生成,其大小也为50M。您还应该使用相同的方法验证表空间JINLIAN的另一个操作系统文件。
6.6 创建本地管理的表空间
接下来您决定还要为这个项目创建一个名为jinlian_index的索引表空间。该表空间只基于一个数据文件,其文件名是J:\\DISK6\\MOON\\JINLIAN_INDEX.DBF,其大小为50M(在实际中可能为几百M)。为了方便磁盘存储的管理,您决定使用本地管理的表空间(EXTENT MANAGEMENT LOCAL)。根据您的调查,您决定每个EXTENT的大小为1M(UNIFORM SIZE 1M)。于是您发出了如例6-8的DDL语句来创建名为jinlian_index的索引表空间。
例6-8
SQL> CREATE TABLESPACE jinlian_index