在online rebuild index的过程中,如果中途异常终止(比如按ctrl+c强行退出),运气不好的话,可能会遇到问题,在你想重新rebuild index(或者drop,analyze)的时候,报错:
ORA-08104: this index object 67420 is being online built or rebuilt
这是由于在异常终止online rebuild操作的时候,oracle没来得及清理相应的临时段和标志位,系统认为online rebuild操作还在进行造成的。在Oracle10g之前,对于这种情况没有太好的办法,只有等SMON进程来进行清理了。网上有说上重启可以解决,有说直接update系统表ind$的,对于不能停机的产品库来说,这些都是不可取的方案。重启不现实,修改系统表更是DBA的大忌。Oracle10g则可以使用dbms_repair.online_index_clean手工清理(metalink的说法,9i打了Bug 3805539的patch的话也能用该过程了)。所以,对于大索引的online rebuild,不要轻易中止。否则可能要等上相当一段时间SMON才能完成清理工作,清理完后,可以在alert.log中看到如下记录:
User:,time:20071209 03:12:09,program:oracle@db1 (SMON),IP:,object:SYS_JOURNAL_67420,DDL: drop table "TAOBAO"."SYS_JOURNAL_67420"
异常终止的情况下,可以发现ind$关于该索引的状态还是online rebuild的:
SQL> select obj#,flags from ind$ where obj#=67420;

      OBJ#      FLAGS
---------- ----------
     67420        514
Flag字段的说明可以在ind$的sql.bsq脚本中找到:
/* mutable flags: anything permanent should go into property */
/* unusable (dls) : 0x01 */
/* analyzed       : 0x02 */
/* no logging     : 0x04 */
/* index is currently being built : 0x08 */
/* index creation was incomplete : 0x10 */
/* key compression enabled : 0x20 */
/* user-specified stats : 0x40 */
/* secondary index on IOT : 0x80 */
/* index is being online built : 0x100 */
/* index is being online rebuilt : 0x200 */
/* index is disabled : 0x400 */
/* global stats : 0x800 */
/* fake index(internal) : 0x1000 */
/* index on UROWID column(s) : 0x2000 */
/* index with large key : 0x4000 */
/* move partitioned rows in base table : 0x8000 */
/* index usage monitoring enabled : 0x10000 */
514=0×202,表示该索引状态为index is being online rebuilt : 0×200 + analyzed : 0×02
在SMON完成清理动作后,再次查询索引状态已经恢复正常:
SQL> select obj#,flags from ind$ where obj#=67420;

      OBJ#      FLAGS
---------- ----------
     67420          2
Metalink相关参考:
Note:375856.1
Note:351585.1
Bug 4364202
Bug 3805539
Bug 2702410