Oracle如何清除创建失败的索引

现象描述:

在一张大表下新建索引时,因为没有加并行而导致创建时间很长,这时候如果终止操作,比如直接关闭终端,kill会话,然后再次登录创建时就会报错ORA-00095提示对象名字已被用,而去删除对象时又报错ORA-08104索引正在被创建。

SQL> drop index xxx.ww_idx;

drop index xxx.ww_idx
                *
ERROR at line 1:
ORA-08104: this index object 1519527 is being online built or rebuilt
SQL> select object_id from dba_objects where object_name='ww_idx';
 OBJECT_ID
----------
   1519527
$ oerr ora 08104
08104, 00000, "this index object %s is being online built or rebuilt"
// *Cause:  the index is being created or rebuild or waited for recovering 
//          from the online (re)build 
// *Action: wait the online index build or recovery to complete

/*

使用 oerr工具看到的ORA-08104的解释是索引并没有创建失败,而是在终端关闭之后,创建的操作还在继续进行。创建或者重建索引时,系统会创建一个临时日志表,

这张表被用于存放创建或者重建索引期间产生的日志信息,同时在基表IND$中这个索引的FLAG字段上会被设置为BUILD或者REBUILD标识,

当索引信息变更时会把变更信息存入日志表。如果索引创建或者重建失败,这个日志表和数据字典中的状态位都需要后台进程smon进行清理。

因此这里的索引不能被删除是因为后台进程smon还没来得及清理相应的临时段和标志位,认为online rebuild操作还在进行。

那么现在如何终止rebuild index这一操作?

 

*/

查找metalink得到一篇文档:ORA-600 [12813] When Dropping A Table Partition After a Failed IndexRebuild (文档 ID 803008.1)。它给出了两种方法:

这个需要有相应账号才能查看支持文档哦

解决方式:

-- 1)使用包 dbms_repair 包来清理
如果在出现问题的对象的数据库活动能停下来,则直接简单地执行如下语句即可:

select dbms_repair.online_index_clean(<problem index object_id>) from dual; 2)使用PL/SQL block调用 dbms_repair 包来清理 如果在出现问题的对象的数据库活动不能停下来,则如下的PL/SQL block来处理 declare isClean boolean; begin isClean := FALSE; while isClean=FALSE loop isClean := dbms_repair.online_index_clean(dbms_repair.all_index_id, dbms_repair.lock_wait); dbms_lock.sleep(2); end loop; exception when others then RAISE; end; /
注:加上 dbms_repair.lock_wait 表示不是立刻清理,需要不断的寻找资源锁,直到抢到为止

 

posted @ 2021-06-23 16:14  一个苦逼的运维人  阅读(510)  评论(1)    收藏  举报