ORA-00959 解决一例

     军卫的数据库,大多数是从Oracle7.3 升级到8i,再升级到11G, Oracle73时有一个表空间USER_DATA, 一般情况下,多次升级时都会保留下来。

此次在搭建开发数据库时,为给数据库瘦身,需去掉多余的表空间。 在删除USER_DATA表空间前,确保USER_DATA表空间上没有数据库对象。数据库版本为X64-11.2.0.1

一、在下面的操作中,发现了以下的问题:

SQL> show user

USER 为 "SYSTEM"

SQL> select default_tablespace from dba_users where username='SYSTEM';

DEFAULT_TABLESPACE

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

USER_DATA

SQL> CREATE TABLE PBCATFMT

  2  (

  3    PBF_NAME  VARCHAR2(30 BYTE),

  4    PBF_FRMT  VARCHAR2(254 BYTE),

  5    PBF_TYPE  INTEGER,

  6    PBF_CNTR  INTEGER

  7  )  ;

CREATE TABLE PBCATFMT

*

ERROR at line 1:

ORA-00959: tablespace 'USER_DATA' does not exist

由于system 用户的缺省表空间是USER_DATA,自然ORA-00959: 错误出现很正常。

SQL> alter user system  default tablespace users;

User altered.

SQL> select default_tablespace from dba_users where username='SYSTEM';

DEFAULT_TABLESPACE

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

USERS

SQL> CREATE TABLE PBCATFMT

  2  (

  3    PBF_NAME  VARCHAR2(30 BYTE),

  4    PBF_FRMT  VARCHAR2(254 BYTE),

  5    PBF_TYPE  INTEGER,

  6    PBF_CNTR  INTEGER

  7  )  ;

Table created.

表可以创建成功。

SQL>  CREATE   INDEX PBSYSCATFRMTS_IDX  ON pbcatfmt(pbf_name);

 CREATE   INDEX PBSYSCATFRMTS_IDX  ON pbcatfmt(pbf_name)

                                      *

ERROR at line 1:

ORA-00959: tablespace 'USER_DATA' does not exist

没有指定表空间时,索引创建缺省使用的是创建者的缺省表空间,为什么在这还报错呢?

我重新创建'USER_DATA' 表空间,并重新执行上面的索引创建语句, 自然可以创建成功,查询数据字典,该索引的确也在USERS 表空间上, USER_DATA'表空间上没有数据库对象。

二、原因查找

 按照以往的经验,由于这个表是新建的,不存在其它使用USER_DATA 表空间上的触发器或索引。在没有USER_DATA 表空间 的情况下,如果指定表空间,例如 CREATE   INDEX PBSYSCATFRMTS_IDX  ON pbcatfmt(pbf_name)  tablespace users ;  是可以执行成功的。那么数据库后面到底做了些什么?

 使用Logminer  对日志进行分析,看看执行创建索引时,数据库到底做了些什么。我们发现,系统对SYS  下的'OBJ$', 'AUD$', 'WRI$_ALERT_THRESHOLD_LOG'SYSMAN 下的'MGMT_TASK_QTABLE', 'MGMT_COLLECTION_TASKS' 做了操作。会不会这些表使用了USER_DATA 表空间?

SQL> SELECT owner, table_name , tablespace_name

  2    FROM dba_tables

  3   WHERE (    owner = 'SYS'

  4          AND table_name IN ('OBJ$', 'AUD$', 'WRI$_ALERT_THRESHOLD_LOG')

  5         )

  6      OR (    owner = 'SYSMAN'

  7          AND table_name IN ('MGMT_TASK_QTABLE', 'MGMT_COLLECTION_TASKS')

  8         );

OWNER      TABLE_NAME                     TABLESPACE_NAME

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

SYSMAN     MGMT_TASK_QTABLE               SYSAUX

SYSMAN     MGMT_COLLECTION_TASKS          SYSAUX

SYS        WRI$_ALERT_THRESHOLD_LOG       SYSTEM

SYS        OBJ$                           SYSTEM

SYS        AUD$                           SYSTEM

可以看到这些表没有使用USER_DATA 表空间。

出于好奇,我又查看了SYS SYSMAN 用户缺省表空间的信息:

SQL> SELECT username, default_tablespace, temporary_tablespace

  2    FROM dba_users

  3   WHERE username IN ('SYS', 'SYSMAN');

USERNAME             DEFAULT_TABLESPACE   TEMPORARY_TABLESPACE

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

SYS                  USER_DATA            TEMP

SYSMAN               SYSAUX               TEMP

发现SYS 缺省的表空间为USER_DATA 

我试着修改下SYS 缺省的表空间:

SQL> alter user sys default tablespace users;

 

User altered

再重新创建索引:

 

SQL>  CREATE   INDEX PBSYSCATFRMTS_IDX  ON pbcatfmt(pbf_name);

 

Index created


成功!

三、原因猜想

    

       在创建索引时,如果不指定表空间,ORACLE 的某些系统操作会使用SYS 的缺省表空间,而且也许这些操作并不体现在Redo 文件中。因此报ORA-00959 ,不只是看操作数据库用户的信息,也要留意下SYS 用户的信息。

 

请使用浏览器的分享功能分享到微信等