【问题标题】:Hibernate equivalent for skip_unusable_indexes (oracle)skip_unusable_indexes (oracle) 的 Hibernate 等效项
【发布时间】:2016-06-03 17:50:32
【问题描述】:

我有一个使用 Spring JPA 和 Hibernate 连接到 ORACLE 11g 数据库的 Java 应用程序。

有时,我需要在数据库中 drop partition 并将所有 UNUSABLE global indexes 重建为 USABLE 状态。 (由于 drop partition 命令,索引变得不可用)

在我的分区被删除且 UNUSABLE 索引尚未重建之间,我的在线应用程序失败并显示ORA-01502 error,如下所示。

Caused by: java.sql.BatchUpdateException: ORA-01502: index 'USER.INDEX_NAME' or partition of such index is in unusable state

   at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10070)
   at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:213)
   at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:70)
   at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:268)
   ... 94 more

在 SQL 中有一个选项可以通过设置 skip_unusable_indexes=TRUE 来忽略 UNUSABLE 索引。这样,查询优化器会选择一个不同的(昂贵的)执行计划,该计划不使用索引,并且不会报告由于索引不可用而导致的 DML 查询失败。

Hibernate 中是否有任何类似的选项,当索引处于 UNUSABLE 状态时,我可以使用它来避免失败?

我正在使用的版本 休眠:3.6.9 甲骨文:11g 爪哇:7

【问题讨论】:

    标签: java oracle hibernate


    【解决方案1】:

    你可以重建索引:

    ALTER INDEX USER.INDEX_NAME REBUILD;
    

    【讨论】:

      【解决方案2】:

      你可以尝试执行:

      ALTER SESSION SET skip_unusable_indexes=true
      

      类似于this,但此会话将返回到收集池并重复使用,因此这将影响多个查询。

      如果我是你,我会问自己“为什么我的索引不可用?”这种情况不应该发生,除非您正在执行一些维护或执行一些非常大的批处理过程。您可能有一个 24/7 系统,您真的不想停止系统进行维护。在这种情况下,您可以明智地设置选项系统,而无需对代码进行任何更改。这样系统会变慢,但在维护期间表现更好。 请记住,不能忽略用于强制约束的索引,插入/更新查询无论如何都会失败。并添加一些自动检查,在特定时间报告 PRO 中不可用的索引。一个发邮件的PL/SQL进程就可以了

      另一种选择是仅在数据库更改期间更改选项:

      ALTER SYSTEM SET skip_unusable_indexes=true;
      ALTER TABLE T1 DROP PARTITION P1; 
      ALTER INDEX I1 REBUILD ONLINE
      ALTER SYSTEM SET skip_unusable_indexes=false;
      

      dba.stackexchange.com 讨论了删除分区的更好方法。因此,您并不孤单,但解决方案适用于 Oracle 12C。

      【讨论】:

      • 正如您所说,索引永远不应该处于不可用状态,但不可用的索引是在构建索引时锁定表之间的过渡,并允许在不使用 Oracle 11g 索引的情况下对表进行 DML。如果我使用像ALTER TABLE T1 DROP PARTITION P1 REBUILD GLOBAL INDEXES 这样的语句,那么我的表会被锁定,直到重建索引。但是,如果我使用 2 个单独的语句,例如 'ALTER TABLE T1 DROP PARTITION P1; ALTER INDEX I1 REBUILD ONLINE`,那么在重建索引时我的 DML 不会被阻止。但不幸的是,由于无法使用的索引错误,休眠插入似乎失败了。
      • 为什么不:ALTER SYSTEM SET skip_unusable_indexes=true; ALTER TABLE T1 删除分区 P1; ALTER INDEX I1 在线重建; ALTER SYSTEM SET skip_unusable_indexes=false;
      • 您能否再次检查是否可以在系统级别修改skip_unusable_indexes?看起来像Oracle DocumentationSKIP_UNUSABLE_INDEXES is a session parameter only
      • 但是从 Oracle 10g 开始,您可以使用 Alter System,当然也可以在您报告的 11g 版本中使用:docs.oracle.com/cd/B28359_01/server.111/b28320/…
      • 啊哈..我的错。让我检查一下是否有效……非常感谢您的确认。
      猜你喜欢
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-06
      • 2018-01-18
      • 1970-01-01
      • 2020-08-28
      相关资源
      最近更新 更多