必须手动重建索引:先查状态确认unusable,再执行alter index idx_name rebuild(可加online和logging),因update global indexes仅对后续ddl有效,无法修复已发生的失效。
全局索引在 drop partition 后变 unusable 怎么办
不加 update global indexes,drop partition 一执行完,全局索引就立即变成 unusable,后续 insert 直接报 ora-01502。这不是延迟生效,是即时状态变更,且 oracle 不打日志、不警告,极易漏查。
修复必须分两步走:
- 先确认状态:
SELECT index_name, status FROM user_indexes WHERE table_name = 'YOUR_TABLE';—— 若看到UNUSABLE,别急着重跑 DDL - 再重建索引:
ALTER INDEX idx_name REBUILD;(加ONLINE可减少锁表时间,但不能消除阻塞) - 重建前注意:默认
NOLOGGING,若需归档同步,显式加上LOGGING
EXCHANGE PARTITION 报 ORA-14098 怎么定位和绕过
ORA-14098 的本质是分区表与交换表的局部索引定义不一致,不是索引“失效”,而是校验失败。Oracle 要求:非分区表的每个非分区索引,都必须有完全匹配的 LOCAL 索引(列顺序、类型、长度全等)。
快速排查和应对方式:
- 用
SELECT index_name, column_name, column_position FROM user_ind_columns WHERE table_name IN ('PART_TABLE', 'TMP_TABLE') ORDER BY index_name, column_position;对比两边索引列定义 - 若只是临时交换、不关心索引可用性,改用
EXCLUDING INDEXES子句,跳过索引校验(交换后手动重建) - 若必须带索引交换,且差异难对齐,可先
ALTER INDEX ... UNUSABLE临时禁用不匹配的索引,交换完成后再REBUILD
索引状态是 VALID 但查询报 ORA-01578 怎么办
这大概率是物理坏块,不是逻辑失效。DBA_INDEXES.STATUS = 'VALID' 只表示 Oracle 没标记它为不可用,不代表索引块完好。首次访问坏块时才暴露问题。
处理路径要严格按顺序:
- 先定位坏块归属:
SELECT owner, segment_name, segment_type FROM dba_extents WHERE file_id = &file_id AND &block_id BETWEEN block_id AND block_id + blocks - 1;—— 确认segment_type = 'INDEX' - 再判断能否用 RMAN 修复:必须满足三条件——有含该块的备份、数据库开
ARCHIVELOG、坏块是物理型(非逻辑损坏) - RMAN 成功后仍报错?可能是 buffer cache 缓存了旧 branch 块,执行
ALTER SYSTEM CHECKPOINT;等 DBWR 刷盘,或谨慎使用ALTER SYSTEM FLUSH BUFFER_CACHE;
UPDATE GLOBAL INDEXES 为什么加了还是失效
语法写对不等于生效。常见失效原因根本不在索引本身,而在 DDL 执行上下文:
-
UPDATE GLOBAL INDEXES只支持DROP/EXCHANGE/SPLIT/MERGE/MOVE,ADD PARTITION或TRUNCATE PARTITION写了也无效 - 子句必须紧贴主语句后、分号前,中间不能换行、不能插注释,否则 Oracle 直接忽略
- DDL 执行中途中断(如被 kill、空间不足报错),可能导致部分索引已置为
UNUSABLE但事务回滚,残留状态没清理 - 执行用户对索引无
ALTER权限时,维护静默跳过,只在 alert.log 写警告,不报错
真正麻烦的是大表加这个子句——它锁整张表,DML 全部阻塞,耗时是普通 DROP PARTITION 的 3–10 倍。线上操作前务必评估窗口期和业务容忍度。











