split后物化视图staleness变为unusable,需先compile再查staleness_reason;日志不捕获split,须重建mlog并含primary key、rowid、sequence;分区键必须显式select;外键父表须纳入mv定义;残留调度任务须手动清理。

分区SPLIT后物化视图STALENESS变成UNUSABLE,不是刷新失败而是元数据断裂
Oracle不会自动感知分区结构变更,SPLIT PARTITION一执行,DBA_MVIEWS.STALENESS立刻变为UNUSABLE。这不是刷新卡住,而是物化视图编译状态直接失效——Oracle无法再安全推导增量变更路径,连DBMS_MVIEW.REFRESH都会被拒绝执行。
必须先做两件事:ALTER MATERIALIZED VIEW your_mv_name COMPILE,再查STALENESS_REASON确认是否还有其他阻塞项(比如日志失效、外键列缺失)。跳过COMPILE直接刷新,等于对一个已损坏的执行计划强行调用,必然报ORA-12008或ORA-12054。
物化视图日志不捕获SPLIT操作,必须重建才能恢复FAST刷新能力
SPLIT PARTITION本身不写入物化视图日志(MLOG$_xxx),哪怕日志建了INCLUDING NEW VALUES也无效。日志只记录DML,而SPLIT是DDL,Oracle默认绕过日志机制。结果就是:基表物理结构变了,但日志里没新增/删除行记录,REFRESH FAST找不到差异行,只能退化为COMPLETE或直接报错。
- 查日志是否还可用:
SELECT ROWIDS, PRIMARY_KEY, SEQUENCE FROM DBA_MVIEW_LOGS WHERE MASTER = 'YOUR_TABLE_NAME',三者至少两个为Y才支持FAST - 查日志表自身状态:
SELECT status FROM dba_objects WHERE object_name = 'MLOG$_YOUR_TABLE_NAME',若为INVALID,重建是唯一选择 - 重建命令必须显式包含所有关键字段:
CREATE MATERIALIZED VIEW LOG ON your_table WITH PRIMARY KEY, ROWID, SEQUENCE, INCLUDING NEW VALUES
分区键列未出现在物化视图SELECT列表中,FAST能力直接被禁用
如果物化视图定义里用了JOIN或WHERE条件依赖分区键(比如sale_date >= ADD_MONTHS(SYSDATE, -3)),但该列没出现在SELECT子句中,Oracle在EXPLAIN_MVIEW检查时会直接标记FAST为DISABLED。这和数据是否一致无关,是语法层面的硬性限制。
解决方法只有两个:SELECT语句里显式包含分区键列;或者改用REFRESH COMPLETE并接受全量重刷代价。别指望加hint或调整参数能绕过这个校验。
外键关联父表未纳入物化视图定义,SPLIT后约束检查会失败
分区表做子表且有外键指向父表(如sales_detail → product)时,SPLIT操作本身不触发父表刷新,但后续REFRESH FAST ON COMMIT会校验所有外键值是否存在于当前MV可见的数据中。如果父表根本没进MV定义,就会报ORA-02291。
不能靠“数据库有外键就自动同步”这种假设:
- 必须把父表(或至少外键列+主键列)显式写进物化视图SELECT和FROM子句
- 若父表太大,改用ON DEMAND模式,并严格控制刷新顺序:先刷父表MV,再刷子表MV
- 禁止在子表MV里用WHERE过滤分区,否则外键列值在MV中残缺,约束检查必挂
真正容易被忽略的是:SPLIT之后,哪怕你立刻重建了日志、重新编译了MV、补全了所有列,只要调度器里还挂着一个卡住的旧刷新任务(比如之前因UNUSABLE状态被中断的ON COMMIT事务),它就会持续占用资源并干扰新刷新。得去DBA_SCHEDULER_JOBS里手动DROP或STOP_JOB,否则问题会反复出现。











