定时自动刷新不触发的主因是job_queue_processes=0或物化视图模式为on commit;start with/next仅设时间点,依赖后台job机制,需确保其启用、mv为on demand、非受限会话、job已注册、时间表达式合法且返回date类型。

定时自动刷新不会触发,大概率是 job_queue_processes = 0 或物化视图模式设成了 ON COMMIT。
START WITH / NEXT 不生效的典型原因
Oracle 的 START WITH 和 NEXT 子句本身不启动任何任务,它只是给数据库“记个时间点”,真正干活的是后台 job 机制。一旦 job 被禁用,MV 就永远停在“计划中”状态。
-
job_queue_processes必须 > 0(12c+ 建议设为1000,避免积压) - 物化视图必须是
ON DEMAND模式;ON COMMIT下NEXT完全被忽略 - 数据库不能处于
RESTRICTED SESSION状态(否则 job 不调度) - 执行
SELECT * FROM DBA_JOBS WHERE WHAT LIKE '%DBMS_MVIEW.REFRESH%',若无记录,说明创建时未注册 job
时间表达式写错导致 ORA-12012
START WITH 和 NEXT 的值必须是返回 DATE 类型的表达式,不是字符串。常见错误是直接写字面量或依赖 NLS 设置。
- ❌ 错误:
START WITH 'SYSDATE + 1'(字符串,解析失败) - ❌ 错误:
NEXT TO_DATE('2026-07-22 02:00', 'YYYY-MM-DD HH24:MI')(NLS 变更时崩) - ✅ 正确:
START WITH SYSDATE、NEXT TRUNC(SYSDATE) + 1 + 2/24(每天凌晨 2 点) - ✅ 正确:
NEXT SYSDATE + 30/(24*60)(每 30 分钟)
验证是否合法:查 SELECT NEXT FROM USER_MVIEWS WHERE MVIEW_NAME = 'YOUR_MV',返回值应为有效日期。
刷新失败但 job 显示“运行中”
job 成功触发 ≠ 刷新成功。DBMS_MVIEW.REFRESH 报错后常被静默吞掉,只留下 BROKEN = Y 或 FAILURES > 0。
- 查
DBA_JOBS.FAILURES:大于 0 表示最近几次都失败了 - 物化视图所有者必须对基表有
SELECT权限(不是SELECT ANY TABLE),且拥有CREATE JOB权限 - 若用 DB Link,需确认远端对象可访问、密码未过期、网络通
- 错误默认不输出,可在创建时加
LOGGING,或手动跑一次EXEC DBMS_MVIEW.REFRESH('MV_NAME', 'F')观察报错
建议改用 DBMS_SCHEDULER 替代传统 job
从 10g 起,DBMS_SCHEDULER 已全面优于 DBMS_JOB:支持失败重试、邮件通知、窗口控制、日志留存,且不依赖 job_queue_processes。
- 原生 MV 的
START WITH/NEXT语法底层已自动绑定DBMS_SCHEDULER(12c+),但显式使用更可控 - 例如:用
DBMS_SCHEDULER.CREATE_JOB创建 job,job_action设为'BEGIN DBMS_MVIEW.REFRESH(''MV_NAME'', ''F''); END;' - 复杂场景(如仅在业务低峰期运行)必须走
DBMS_SCHEDULER,传统 job 无法满足
真正容易被忽略的点是:即使 DBA_JOBS 显示正常,只要 DBA_MVIEWS.LAST_REFRESH_DATE 长期没变,就说明刷新链断了——得立刻查 FAILURES 和权限,而不是等告警。











