在Oracle9i Database之前,假如在创建用户时没有指定默认表空间,那么它将默认为SYSTEM 表空间。假如用户在创建一个段时没有显式地指定一个表空间,那么这个段将在 SYSTEM 中创建—前提是用户在 SYSTEM 表空间中拥有配额(要么显式地授予,要么通过系统权限 UNLIMITED TABLESPACE 来授予)。Oracle9i 答应DBA为所有未用显式的临时表空间子句创建的用户指定一个默认的临时表空间,从而减少了这个问题。
在 Oracle Database 10g 中,您可以类似地为用户指定一个默认表空间。在数据库创建期间,CREATE DATABASE 命令可以包含子句 DEFAULT TABLESPACE 。在创建之后,您可以通过发出以下命令来使一个表空间变成默认表空间:
ALTER DATABASE DEFAULT TABLESPACE <tsname>;
未用 DEFAULT TABLESPACE 子句创建的所有用户将以作为它们的默认表空间。您可以在任何时候通过这个 ALTER 命令来改变默认表空间,从而答应您在不同的节点上将不同的表空间指定为默认表空间。
重要注重事项:拥有旧的表空间的所有用户的默认表空间都被修改为,即使有些表空间是为某些用户显式指定的。例如,假定用户 USER1 和 USER2 的表空间分别是 TS1 和 TS2 — 它们是在用户创建期间显式指定的。数据库当前的默认表空间是 TS2,但之后,数据库的默认表空间变为 TS1。即使 USER2 的默认表空间是显式指定为 TS2 的,它也将变为 TS1。小心这种边界效应!
假如在数据库创建期间没有指定默认表空间,它将默认为 SYSTEM。但您如何才能知道现有的数据库的默认表空间是哪一个?发出以下查询:
SELECT PROPERTY_VALUE
FROM DATABASE_PROPERTIES
WHERE PROPERTY_NAME = 'DEFAULT_PERMANENT_TABLESPACE';
DATABASE_PROPERTIES 视图显示默认表空间之外,还显示一些非常重要的信息 — 例如默认临时表空间、全局数据库名、时区等。
非必要模式的默认表空间
几种模式(如智能代理用户 DBSNMP、数据挖掘用户 ODM)与用户操作不直接相关,但对数据库完整性仍很重要。这些模式中的一些曾经用 SYSTEM 作为它们的默认表空间 — 这是在 SYSTEM 表空间内对象增殖的又一个原因。
Oracle Database 10g 引进了一个新的称为 SYSAUX 的表空间,它用来保存这些模式的对象。这个表空间是在数据库创建期间自动创建的,并在本地进行治理。唯一答应修改的是数据文件的名称。
这种方法在 SYSTEM 损坏需要完整的数据库恢复时,为恢复提供支持。SYSAUX 中的对象可以被恢复为任意正常的用户对象,同时数据库本身保持运行。
但假如您想将 SYSAUX 中的这些模式中的一些转移到一个不同的表空间中时,该怎么办?例如,考虑 LogMiner 使用的对象,这些对象的大小经常增长,直到最终填满表空间。出于可治理性的原因,您可能考虑将它们转移到它们自己的表空间中。但实现这一目的的最好的方法是什么?
作为一个数据库治理员,了解转移这些非凡对象的正确过程对您而言是很重要的。幸运的是,Oracle Database 10g 提供了一个新的视图使要凭猜测来做的工作形象化。这个视图,V$SYSAUX_OCCUPANTS,列出了表空间 SYSAUX 中的模式的名称、它们的说明、当前使用的空间,以及如何转移它们。
注重 LogMiner 如何被清楚地显示为占用 7,488 KB 的空间。它归模式 SYSTEM 所有,而要转移对象,您需要执行打包的过程 SYS.DBMS_LOGMNR_D.SET_TABLESPACE。不过,对于 STATSPACK 对象,这个视图推荐使用导入/导出方法;而对于流,没有转移过程 — 因而您不能轻易地将它们从 SYSAUX 表空间中转移出来。列 MOVE_PROCEDURE 默认显示 SYSAUX 中存在的几乎所有工具的正确的转移过程。也可以逆向使用转移过程来使对象回到 SYSAUX 表空间中。
重命名一个表空间
在数据仓库环境中(典型地,对于数据中心体系结构),在数据库之间传输表空间是很常见的。但源数据库和目标数据库必须不存在拥有相同名称的表空间。假如存在两个拥有相同名称的表空间,则目标表空间中的段必须转移到一个不同的表空间中,然后重新创建这个表空间— 这个任务说起来轻易做起来难。
Oracle Database 10g 提供了一个方便的解决方案:您可以用以下命令来简单地重命名一个现有的表空间(SYSTEM 和 SYSAUX 除外) — 无论是永久表空间还是临时表空间:
ALTER TABLESPACE <oldname> RENAME TO <newname>;
这个功能还将应用在存档过程中。假定您有一个按范围分区的表,用于记录销售历史数据,每个月的这个分区位于按这个月份命名的一个表空间中 — 例如,1 月份的分区命名为 JAN,并位于一个名称为 JAN 的表空间中。这样您就拥有了一个将信息保留 12 个月的策略。在 2004 年 1 月,您将能够存档 2003 年 1 月的数据。大致的操作流程类似于以下操作:
◆利用 ALTER TABLE EXCHANGE PARTITION 从分区 JAN 中创建一个独立的表 JAN03。
◆将表空间重命名为 JAN03。
◆为表空间 JAN03 创建一个可传输表空间集。
◆将表空间 JAN03 重新命名为 JAN。
◆将空的分区交换回表中。
第 1、2、4 和 5 步很简单,并且不会过度地消耗资源(如重做和撤消空间)。第 3 步只是拷贝文件并只为 JAN03 输出数据字典信息,这也是个非常轻松的过程。假如您需要恢复之前存档的分区,这个过程也非常简单,您只需要将相同的过程反过来就行了。
Oracle Database 10g 在处理这些重命名的方式上相当智能化。假如您重命名作为 UNDO 或默认临时表空间的表空间,这可能产生混淆。但数据库将自动调整必要的记录来反映这种变化。例如,将默认表空间的名称从 USERS 修改为 USER_DATA 将自动修改视图 DATABASE_PROPERTIES。在修改之前,查询:
select property_value from database_properties
where property_name = 'DEFAULT_PERMANENT_TABLESPACE';
返回 USERS。在运行下面的语句之后:
alter tablespace users rename to user_data;
上述查询返回 USER_DATA,因为所有对 USERS 的引用都被修改为到 USER_DATA。修改默认临时表空间的情况一样。甚至修改 UNDO 表空间的名称也将触发 SPFILE 中的变化,如下所示:
SQL> select value from v$spparameter
where name = 'undo_tablespace';
VALUE
--------
UNDOTBS1
SQL> alter tablespace undotbs1 rename to undotbs;
Tablespace altered.
SQL> select value from v$spparameter
where name = 'undo_tablespace';
VALUE
--------
UNDOTBS
结论
在最近的几个 Oracle 版本演变的过程中,对象处理得到了稳定的增强。Oracle8i 引进了表从一个表空间到另一个表空间的转移,Oracle 9i Database R2 引进了列重命名,现在 — 在最新的版本中 — 表空间自身的重命名成为可能。这些增强显著地减轻了数据库治理员的任务 — 非凡是在数据仓库或数据中心环境中。