oracle原生dbms_scheduler作业无自动重试机制,执行失败后仅记录状态不补跑;需手动封装带重试逻辑的pl/sql过程,区分可重试(如ora-12008、-54)与不可重试错误(如ora-12004),并结合atomic_refresh=>false等配置保障可靠性。

DBMS_SCHEDULER作业本身不支持自动重试
Oracle原生的DBMS_SCHEDULER作业没有内置重试逻辑——它执行一次,成功或失败都只记录一次状态,不会自动重试。你看到USER_SCHEDULER_JOB_LOG里STATUS = 'FAILED',但后续不会补跑。这不是配置漏了,是设计如此。
常见错误现象:物化视图定时刷新偶尔失败(如网络抖动、临时锁表、日志表空间满),但作业照常标记为完成,LAST_START_DATE更新了,而数据却没刷进去,且无人告警。
- 不能依赖
RESTART_ON_FAILURE => TRUE——该参数只对CHAIN类型作业生效,普通STORED_PROCEDURE类刷新作业不认 - 别改
MAX_RUNS或MAX_FAILURES,它们控制的是作业生命周期,不是单次执行失败后的重试 - 验证方式:查
SELECT job_name, status, error#, additional_info FROM user_scheduler_job_log WHERE status = 'FAILED' ORDER BY log_date DESC,确认失败是否被静默吞掉
手动封装带重试的REFRESH调用(推荐)
把DBMS_MVIEW.REFRESH包进一个自定义PL/SQL过程,由调度器调用这个过程,而非直接调用REFRESH。这样你完全掌控重试逻辑、错误分类和降级策略。
关键点在于区分可重试错误和不可重试错误:
- 可重试:ORA-12008(内部错误)、ORA-00054(资源忙)、ORA-01555(快照过旧)、ORA-03113/03114(连接中断)
- 不可重试:ORA-12004(日志缺失)、ORA-12034(日志过期)、ORA-01403(NO DATA FOUND但非预期)——这类说明配置或状态已坏,重试无意义
- 示例片段:
BEGIN FOR i IN 1..3 LOOP BEGIN DBMS_MVIEW.REFRESH('DW.SALES_MV', method => 'F', atomic_refresh => FALSE); EXIT; -- 成功则退出循环 EXCEPTION WHEN OTHERS THEN IF SQLCODE IN (-12008, -54, -1555, -3113, -3114) AND i
必须配合状态检查与降级兜底
光重试不够。如果物化视图已变成STALE,或日志失效,再怎么重试FAST都会静默退化为COMPLETE,甚至卡死在锁表上。
- 每次重试前,先查
SELECT staleness FROM user_mviews WHERE mview_name = 'SALES_MV';若为STALE,应跳过FAST,直接走method => 'C' - 刷新后立刻验证:
SELECT last_refresh_date, refresh_mode, refresh_method FROM user_mviews WHERE mview_name = 'SALES_MV',确认last_refresh_date已更新且无倒退 - 失败后不要只发邮件——要写入监控表(如
mv_refresh_audit),记录job_name、error_code、staleness、log_can_use(来自user_mviews.can_use_log),否则下次排查时你根本不知道当时日志是否还有效
别忽略原子刷新与并行度对重试的影响
atomic_refresh => TRUE(默认)会在刷新全程锁住物化视图,一旦失败,MV会处于“半更新”状态,后续重试可能因锁冲突直接报ORA-00054;而parallelism > 1在高并发下反而增加资源争用概率,让失败更频繁。
- 生产环境建议统一设
atomic_refresh => FALSE:先建新表,再原子切换,失败不影响原MV可用性 -
parallelism对FAST基本无效,对COMPLETE也建议设为1或2,除非MV跨多个大分区且IO充足 - 注意:
atomic_refresh => FALSE要求MV必须有主键或唯一约束,否则ORA-12015会直接中断重试流程
真正难的不是写三次DBMS_LOCK.SLEEP,而是判断哪次该停、哪次该切模式、哪次该发告警而不是继续等。很多团队把重试做成黑盒,结果失败日志堆成山,却没人去看can_use_log = 'NO'那一行。











