应查dba_jobs或dba_scheduler_jobs判断物化视图刷新状态,而非user_mview_analysis;结合v$session、dba_mviews.staleness、dba_mview_logs.last_purge_date及mlog$_表中snaptime$$=date'4000-01-01'记录综合分析。

查 DBA_JOBS 或 DBA_SCHEDULER_JOBS,不是 USER_MVIEW_ANALYSIS
USER_MVIEW_ANALYSIS 默认为空,且只在手动触发 DBMS_MVIEW.EXPLAIN_MVIEW 或特定统计任务后才填充,不能反映真实刷新状态。别被空结果误导——它不记录每次 REFRESH 调用。
真正有效的作业状态看这两张表:
-
DBA_JOBS:适用于传统DBMS_JOB调度的物化视图(尤其 11g 及更早);重点看BROKEN字段是否为Y、LAST_DATE是否长期未更新、FAILURES是否 > 0 -
DBA_SCHEDULER_JOBS:12c+ 推荐方式;查STATE(RUNNING/COMPLETED/FAILED)、ENABLED是否为TRUE - 两者都需过滤
WHAT或JOB_ACTION含DBMS_MVIEW.REFRESH的记录
盯 V$SESSION,确认刷新是否真在跑
作业调度成功 ≠ 刷新正在执行。很多“卡住”其实是会话阻塞或锁等待,而非作业没启动。
运行以下语句抓活跃刷新进程:
SELECT sid, serial#, sql_id, event, state, blocking_session FROM v$session WHERE program LIKE '%mview%' OR sql_id IN ( SELECT sql_id FROM v$sql WHERE sql_text LIKE '%DBMS_MVIEW.REFRESH%' );
重点关注:
-
EVENT值为enq: MV – contention:物化视图内部锁冲突 -
EVENT值为row cache lock:数据字典争用,常见于高并发刷新 -
BLOCKING_SESSION非空:上游会话持锁未释放
看 DBA_MVIEWS.STALENESS 和 DBA_MVIEW_LOGS.LAST_PURGE_DATE 联合判断滞后
单看时间戳容易误判。必须把物化视图自身状态和日志消费进度一起看。
DBA_MVIEWS.STALENESS 字段含义:
-
STALE:需刷新,但未必失败(可能只是还没轮到) -
FRESH:当前数据与基表一致(注意:可能是刚完成 COMPLETE 刷新) -
UNUSABLE:结构损坏或日志不可用,FAST 已失效
DBA_MVIEW_LOGS.LAST_PURGE_DATE 更关键:
- 为空或比当前时间早 >2 小时 → 日志消费停滞,FAST 刷新大概率已退化
- 持续更新但
STALENESS = 'STALE'→ 刷新逻辑未生效(如权限不足、事务未提交、MV 定义变更未重编译) - 若
ROWIDS = 'YES'且基表近期执行过ALTER TABLE ... SHRINK SPACE→ ROWID 失效,FAST 静默失败
验证 MLOG$_ 表里是否有待消费变更
快速刷新依赖日志中存在 SNAPTIME$$ = DATE '4000-01-01' 的记录。这是“待消费”的唯一标记。
执行这个查询(安全、高效):
SELECT COUNT(*) FROM MLOG$_YOUR_BASE_TABLE WHERE SNAPTIME$$ = DATE '4000-01-01';
结果解读:
- 返回 0,且你确认基表有新 DML → 日志写入异常(触发器禁用、权限丢失、日志表被
TRUNCATE) - 返回 >0,但
LAST_PURGE_DATE不更新 → 消费端卡住(锁、长事务、REFRESH调用失败未重试) - 不要
SELECT *查MLOG$_表——大日志表会拖垮性能
日志表名和基表名严格对应,大小写敏感;DATE '4000-01-01' 是 Oracle 内部硬编码值,不能替换为 TO_DATE 或其他表达式。











