在线重建索引与ORA-08104
做索引在线重建的时候,可能相关的表还在变化,Oracle需要记录这个索引的相关变化,因此Oracle会创建一张临时表来记录这些变化,等索引重建完成后再删除这张临时表,这张临时表的名字为SYS_JOURNAL_<INDEX的OBJECT_ID>。REBUILD刚刚开始的时候就会去创建这张日志表,但是如果创建日志表的时候,发现这张表已经存在了,就可能会报ORA-8104,并无法继续做REBUILD(普通的REBUILD会检查索引的FLAG标志和这张表,如果冲突,也会失败)。
如果REBUILD被中途杀掉了,那么这张表和IND$中的FLAGS不会被自动清除,必须由SMON来清除。而SMON每个小时会进行一次类似的清除工作,SMON做清除前首先要锁住日志表,如果这个索引相关的表还在变化,那么SMON可能无法锁住这张表,如果SMON锁表失败,就会放弃这次清理工作,等一个小时后再来清理。这样一来,在业务较为繁忙的生产系统上,可能SMON永远都没有机会清除这张日志表。
解决方法
找到索引的OBJECT_ID为1234567
DECLARE
RetVal BOOLEAN;
OBJECT_ID BINARY_INTEGER;
WAIT_FOR_LOCK BINARY_INTEGER;
BEGIN
OBJECT_ID := 1234567;
WAIT_FOR_LOCK := NULL;
RetVal := SYS.DBMS_REPAIR.ONLINE_INDEX_CLEAN ();
COMMIT;
END;
/