首页 » ORACLE » Troubleshooting ORA-00959: name is already used by an existing object 案例

Troubleshooting ORA-00959: name is already used by an existing object 案例

昨天同事在SPLIT PARTITION时遇到这个问题,其实问题很简单,只是从最大分区拆分出下一个月的分区,表是一个IOT 分区表,分区条件不存在任何问题,只是分享一点儿思路简单总结一下。报错信息如下:

SQL> ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  TLOG_201706  ,PARTITION TLOG_MAX)
  2  ;
ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  TLOG_201706  ,PARTITION TLOG_MAX)
                       *
ERROR at line 1:
ORA-00959: name is already used by an existing object

oracle@WEEJAR$ oerr ora 959
00959, 00000, "tablespace '%s' does not exist"
// *Cause:
// *Action:

NOTE:
拆分区语法没有问题,报的是ORA-00959: name is already used by an existing object,这个错误提示有些奇怪ora-959是表空间不存在, 但是这里ora-959错误的描述提示是对象已存在。 然后从DBA_OBJECTS 确认名为”TLOG_201706″不存在任何对象。

SQL> show parameter recycle

PARAMETER_NAME                                               TYPE        VALUE
------------------------------------------------------------ ----------- ----------------------------------------------------------------------------------------------------
buffer_pool_recycle                                          string
db_recycle_cache_size                                        big integer 0
recyclebin                                                   string      OFF

SQL> select * from dba_recyclebin;
- none

确认了回收站当前是关闭的,并且回收站中当前无对象。

使用Errorstack诊断该问题

SQL> oradebug setmypid 
Statement processed.

SQL> oradebug event 955 trace name errorstack level 3;
Statement processed.

SQL>  ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  TLOG_201706a  ,PARTITION TLOG_MAX);
 ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  TLOG_201706a  ,PARTITION TLOG_MAX)
                        *
ERROR at line 1:
ORA-00955: name is already used by an existing object


SQL> oradebug tracefile_name
/oracle/app/oracle/diag/rdbms/bill/bill1/trace/bill1_ora_13369466.trc


** 2017-05-25 17:46:34.570
dbkedDefDump(): Starting a non-incident diagnostic dump (flags=0x0, level=3, mask=0x0)
----- Error Stack Dump -----
ORA-00955: name is already used by an existing object
----- Current SQL Statement for this session (sql_id=67p50g4vv8t2g) -----
CREATE TABLE "ANBOB"."SYS_IOT_TRNS_20078"("EVENT_KEY", PRIMARY KEY("EVENT_KEY"))  ORGANIZATION INDEX  SPLIT     as (SELECT * FROM "ANBOB"."TLOG" PARTITION ("TLOG_MAX")  WHERE
NOT (("EVENT_KEY" < '2017070101')))

----- Call Stack Trace -----
calling              call     entry                argument values in hex
location             type     point                (? means dubious value)
-------------------- -------- -------------------- ----------------------------
skdstdst()+40        bl       107c59c10            FFFFFFFFFFEA210 ? 000000001 ?
                                                   000000003 ? 000000000 ?
                                                   000000000 ? 000000001 ?

Note:
从trace文件中找到了递归调用的SQL,是一个自动维护创建的一种瞬间存在状态的“transient table”,  这种对象通常是在命令执行过程中存在,命令结束后自动删除, 如online create index也是需要一张“影子表”。  然后检查“ANBOB”.”SYS_IOT_TRNS_20078″确实已经存在, 这类对象不可以重命名,如果尝试会提示错误:

SQL> alter table ANBOB.SYS_IOT_TRNS_20078 rename to SYS_IOT_TRNS_20078_bak;
alter table ANBOB.SYS_IOT_TRNS_20078 rename to SYS_IOT_TRNS_20078_bak
*
ERROR at line 1:
ORA-28674: cannot reference transient index-organized table

手动删除后就可以了。

SQL> drop table "ANBOB"."SYS_IOT_TRNS_20078";

Table dropped.

SQL> ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  "TLOG_201706"  ,PARTITION TLOG_MAX);
ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  "TLOG_201706" ,PARTITION TLOG_MAX)
                       *
ERROR at line 1:
ORA-00959: tablespace 'EMPTYCDR' does not exist

Note:
再次尝试时出现了有用的信息,这里的ORA-959的错误描述是对应的错误信息,真实的原因’EMPTYCDR’表空间不存在,这类提示通常是用户、表或分区上的默认表空间属性指向了一个过去存在但已删除的表空间,使用如下命令修正指向一个正确的表空间,该类问题在日后巡检中应该排查及时修正。

SQL> @us ANBOB
Show database usernames from dba_users matching %ANBOB%

USERNAME                  DEFAULT_TABLESPACE        TEMPORARY_TABLESPACE              USER_ID CREATED           PROFILE
------------------------- ------------------------- ------------------------------ ---------- ----------------- ------------------------------
ANBOB                   USERS                     TEMP                                   95 20090709 11:50:05 JFZX_APP

SQL> ALTER TABLE "ANBOB"."TLOG"  MODIFY DEFAULT ATTRIBUTES TABLESPACE GGSNCDR;
Table altered.

SQL> ALTER TABLE  "ANBOB"."TLOG" SPLIT PARTITION  TLOG_MAX at ('2017070101') into (PARTITION  "TLOG_201706"  ,PARTITION TLOG_MAX);
Table altered.

Summary:
这个问题就是TABLE默认的属性Tablespace已不存在,在Split IOT表失败,但是创建的递归“瞬态表”却留在了数据库中,需要人手动清理,如果不删除下次再次尝试时就会提示不同的错误信息“ORA-00959: name is already used by an existing object”,解决方法是手动清理“瞬态表”后修改表的默认属性。errorstack在问题诊断时是一把利器,对于这个案例同样使用10046也就可发现。

--enjoy–

打赏

, ,

对不起,这篇文章暂时关闭评论。