要验证物化视图是否真走增量刷新,需查mlog$_t中snaptime$$=‘4000-01-01’的记录数变化;用v$mvrefresh获取真实耗时;查fast_refreshable确认未静默降级;警惕日志膨胀、共享日志不兼容及水位线漂移。

查 DBA_MVIEW_LOGS 和 MLOG$_ 表的刷新水位变化
物化视图是否真走增量、花了多久,不能只看 DBMS_MVIEW.REFRESH 返回成功——它静默降级为 COMPLETE 时也返回成功。关键看日志表里变更记录是否被真正“消费”:刷新前 SELECT COUNT(*) FROM MLOG$_t WHERE SNAPTIME$$ = TO_DATE('4000-01-01', 'YYYY-MM-DD'),刷新后立刻再查,差值就是本次增量处理的行数。若差值为 0,说明没走增量;若非零但耗时仍高,说明增量逻辑本身慢(比如日志膨胀、目标 MV 查询含函数)。
用 V$MVREFRESH 查实时刷新会话与耗时
V$MVREFRESH 是唯一能捕获单次刷新真实执行时间的动态视图,但它只在刷新进行中可见。需配合定时轮询或触发式快照:
- 刷新前记录
SYSDATE或DBMS_UTILITY.GET_TIME(毫秒级) - 立即查
SELECT * FROM V$MVREFRESH WHERE MVIEW_NAME = 'MV_T',取START_TIME和END_TIME(注意:该视图不总保留历史,仅当前活跃/刚结束的刷新) - 若
END_TIME为空,说明还在跑;若已存在,用(END_TIME - START_TIME) * 24 * 60 * 60算秒级耗时
常见错误:直接查 DBA_MVIEWS.LAST_REFRESH_DATE,它只存时间点,不存持续时间,且更新滞后于实际完成。
监控 FAST 刷新是否被静默降级
Oracle 对 FAST 条件检查极严,不满足就降级,且不报错。必须主动验证:
- 刷新后立刻查
SELECT FAST_REFRESHABLE FROM DBA_MVIEWS WHERE MVIEW_NAME = 'MV_T',若值不是YES,说明定义已不支持 FAST(如加了SYSDATE、漏列、基表被TRUNCATE过) - 查
SELECT * FROM USER_MVIEW_LOGS WHERE MASTER = 'T',确认LOG_TRIGGER为YES且ROWIDS为YES,否则日志路径不兼容时间戳推进 - 执行
EXPLAIN_MVIEW('MV_T'),看输出里FASTREFRESHABLE是否为Y,以及MSGTXT是否提示缺失INCLUDING NEW VALUES等硬伤
避免误读“秒级”延迟的三个盲区
所谓“秒级同步”,在 Oracle 物化视图里本质是感知延迟,不是技术 SLA:
-
ON COMMIT模式下,延迟 = 源库 commit 完成 → 日志写入 → 网络 RTT → 目标库解析执行 → 提交,实测中位数约 300ms,但峰值可能到 2s;跨库必须放弃ON COMMIT,改用应用层触发DBMS_MVIEW.REFRESH('mv','F') - 日志表
MLOG$_t若长期未刷新,SNAPTIME$$停滞,会导致后续刷新扫描全量日志,耗时陡增——这不是代码问题,是运维水位漂移 - 多个 MV 共享同一张日志时,任一 MV 定义不兼容(如 SELECT 只取旧值,但日志含
INCLUDING NEW VALUES),所有关联 MV 的FAST_REFRESHABLE都变NO,且无明确告警
最易被忽略的是:SNAPTIME$$ 字段不是全局时钟,而是每个 MV 自己维护的水位线。一个 MV 刷新失败,不影响另一个,但没人自动修它——得靠脚本定期校验并重置异常水位。











