db link断开导致物化视图快速刷新静默失败且不重试,仅停滞数据并停更last_refresh_date;日志持续累积但无法消费,恢复后需确认mlog$完整性方可继续fast刷新,否则退至代价高昂的complete刷新。
db link断开后物化视图刷新直接失败,不重试也不报错
oracle 默认不会对 refresh fast 过程中的 db link 失联做自动重试——它只是静默跳过本次刷新,且不记录明确错误到 dba_mview_refresh_logs 或告警日志。你查不到“连接失败”,只发现物化视图数据停滞、last_refresh_date 停在故障时刻。
- 刷新任务由后台作业(
job_queue_processes)异步执行,失败时仅写入USER_SCHEDULER_JOB_LOG,但错误级别常为FAILED而非ERROR,容易被忽略 - DB Link 故障期间,物化视图日志(
MLOG$)仍在本地累积变更,但无法消费;若长期不恢复,日志表可能膨胀甚至撑满表空间 - 下次连接恢复后,快速刷新仍能继续——前提是日志未被手工清理或触发
purge操作
手动补刷前必须确认:物化视图日志是否完整可用
断连期间源表的 DML 变更全靠物化视图日志记录,一旦日志损坏或被截断,就只能退回到 COMPLETE 刷新,代价巨大。
- 检查日志状态:
SELECT log_table, master, rowids, primary_key, filter_columns FROM user_mview_logs WHERE master = 'HRNAME',确认rowids和primary_key为YES - 验证日志条目是否连续:
SELECT COUNT(*), MIN(sequence#), MAX(sequence#) FROM mlog$_hrname;若COUNT明显小于MAX - MIN + 1,说明有丢失 - 禁止在断连期间执行
TRUNCATE TABLE mlog$_hrname或DROP MATERIALIZED VIEW LOG——这是不可逆操作
安全重试的三步实操:从诊断到强制刷新
不要直接跑 DBMS_MVIEW.REFRESH,先看当前状态再动手。
- 查最后一次刷新结果:
SELECT name, last_refresh_date, refresh_method, last_refresh_duration FROM user_mviews WHERE mview_name = 'HR_HRM_TEST' - 手动触发一次带超时和重试的刷新:
EXEC DBMS_MVIEW.REFRESH('HR_HRM_TEST', 'F', atomic_refresh => FALSE, rollback_seg => NULL, refresh_after_errors => TRUE)(refresh_after_errors => TRUE允许跳过部分失败的基表,适用于多源场景) - 若仍失败,改用完全刷新兜底:
EXEC DBMS_MVIEW.REFRESH('HR_HRM_TEST', 'C'),并立即重建日志(因C刷新不依赖日志,但后续F需要)
日志保留策略:别等磁盘爆了才想起归档
物化视图日志不是临时缓存,它是增量刷新的唯一依据——没它,FAST 就是废的。但 Oracle 不自动清理,得自己管。
- 设置日志自动老化:在创建日志时加
WITH PRIMARY KEY INCLUDING NEW VALUES后,配合定时任务运行DBMS_MVIEW.PURGE_LOG - 推荐归档周期 = 最长容忍刷新延迟 × 1.5,例如每小时刷新一次,日志至少保留 90 分钟:
EXEC DBMS_MVIEW.PURGE_LOG('HRNAME', 90) - 切忌用
DELETE FROM mlog$_hrname手动删——会破坏内部SNAPTIME$$序列,导致后续FAST刷新报ORA-12034
断连本身不可怕,可怕的是日志失效后还盲目相信“下次自动就好了”。物化视图的可靠性,一半靠 DB Link 稳定,另一半靠你盯紧 mlog$ 表里那几行 SNAPTIME$$ 和 CHANGE_VECTOR$$。










