Oracle Online 创建索引失败, ORA-08104

| 6 Comments

通过 ONLINE 参数创建索引(或者重建索引), 如果进程被突然终止,或者是手工 CTRL+C 取消该操作, 在非常个别的时候,麻烦来了。重新创建索引,会告诉你该索引已经存在,drop index ,会告诉你该索引被锁,或者是 ORA-08104(this index object xxxxx is being online built or rebuilt) 错误。该过程失败之前创建的一些临时对象由 SMON 负责清除,糟糕的是, SMON 可能会不作为--我在 9i 上观察是 2 个小时(周期?)才清除掉。

如果是一个比较繁忙的 OLTP 系统, 并且是要维护单列索引,那么风险真的是很大的。在 SMON 清除这些临时对象之前,没有办法在该列上建立新的索引。服务器能撑住么?

在 10g 版本, Oracle 的 DBMS_REPARE 包新增了: online_index_clean ,能够手工进行清除:

dbms_repair.online_index_clean(
object_id     IN BINARY_INTEGER DEFAULT ALL_INDEX_ID,
wait_for_lock IN BINARY_INTEGER DEFAULT LOCK_WAIT)
RETURN BOOLEAN;

谢中辉说这是一个 Bug,经过仔细查看 Metalink ,发现很多文档都说的不够准确--10g 的功能,Oracle 还让 9i 的用户去用呢,很不幸,我也上当了。

非常繁忙的一天.

--EOF--

6 Comments

一般只在很忙的机器上或很忙时遇到, 也有人直接改$表的.

大家都知道的问题了。你才碰到?哈哈

metalink上有这个bug[在9i中可以说是bug,也可以不认为是bug]的相关解释和处理方法。

大家都知道? 有谁告诉我 8i/9i/10g SMON 多久会清除这些对象么?

你去搜索引擎上搜索 online_index_clean
这才是这篇文字要记录的意义

关于10g中dbms_repair.online_index_clean介绍的文章确实不多。

呵呵。。。这个问题好像地球人都已经知道了。^_^

online rebuild或create失败后,oracle会做以下两件事情:

1.smon进程清除ind$基表,将相应的索引的flags更改为0.这步操作每隔一小时做一次。
2.smon进程清理临时段。每隔两小时做一次。

正常情况下,smon将flags改为0后,可以将索引删除。但是如果此时临时段还未清理完毕的话,还不能马上做rebuild online操作,否则将会报出ora-8106的错误。

手工做的话,可以将相应的index的flags的状态改为0,然后删除SYS_JOURNAL_nnnnn临时表格,最后再重建。

如果先删除SYS_JOURNAL_nnnnn临时表格,然后再将index的flags状态改为0的话,则会报出ora-600 [4610]号错误,
也就是数据字典不一致的错误。