根本原因是Oracle对MERGE PARTITIONS默认不维护全局索引,因数据块物理重写导致ROWID失效且B-tree无法局部验证,故直接置为UNUSABLE;本地索引因分区独立而不受影响。
oracle 对 merge partitions 操作默认不维护全局索引(global),因为合并过程会物理重写数据块位置,导致原有索引条目中指向旧分区的 rowid 失效;b-tree 结构无法局部验证这些条目是否仍有效,所以 oracle 选择立即将整个全局索引置为 unusable,而不是返回错误结果或部分可用状态。
本地索引(LOCAL)不受影响——每个分区索引段独立,MERGE 只删掉被合并的两个分区索引段、新建一个对应新区间的索引段,其余分区索引保持 USABLE。
UPDATE GLOBAL INDEXES 不是可选项,而是防止静默失效的必要子句。它让 Oracle 在 MERGE 执行过程中同步扫描并修正全局索引中所有指向被合并分区的条目,等价于隐式触发一次全量重建。
ALTER TABLE t MERGE PARTITIONS p1, p2 INTO PARTITION p_new UPDATE GLOBAL INDEXES;
ONLINE 与 UPDATE GLOBAL INDEXES 同时使用(MERGE PARTITIONS 本身不支持 ONLINE)UNUSABLE 状态的索引,再补这个子句也无效——DDL 直接报错或忽略,必须先 ALTER INDEX idx_name REBUILD
常见真实场景下,即使语法正确,索引仍可能卡在 UNUSABLE 状态。排查优先看这三件事:
SELECT index_name, status FROM user_indexes WHERE table_name = 'YOUR_TABLE' —— 如果已有 UNUSABLE,DDL 不会自动修复,必须先重建ALTER 权限:维护跳过且无报错,仅日志里有警告,极易被忽略UPDATE GLOBAL INDEXES 实际执行的是全索引扫描 + 重建,耗时与索引大小强相关。实测显示,相比不加该子句,单次 MERGE 可能慢 3–10 倍,尤其当索引键值分布稀疏、DML 并发高时,锁持有时间显著延长。
更隐蔽的风险是:联机维护期间,全局索引上的 INSERT/UPDATE 会被阻塞或延迟,应用写入可能卡住——这不是理论风险,而是生产环境高频问题。所以别只盯着“能不能用”,得提前评估窗口期和业务容忍度。