ORA-01555 根本原因是物化视图刷新时所需 SCN 的 undo 数据被覆盖,与回滚表空间大小无直接关系;典型场景为基表变更频繁、刷新耗时长且 undo_retention 设置过短,应优先采用快速刷新、合理设置 retention 并避开业务高峰。
ORA-01555 是快照过旧,不是回滚表空间不够
ora-01555 的根本原因是物化视图刷新过程中,查询需要读取的 scn 对应的数据块已被覆盖(undo 数据被覆写),和回滚表空间大小没有直接关系。盲目增大 undo_tablespace 或调高 undo_retention 可能无效,甚至掩盖真正问题。
典型触发场景是:基表数据变更频繁 + 刷新耗时长(比如全量刷新或复杂 join)+ undo 保留时间短于刷新执行时间。
- 检查当前 undo 保留时间:
SELECT value FROM v$parameter WHERE name = 'undo_retention'; - 确认刷新任务实际运行时长(查
DBA_MVIEW_REFRESH_TIMES或日志) - 如果刷新耗时 20 分钟,而
undo_retention只设了 600(10 分钟),大概率报 ORA-01555
优先用快速刷新(FAST)替代完全刷新(COMPLETE)
完全刷新会重建整个物化视图,扫描全量基表,极大拉长查询时间窗口;快速刷新只处理增量变更,大幅缩短一致性读所需的时间跨度。
- 确保物化视图已启用日志:
CREATE MATERIALIZED VIEW LOG ON your_table WITH ROWID, SEQUENCE (col1, col2) INCLUDING NEW VALUES; - 创建物化视图时指定
REFRESH FAST ON COMMIT或ON DEMAND,且必须满足快速刷新限制(如无AVG()、MAX()等禁止聚合) - 刷新前用
DBMS_MVIEW.EXPLAIN_MVIEW检查是否支持快速刷新,输出中fast_refreshable字段必须为YES
调整刷新方式与时机,避开业务高峰
即使支持快速刷新,若在高并发 DML 时段执行,仍可能因 undo 链争用或延迟提交导致快照过旧。主动控制刷新节奏比硬调参数更可靠。
- 改用
ATOMIC_REFRESH => FALSE:刷新时先 truncate 再 insert,避免长事务持有 undo;但注意这会短暂清空 MV 数据 - 在低峰期调度刷新,例如用
DBMS_SCHEDULER设置凌晨执行,配合基表变更低谷 - 对超大基表,考虑分片刷新:按分区或时间范围拆成多个小 MV,单次刷新窗口缩短
undo_retention 要设得“够用”,不是“越大越好”
UNDO_RETENTION 是 soft limit,Oracle 在空间压力下仍会覆写 undo。设太高会导致 undo 表空间膨胀、自动扩展频繁,甚至引发空间不足错误。
- 先估算安全值:取最近 7 天最长刷新耗时的 1.5 倍(例如最长 18 分钟 → 设 2700 秒)
- 监控 undo 使用率:
SELECT BEGIN_TIME, END_TIME, UNDOBLKS, TXNCOUNT FROM V$UNDOSTAT ORDER BY BEGIN_TIME DESC FETCH FIRST 10 ROWS ONLY; - 配合设置
RETENTION GUARANTEE(仅限专用 undo 表空间)可强制保留,但务必确保表空间有足够冗余空间
真正难处理的是基表本身变更太猛又无法停写的情况——这时候得回到 MV 设计源头,看能否简化逻辑、拆分依赖,或者接受一定延迟改用异步 CDC 方案。

















