最近工作中遇到一个Oracle的数据库问题
逻辑背景:
由于Performance 原因重构一些数据库表(其中包含了一些分区数据表) 同级联删除旧的index 和 新建了index.
程序执行:
1 check and truncate by partition (DDL)
2 bacth insert
问题现象:
步骤2出现 java.sql.SQLException: java.sql.BatchUpdateException: ORA-01502: index 'A' or partition of such index is in unusable state
分析:
debug 到步骤1 完:
select status from user_indexes where index_name in ( 'A', 'A2‘); 发现状态变为 unusable.
DB上rebuild unusable的index, such as:
alter index A rebuild;
alter index A2 rebuild;
继续执行步骤2 无exception.
查询相关分区表的所有索引状况:
ALTER TABLE A表
ADD CONSTRAINT A PRIMARY KEY(主键字段);
CREATE INDEX A2 ON A表(索引字段);
其他分区表:
ALTER TABLE B表
ADD CONSTRAINT B PRIMARY KEY(主键字段)
USING INDEX LOCAL;
CREATE INDEX B2 ON B表(索引字段) LOCAL;
由于本人不是DBA,所以采取了比较分析的办法,大致找到解决办法。 重建分区索引加上Local, 因为重建表的分析索引时脚本丢失了这个关键字。
根本原因:
和DBA沟通后得知。 当我们的表为分区表的时候, 所有用到与分区字段有关的 索引要创建为 本地索引。 否则, 默认为全局索引, 这样一旦有相关的 更新分区数据的DDL (比如 步骤1中执行的是:alter table A表 truncate partition for (分区ID)。) 造作会导致这样的全局索引失效。