在Oracle中创建索引,尤其是大的热表索引(存在很多的活动事务),如果在创建过程中出现异常,例如会话中断(OS层面kill-9),可能会导致Oracle数据字典内已经包含了该索引的信息(诸如像在ind$的标记位信息不能及时复位),但是却实际没有为该索引分配段,进而导致需要重新建立索引的时候,可能会抛出异常,如下所示,在删除索引IDX1时,会提示索引对象826976号正在创建或者被重建,无法删除,(在alter table ... drop partition的时候(Drop Partition Failed With ORA-08104: This Index Object Is Being Online Built Or Rebuilt (Doc ID 2358693.1)),可能出现相同的错误),



SQL> drop index IDX1;
drop index IDX1
*
ERROR at line 1:
ORA-08104: this index object 826976 is being online built or rebuilt



此时,可以在sys下执行这个脚本,



SQL> declare
2  done boolean;
3  begin
4  done:=dbms_repair.online_index_clean(826976);
5  end;
6  /
PL/SQL procedure successfully completed.



调用dbms_repair存储过程的online_index_clean函数,参数就是上面的索引对象号,这个函数从Oracle 10.2开始支持,在10.2以前,需要等待SMON自己完成清理的工作,



This function performs a manual cleanup of failed or interrupted online index builds or rebuilds. This action is also performed periodically by SMON, regardless of user-initiated cleanup.



(How to Cleanup and Rebuild an Interrupted Online Index Rebuild - ORA-8104 , ORA-8106 (Doc ID 272735.1)),SMON进程每60秒尝试一次清理,但是在highly active的数据库,存在很多活动的事务,导致SMON无法以NOWAIT获得对象锁,进而需要等待很久的时间,才能完成清理,在此之前,就无法执行索引重建的工作。因此,才需要这个函数,代替SMON,执行手工清理,清除临时信息。