暂无图片
暂无图片
2
暂无图片
暂无图片
暂无图片

ORA-01502: 索引 'USER.SYS_C0067978' 或这类索引的分区处于不可用状态

原创 苦行僧 2024-06-06
1023

​ 在插入数据时突然报错,ORA-01502: 索引 ‘USER.SYS_C0067978’ 或这类索引的分区处于不可用状态
奇怪,索引失效按说只是影响查询速度,索引失效怎末会导致无法插入呢

故障处理及问题排查

  1. 首先查看下索引状态
select index_name,index_type,table_owner,table_name,status from user_indexes where index_name='SYS_C0067978' and table_owner='GWM_FLS';

INDEX_NAME      INDEX_TYPE      TABLE_OWNER   TABLE_NAME                STATUS
SYS_C0067978	NORMAL    	UNUSABLE      PF_REQUEST_LOG_CONTENT	UNUSABLE
  1. 重构索引
alter index gwm_fls.SYS_C0067978 rebuild online;
推荐加online,使用online会在后台运行虽然速度慢一些不过不会锁表影响业务
  1. 原因回顾
错误原因:
回想前天对该库中的表排查行迁移,对该表进行了move在线重定义,move操作会导致rowid变化,所以会导致索引失效
继续下面聊一下为什么索引失效导致insert、update操作失效👇

索引为什么会导致insert、update失效

一般情况下,CBO不考虑使用UNUSABLE状态的索引,包含分区表。相关参数为SKIP_UNUSABLE_INDEXES,其作用如下所示:
SKIP_UNUSABLE_INDEXES作用:在DML期间跳过对索引的维护,这样可以提高DML的效率,可以事后一次性重建,但是SKIP_UNUSABLE_INDEXES=y对unique index不起作用,因为此时的unique index扮演者constraint的作用所以在insert数据时index必须被更新。

当参数SKIP_UNUSABLE_INDEXES设置为true时(默认),当数据库遇到不可用索引时,只会忽略而不会提示任何错误信息;同时即使该表上带有不可用的索引或索引分区,也可以针对该表执行DML操作,针对不可用索引对应的DML语句都将正常执行,而且数据库停止维护相关索引。

在进行DML(INSERT和UPDATE)操作时,如果是唯一索引,那么无论该参数的值设置为何值,Oracle都会去校验索引的可用性。如果索引不可用,那么就会报错ORA-01502。

当参数SKIP_UNUSABLE_INDEXES设置为false时,DML操作及CBO生成执行计划时都会考虑该索引。所有与UNUSABLE索引相关的操作都会失败,报错信息为:ORA-01502: 索引 '‘USER.SYS_C0067978’ 或这类索引的分区处于不可用状态。

move的注意事项

在对表进行move前要注意,move操作时如果不指定表空间,则在原表空间移动数据块,在这个表空间中需要至少额外一倍该表大小的空间。
数据重组后,其 rowid 发生了改变。index是通过 rowid 来 fetch 数据行的,所以表上的 index 需要 rebuild。

索引失效原因

库中索引状态已经是不可用的状态,回想导致索引的情况有哪些呢?

当某些操作导致数据行的ROWID改变,索引就会完全失效。可以分普通表和分区表来讨论哪些操作将导致索引失效。

普通表索引失效的情形如下所示:

​ ① 手动置索引无效:ALTER INDEX IND_OBJECT_ID UNUSABLE;。
​ ② 如果对表进行MOVE操作(包含移动表空间和压缩操作)或在线重定义表后,那么该表上所有的索引状态会变为UNUSABLE。MOVE操作的SQL语句为:ALTER TABLE TT MOVE;。
​ ③ SQL*Loader加载数据。

分区表索引失效的情形如下所示:

​ ① 对分区表的某个含有数据的分区执行了TRUNCATE、DROP操作可以导致该分区表的全局索引失效,而分区索引依然有效,如果操作的分区没有数据,那么不会影响索引的状态。需要注意的是,对分区表的ADD操作对分区索引和全局索引没有影响。
​ ② 执行EXCHANGE操作后,全局索引和分区索引都无条件地会被置为UNUSABLE(无论分区是否含有数据)。但是,若包含INCLUDING INDEXES子句(缺省情况下为EXCLUDING INDEXES),则全局索引会失效,而分区索引依然有效。
​ ③ 如果执行SPLIT的目标分区含有数据,那么在执行SPLIT操作后,全局索引和分区索引都会被被置为UNUSABLE。如果执行SPLIT的目标分区没有数据,那么不会影响索引的状态。
​ ④ 对分区表执行MOVE操作后,全局索引和分区索引都会被置于无效状态。
​ ⑤ 手动置其无效:ALTER INDEX IND_OBJECT_ID UNUSABLE;。
对于分区表而言,除了ADD操作之外,TRUNCATE、DROP、EXCHANGE和SPLIT操作均会导致全局索引失效,但是可以加上UPDATE GLOBAL INDEXES子句让全局索引不失效。
重建分区索引的命令为:ALTER INDEX IDX_RANG_LHR REBUILD PARTITION P1;。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论