有关域索引错误产生的原因及解决办法
1说明
数据库错误ORA-29861:域索引标记为LOADING/FAILED/UNUSABLE,其错误原因及解决办法,根据ORACLE官方文档的说法如下:
// *Cause: An attempt has been made to access a domain index that is
// being built or is marked failed by an unsuccessful DDL
// or is marked unusable by a DDL operation.
// *Action: Wait if the specified index is marked LOADING
// Drop the specified index if it is marked FAILED
// Drop or rebuild the specified index if it is marked UNUSABLE
由上述可知,当空间索引被DDL标记为FAILED或UNUSABLE时,访问空间索引会报该错误。当出现此类错误时,若标记为LOADING,则需等待DDL完成;若标记为FAILED,则需删除索引;若标记为USUSABLE,则需重建或删除。尽管,ORACLE给出了解决办法,但显然不适用于我们的使用场景。我们不可能在每一次出现此类错误时,都删除索引重建或者使用REBUILD命令。我们的目标是避免此类错误的产生,而不是在此类错误发生后采取某些解决手段。
既然是由DDL引起,自然首先应关心哪些DDL会引起此类错误呢?这里分两类情况,分全局索引和分区索引。
2全局索引
当使用全局域索引时,以下的DDL命令会造成上述域索引错误:
- Exchange partition(我们的应用中目前没有使用这一技术)
- Drop partiion ,当drop的分区中存在数据记录时,标记UNUSABLE
- Truncate partition(我们的应用中目前没有使用这一技术)
- Split partition ,当分裂后的两个分区中均存在数据时,标记UNUSABLE
- Create index ,当由于某些原因(例如弧),创建失败时,标记FAILED
在我们的应用中,存在drop partition、split partition、create index命令。其中create index在数据库初始化的时候进行,此时图层为空图层,所以不会出现将域索引标记为FAILED的情况;而drop partition会在删除某个县的数据时用到,此时该分区内可能有数据,当存在数据时,会导致域索引被标记为USUABLE;split partition会在应用中用到,但不会出现分裂后的两个分区均存在数据的情况,因此在我们的应用中不会因为split partition导致域索引被标记为UNUSABLE或FAILED。因此,得出一个结论,在使用drop partition、技术删除某个县的数据时,若使用全局索引,极有可能出现域索引的问题。
可以通过如下命令查看某个全局索引是否被标记为UNUSABLE或FAILED。
select INDEX_NAME,INDEX_TYPE,STATUS,DOMIDX_STATUS,DOMIDX_OPSTATUS from user_indexes where table_name=TABLENAME and index_type='DOMAIN';
若STATUS值为UNUSABLE或FAILED,或者DOMIDX_OPSTATUS值为FAILED,则该索引需要被删除或被重建。重建的命令如下:
Alter index index_name rebuild;
3分区索引
当使用分区索引时,以下DDL命令会造成上述域索引错误:
- Split partition ,当分裂后的两个分区中均存在数据时,标记UNUSABLE
- Create index ,当由于某些原因(例如弧),创建失败时,标记FAILED
其中create index在数据库初始化的时候进行,此时图层为空图层,所以不会出现将域索引标记为FAILED的情况;split partition会在应用中用到,但不会出现分裂后的两个分区均存在数据的情况,因此在我们的应用中不会因为split partition导致域索引被标记为UNUSABLE或FAILED。综上所述,对于分区索引,我们的应用应该不会导致域索引错误。当的确在分区索引时出现了域索引错误,极有可能将多个县的数据入在了一个分区中。而至于为什么出现将多个县的数据入在了一个分区中,需要认真分析原因。
可以通过如下命令查看某个全局索引是否被标记为UNUSABLE或FAILED。
Select INDEX_NAME,PARTITION_NAME,STATUS,DOMIDX_OPSTATUS from user_ind_partitions where index_name=INDEXNAME
若STATUS值为UNUSABLE或FAILED,或者DOMIDX_OPSTATUS值为FAILED,则该索引需要被删除或被重建。重建的命令如下:
Alter index INDEXNAME rebuild partition partition_name;