物化视图FAST刷新静默退化为COMPLETE的根本原因是日志缺失关键配置:必须显式包含WITH PRIMARY KEY(或ROWID)、INCLUDING NEW VALUES及完整SEQUENCE列,缺一即降级。
物化视图日志没建对,FAST 刷新必然静默退化为 COMPLETE
oracle 19c 不会在你执行 refresh fast 前报错,而是在运行时发现日志结构不满足硬性条件,就自动降级——你只会看到刷新变慢、last_refresh_date 更新了但耗时暴涨,却看不到任何明确提示。根本原因几乎总是日志缺失关键配置:要么没带 with primary key 或 with rowid,要么漏了 including new values,要么 sequence 里没列全被引用的列。
检查 DBA_MVIEW_LOGS 确认日志是否真含 ROWID 或主键
别只看日志表是否存在,要查它是否被 Oracle 认可为“可用”。执行:
SELECT log_owner, master, log_table, rowids, primary_key, object_id FROM DBA_MVIEW_LOGS WHERE master = 'YOUR_BASE_TABLE';
必须满足以下至少一项,否则 REFRESH FAST 直接不可用:
-
rowids = 'Y'(表示日志含WITH ROWID) -
primary_key = 'Y'(表示日志含WITH PRIMARY KEY) - 若两者都是
'N',说明日志是无效的——哪怕表名对、用户对、也建了日志,FAST 就不可能启用
注意:ROWID 在分区表或 IOT 表中可能失效,此时必须用 WITH PRIMARY KEY;而主键列必须被物化视图 SQL 完整引用,否则仍会失败。
为什么 WITH ROWID 和 WITH PRIMARY KEY 不能共存?
Oracle 19c 明确禁止在一条 CREATE MATERIALIZED VIEW LOG 语句里同时指定 WITH ROWID 和 WITH PRIMARY KEY。它们是互斥的刷新锚点机制:
-
WITH ROWID:依赖物理行地址定位变更,适合非分区、无主键或主键未被完整引用的场景;但分区表分裂/移动后ROWID可能失效,导致增量丢失 -
WITH PRIMARY KEY:依赖逻辑主键值匹配,稳定性更高,尤其推荐用于分区表;但要求基表有可用主键,且物化视图 SELECT 中必须显式包含该主键列 - 选错会导致
DBMS_MVIEW.EXPLAIN_MVIEW返回MSGNO = 2012(“missing ROWID in SELECT list”)或MSGNO = 2005(“no materialized view log with primary key”)
重建日志前必须确认的三件事
盲目 DROP MATERIALIZED VIEW LOG 可能清空其他物化视图正在消费的日志记录,引发连锁数据不一致。动手前先查:
- 执行
SELECT LOG_TABLE, MASTER, LOG_OWNER FROM USER_MVIEW_LOGS WHERE MASTER = 'YOUR_TABLE',确认该日志是否被多个物化视图复用 - 查
SELECT COUNT(*) FROM MLOG$_your_table:若长期为 0,但基表有 DML,大概率是缺INCLUDING NEW VALUES导致 INSERT/UPDATE 未被捕获 - 对比
DBA_OBJECTS.OBJECT_ID和DBA_MVIEW_LOGS.MASTER_OBJECT_ID是否一致:不一致说明日志已“脱钩”,必须重建
真正容易被忽略的是:分区表上建日志时,INCLUDING NEW VALUES 不是可选项,而是强制项——不加它,新插入的分区数据永远进不了物化视图。











