我在Grails框架中使用底层Hibernate实现了一个应用程序。运行一段时间后,我收到了Oracle DB错误,并通过重建违规索引解决了这个问题。我想知道是否有人可以提出可能的原因以及防止其发生的方法。
引起: org.springframework.jdbc.UncategorizedSQLException:
Hibernate操作:无法执行JDBC批量更新; 未分类SQL的SQLException [更新RSS_ITEM set guid =?, pubdate =?,link =?,rss_source_id = ?, title = ?, description =?, rating_raw =?,rating_tuned =?,date_created =?,date_locked =?哪里 ?RSS_ITEM_ID =]; SQL状态[99999];错误代码[29861]; ORA-29861: 域索引标记为LOADING / FAILED / UNUSABLE
嵌套异常是java.sql.BatchUpdateException: ORA-29861: 域索引标记为LOADING / FAILED / UNUSABLE
答案 0 :(得分:24)
找到损坏的索引使用:
select index_name,index_type,status,domidx_status,domidx_opstatus from user_indexes where index_type like '%DOMAIN%' and (domidx_status <> 'VALID' or domidx_opstatus <> 'VALID');
要重建索引,请使用:
alter index INDEX_NAME rebuild;
答案 1 :(得分:13)
域索引是一种特殊类型的索引。可以使用OCI构建我们自己的,但您可能正在使用Oracle Text提供的索引类型之一。我说这个,因为你的表似乎包含自由文本列。
最常用的Text索引是CTXSYS.CONTEXT索引类型。关于这种索引类型的观点是它不是以事务方式维护的,以便最小化索引大型文档所涉及的工作量。相反,后台进程(例如数据库作业)会定期启动索引同步。索引在同步时无法使用。如果resync因任何原因失败,那么您将需要删除并重新创建索引。
这是经常发生的吗?如果是这样,您可能需要重新评估您的申请。也许不同类型的索引(例如CTXSYS.CTXCAT)可能更合适。有关您的错误消息的一件事是您的UPDATE语句触及了很多列,包括看起来像主键的列。这让我觉得你有一个通用的更新语句,它设置每一列,无论它是否实际发生了变化。这是正常索引的不良做法;如果您使用文本索引,它将终止您的应用程序。
答案 2 :(得分:4)
http://ora-29861.ora-code.com/
原因:已尝试访问正在进行的域索引 建造或标记失败的 DDL不成功或标记为无法使用 通过DDL操作。
操作:等待指定的索引标记为LOADING 指定的索引,如果标记为FAILED 删除或重建指定的索引if 它被标记为不可用。
这应该是足够的背景。你能从中找出问题吗?