物化视图刷新卡住时,应优先查dba_jobs和v$session而非user_mview_analysis;该表默认为空且不实时记录刷新,需手动触发分析才填充;真正有效的状态判断依据是作业状态、会话等待事件及dba_mviews.staleness字段。

物化视图刷新卡住了?先查 USER_MVIEW_ANALYSIS 有没有数据
USER_MVIEW_ANALYSIS 并不实时记录每次刷新,它只在你手动执行 DBMS_MVIEW.REFRESH_ALL_MVIEWS 或启用自动分析任务后才可能被填充,且默认不开启。多数情况下,这张表是空的——别急着翻它,先确认你是否真的触发过分析收集。
常见错误现象:SELECT * FROM USER_MVIEW_ANALYSIS 返回零行,就以为“没刷新”或“刷新失败”,其实只是没采集指标。
- 该视图字段如
LAST_REFRESH_DATE、STALENESS来自上次显式分析,不是刷新操作本身的日志 - 若用
DBMS_MVIEW.REFRESH单独刷一个 MV,不会自动更新此视图 - 要让它有数据,得主动调用
DBMS_MVIEW.EXPLAIN_MVIEW或运行DBMS_STATS.GATHER_SCHEMA_STATS(部分版本支持)
真正靠谱的刷新状态查法:盯住 DBA_JOBS 和 V$SESSION
物化视图自动刷新(如 ON DEMAND + DBMS_JOB 或 DBMS_SCHEDULER)本质是后台作业。卡住时,DBA_JOBS 里的 BROKEN 字段为 Y,或 LAST_DATE 长期没变;而正在跑的刷新会出现在 V$SESSION 中,SQL_ID 对应刷新语句,EVENT 常为 enq: MV – contention 或 row cache lock。
- 查挂起作业:
SELECT JOB, WHAT, BROKEN, LAST_DATE, NEXT_DATE FROM DBA_JOBS WHERE WHAT LIKE '%DBMS_MVIEW.REFRESH%' - 查活跃会话:
SELECT SID, SERIAL#, SQL_ID, EVENT, STATE FROM V$SESSION WHERE PROGRAM LIKE '%mview%' - 注意:12c+ 推荐用
DBA_SCHEDULER_JOBS替代DBA_JOBS,尤其当刷新由 Scheduler 控制时
DBA_MVIEW_LOGS 和 DBA_MVIEWS 联合看,判断刷新是否真“滞后”
刷新是否滞后,不能只看时间戳,要看基表变更是否已写入物化视图日志,以及 MV 本身是否标记为 STALE。关键字段在 DBA_MVIEWS.STALENESS(值可能是 STALE、FRESH、UNUSABLE),而 DBA_MVIEW_LOGS.LOG_TABLE 是否持续增长,能反映 DML 捕获是否正常。
-
STALENESS = 'STALE'表示需刷新,但不一定失败——可能只是还没调度到 - 如果
DBA_MVIEW_LOGS.ROWIDS = 'YES'且LOG_TABLE行数暴涨,但 MV 仍是FRESH,说明刷新逻辑可能跳过了日志(比如用了COMPLETE刷新模式) - 刷新模式影响很大:
FAST依赖日志,COMPLETE直接重查基表,后者不会清空日志表,容易误判“积压”
想实时跟踪一次刷新?用 DBMS_APPLICATION_INFO.SET_MODULE 打标 + 查 V$SESSION_LONGOPS
原生没有“刷新进度条”,但你可以给刷新会话打标,再轮询查长期操作。在调用 DBMS_MVIEW.REFRESH 前,先设模块名:
EXEC DBMS_APPLICATION_INFO.SET_MODULE('MV_REFRESH', 'SALES_MV');
然后查进度:
SELECT OPNAME, TARGET_DESC, SOFAR, TOTALWORK, ROUND(SOFAR/TOTALWORK*100,2) PCT_DONE FROM V$SESSION_LONGOPS WHERE MODULE = 'MV_REFRESH' AND OPNAME LIKE '%refresh%';
- 这个方法只对耗时 > 6 秒的操作生效(Oracle 内部阈值)
-
TOTALWORK在某些 COMPLETE 刷新中可能为 0,此时PCT_DONE不可用 - 别依赖
V$SESSION_LONGOPS的TIME_REMAINING,它估算极不准,尤其涉及大量索引维护时
真正难的不是查状态,而是区分“慢”和“卡死”——前者可能只是基表太大、日志膨胀或统计信息陈旧,后者往往伴随锁等待或 job 被置为 broken。盯着 V$LOCK 和 V$SESSION_WAIT 比反复刷 USER_MVIEW_ANALYSIS 有用得多。











