原作者:柴田長(日本Oracle)

第一回,让我们针对表空间来做一些练习。

对于每一个练习,我们将总结出答案和回答的例子,大家可以跟自己的答案来比较一下。

此外,在SQL中使用的目录结构是基于Linux的。


■练习1。请创建一个名为[TBS_SMALL]的Small File表空间。这个表空间需要使用三个100MB的数据文件来构成。

SQL> create tablespace TBS_SMALL datafile '/oracle_datafile1/tbs_small01.dbf' size 100M,                                           '/oracle_datafile1/tbs_small02.dbf' size 100M,                                           '/oracle_datafile2/tbs_small03.dbf' size 100M;

可能有些人还是第一次听到【Small File表空间】这样的说法。其实,从Oracle Database10g Release 1

开始出现了【Big File表空间】,所以,以前传统的表空间就被称为【Small File表空间】了。

在这里希望可以理解,Small File表空间是可以由多个数据文件构成的。在以前32位的操作系统上,

一个文件的最大限制为2GB ,当你想做成一个超过2GB的表空间时,这个功能会非常有效。

当然,在进化成64位系统以后,对于这个文件大小2GB的限制,在操作系统层面已经不用再做过多考虑,

但是作为Oracle数据库来说,还是要注意数据文件大小是有限制的。

Small File表空间中的一个数据文件大小的最大值:

[表空间的Block Size] × 4194303(= 2^22 -1)  Block Size=8KB的话,大约是32GB(一个数据文件内的 数据块号要使用22bit来管理,另外,Block Size的大小也会影响计算结果) 顺便说一句,像上面回答例中的DDL一样,使用不同文件夹下的数据文件来做成一个表空间也是可以的。 但是ASM和BigFile表空间组合使用的情况下,其实并不需要考虑这个问题(以后再找机会介绍)。 ■练习2。通过数据字典视图【DBA_DATA_FILES】来确认TBS_SMALL表空间的大小。 SQL> select tablespace_name, sum(bytes)/1024/1024 "size(MB)" from DBA_DATA_FILES where tablespace_name = 'TBS_SMALL' group by tablespace_name; TABLESPACE_NAME                  size(MB) ------------------------------ ---------- TBS_SMALL                             300 Oracle数据库里准备了大量的数据字典视图,可以用来确认数据库内部的设定信息等。 作为DBA来讲,不是仅仅执行完DDL语句就结束了,执行后的结果确认也是非常重要的。 练习2中使用的数据字典视图【DBA_DATA_FILES】,可以用来确认全部数据文件的各种信息。 比如各个数据文件属于哪个表空间。 根据上面的Select语句,就可以看出,TBS_SMALL表空间里的三个数据文件大小合计 (300MB = 100MB + 100MB + 100MB)。如果结果不是300MB, 那么练习1中表空间做成的时候可能存在误操作。 关于数据字典视图中各列所表示的意思,请参考相关的说明文档。 ■练习3。向TBS_SMALL表空间中追加新的数据文件,使其大小扩大至400MB。 SQL> alter tablespace TBS_SMALL add datafile '/oracle_datafile2/tbs_small04.dbf' size 100M; 很简单吧?通过向SMALL FILE表空间内追加数据文件,可以实现将表空间扩大的目的。 ■练习4。把TBS_SMALL表空间的大小扩大至500MB。 SQL> alter tablespace TBS_SMALL add datafile '/oracle_datafile2/tbs_small05.dbf' size 100M; 打算使用跟练习3一样的语句的各位,先等一下。 这个语句当然是没问题的,但是当我想把表空间扩大至50GB的话,怎么办呢? 要重复500次这样的操作的话,需要花费相当多的时间。 做成以后,数据文件的维护显而易见也会成为一个×××烦。 而且,一个SMALL FILE表空间内可以包含的数据文件个数的上限是1022个,不能无限的追加下去。 所以,练习4,我们使用另外一个扩大表空间的办法,也就是扩大数据文件的大小。 SQL> alter database datafile '/oracle_datafile1/tbs_small01.dbf' resize 125M; SQL> alter database datafile '/oracle_datafile1/tbs_small02.dbf' resize 125M; SQL> alter database datafile '/oracle_datafile2/tbs_small03.dbf' resize 125M; SQL> alter database datafile '/oracle_datafile2/tbs_small04.dbf' resize 125M; 当然,只把其中第4个文件的大小改为200MB也是可以实现要求的,但是这样的组成不太整齐不是吗。 作为一个老资格的DBA,当然是所有的数据文件大小都一直才会觉得舒服。 其实,这样做是有理由的。举个例子,表里的数据被均等的分布在各个数据文件, 100MB的数据文件满了的时候,只有这个200MB的数据文件还有空间了, 这时候,数据文件的写入就全部集中于这个文件上了。 当目录【/oracle_datafile】和【/oracle_datafile2】在不同的磁盘上的时候, 对于特定的磁盘的写入就会很集中,则会产生性能下降的可能。 另外,从各个磁盘上读取的数据量也有可能会发生偏移。 所以,这次我们对存在的4个数据文件都做了同样大小的扩大。 通过这项练习,希望大家体会到的有2点。 第一点,虽然是对表空间进行变更时,但是使用的语句不是【alter tablespace】 而是【alter database】来进行数据文件大小的变更。 第二点,数据文件的数量越多,维护起来就越难。 尤其是在使用裸设备放置数据文件的时候,是很难扩大数据文件的大小的。 所以随着表空间大小的扩大,需要被管理的裸设备以及数据文件数都会增加。 此外,也许有人有过这样的经验,由于新追加的数据文件都是空的, 所以在追加数据文件后还要通过对数据做一次导出然后再做一次导入来避免问题。 (不过这个问题在ASM上已经可以得到解决) 完成扩大数据文件的操作后,可以使用下面的Select语句来进行查询,使用rollup的话,会很方便。 SQL> select tablespace_name, file_name, sum(bytes)/1024/1024 "size(MB)" from DBA_DATA_FILES        where tablespace_name = 'TBS_SMALL'        group by tablespace_name, rollup(file_name); TABLESPACE_NAME                FILE_NAME                                          size(MB) ------------------------------ ------------------------------------------------ ---------- TBS_SMALL                      /oracle_datafile1/tbs_small01.dbf                       125 TBS_SMALL                      /oracle_datafile1/tbs_small02.dbf                       125 TBS_SMALL                      /oracle_datafile2/tbs_small03.dbf                       125 TBS_SMALL                      /oracle_datafile2/tbs_small04.dbf                       125 TBS_SMALL                                                                              500 ■练习5。做一个名为【TBS_BIG】的Big File表空间。表空间的大小设置为300MB。 SQL> create bigfile tablespace TBS_BIG datafile '/oracle_datafile1/tbs_big01.dbf' size 100M,                                                 '/oracle_datafile1/tbs_big02.dbf' size 100M,                                                 '/oracle_datafile2/tbs_big03.dbf' size 100M; 上面的语句,会执行失败。错误代码ORA-32774。 发生错误的原因,是因为BIGFILE表空间里只允许指定一个数据文件。 这样的话,对于多个数据文件的管理上的工作量就会少很多。 但是,可以包含多个数据文件的SMALLFILE表空间不是可以做扩大的吗?BIGFILE是什么样的呢? 首先看一下Big File表空间中的数据文件大小的最大值: [表空间的Block Size] × 4294967295 (= 2^32 -1)  Block Size=8KB的话,大约是32TB。 BigFile表空间的数据文件大小的最大值是SmallFile表空间中一个数据文件大小的最大值的1000倍。 这是因为BigFile表空间里只限定使用一个数据文件,而SmallFIle表空间里为了识别多个数据文件 而使用的10bit可以用来存放数据块号了(22bit+10bit=32bit)。 不过,由于SmallFile表空间中可以有1022个数据文件,因此表空间的最大大小,都是32TB左右。 那么使用BigFile表空间又有什么好处呢。 在这里,新的数据库限制要登场了。 那就是,一个数据库内数据文件的最大个数(通常情况下为64000个)。 因为存在这个限制,所以可以考虑使用BigFile表空间来大幅增加数据库的容量。 说明有点长了,练习5的答案在这里: SQL> create bigfile tablespace TBS_BIG datafile '/oracle_datafile1/tbs_big.dbf' size 300M; ■练习6。通过数据字典视图DBA_TABLESPACES来确认表空间TBS_BIG是BIGFILE表空间 SQL> select tablespace_name,bigfile from dba_tablespaces where tablespace_name in ('TBS_SMALL','TBS_BIG') TABLESPACE_NAME                BIGFILE ------------------------------ ---------------- TBS_BIG                        YES TBS_SMALL                      NO 这里再多说一点。练习1中执行的create tablespace命令,实际上在做成表空间的时候命令 是create smallfile tablespace。认为不指定smallfile的时候会默认做成smallfile表空间的人一定会有, 但实际上默认表空间的类型是依存于默认表空间类型的。确认默认表空间类型的SQL如下: SQL> -- Checking Default Tablespace Type   col property_value for a32   select PROPERTY_NAME, PROPERTY_VALUE     from DATABASE_PROPERTIES     where PROPERTY_NAME = 'DEFAULT_TBS_TYPE'; SQL> -- Setting Default Tablespace Type [BIGFILE]   alter database set default BIGFILE tablespace; SQL> -- Setting Default Tablespace Type [SMALLFILE]   alter database set default SMALLFILE tablespace;    ■练习7。用任意方法把表空间TBS_BIG的大小扩大为500MB。 SQL> alter database datafile '/oracle_datafile1/tbs_big.dbf' resize 500M; 用的是跟练习4一样的方法的话,当然是不会有错的。 不过这也是作者尽量考虑到各个方面而想出来的问题,大家没有产生怀疑吗? 是的,我期待的完美回答其实是下面这样的: SQL> alter tablespace TBS_BIG resize 500M; 希望大家可以产生一种“Bigfile表空间的话,管理起来会比较容易”的感觉。 smallfile表空间的话的扩大,需要使用alter database并且指定数据文件名的方式来实施。 而bigfile表空间的话的扩大,不用考虑数据文件名,直接使用alter tablespace这样直观的命令来做, 这样不需要再通过数据字典视图去确认数据文件的名称了。 通过上面的联系,我们已经学会生成表空间的方法了。create tablespace语句,除了这里介绍的, 其实还可以指定很多其他选项。但是大多数场合,这些选项不指定(使用默认值)也是没问题的。 为了详细理解,段和区的构造也是需要去好好把握的。这里就不做过多的延伸了。 SMALLFILE表空间和BIGFILE表空间的区别,还是要通过手册去好好研究。 想成为一个DBA的话,一定要去读一读这些手册。 下回,我们来说说【表和表空间的关系】。