物化视图日志存在不等于生效,需同时验证ROWIDS/SEQUENCE()覆盖、CAN_USE_LOG='YES'及OBJECT_ID一致性,三者缺一不可。

物化视图日志存在 ≠ 日志生效,必须查 ROWIDS、SEQUENCE() 列覆盖、CAN_USE_LOG 三处才知真假。
查 USER_MVIEW_LOGS 确认日志基础结构是否达标
日志表建了但没启用关键能力,FAST 刷新照样失败。重点不是“有没有”,而是“能不能用”:
-
ROWIDS字段必须为'Y'(若 MV 定义依赖 ROWID);若用主键模式,则PRIMARY_KEY必须为'Y' -
OBJECT_ID必须与基表DBA_OBJECTS.OBJECT_ID一致,否则 Oracle 认为日志不属于该表 -
LOG_TABLE名为MLOG$_XXX,但若状态为INVALID(查DBA_OBJECTS.STATUS),说明 DDL 已破坏其元数据,必须重建
查 USER_MVIEW_LOG_FILTERS 验证变更列是否被真正捕获
日志结构对,不代表内容可用。新增列、改 DEFAULT、加 NOT NULL 后,日志不会自动更新字段列表:
- 执行
SELECT COLUMN_NAME FROM USER_MVIEW_LOG_FILTERS WHERE LOG_TABLE = 'MLOG$_YOUR_TABLE' - 结果必须包含所有参与
JOIN、WHERE、GROUP BY的列——漏一个,REFRESH_FAST就会报MSGNO = 2005或静默退化 - 特别注意:哪怕基表列有
DEFAULT值,只要没显式写进SEQUENCE(col1, col2),该列变更就不会记入日志
查 USER_MVIEWS.CAN_USE_LOG 和 DBMS_MVIEW.EXPLAIN_MVIEW 交叉验证
这是最终判决依据,绕不开:
-
SELECT CAN_USE_LOG FROM USER_MVIEWS WHERE MVIEW_NAME = 'YOUR_MV'返回'NO',说明日志链已断,FAST 刷新必然不可用 - 必须立刻执行
EXEC DBMS_MVIEW.EXPLAIN_MVIEW('YOUR_MV'),然后查PLAN_TABLE中CAPABILITY_NAME = 'REFRESH_FAST'的行 - 紧盯
MSGTXT:如出现"materialized view log does not exist on table XXX",其实是日志存在但CAN_USE_LOG = 'NO'导致的误报;而"fast refresh not possible after DDL on base table"几乎总是因SEQUENCE()漏列或INCLUDING NEW VALUES缺失
日志失效最常被忽略的触发点
不是语法错,是结构断——这些操作后不重建日志,FAST 就彻底瘫痪:
- 基表执行
ALTER TABLE ... ADD col NUMBER NOT NULL DEFAULT 0(哪怕有 DEFAULT,也必须进SEQUENCE()) - 基表删了主键或唯一索引(
ROWID模式下可能仍可用,但PRIMARY_KEY模式直接失效) - 基表做了
TRUNCATE PARTITION(DDL 不写日志,SCN 不推进,日志表里无新记录,FAST 刷新直接卡死或退化) -
INCLUDING NEW VALUES没加——这是 INSERT/UPDATE 新值能否被捕获的关键开关,缺它等于日志只记旧值
日志是否生效,不能靠“建过就完事”的经验判断。每次基表 DDL 后,都得重跑 EXPLAIN_MVIEW + 查 USER_MVIEW_LOG_FILTERS + 对比 OBJECT_ID,三者全通才算真正可用。











