DBAtlas · 数据库运维图谱

ORA-01555: Snapshot too old(Oracle)

Oracle 的 'ORA-01555: snapshot too old' 错误表示查询进行一致性读所需的旧数据(undo)已被覆盖。此决策树缩小错误来源的范围(长查询 + UNDO 不足、undo 周转过快或 LOB),并引导你找到正确的修复方法。

错误发生在哪里?

先确定错误发生的上下文。经典的 ORA-01555 是在长时间运行的 SELECT/报表期间出现,还是在访问 LOB(CLOB/BLOB)列时出现?与 LOB 相关的 ORA-01555 是另一种机制(PCTVERSION/RETENTION),需单独解决。

SELECT sql_id, elapsed_time/1e6 AS sec, sql_text
FROM v$sql ORDER BY elapsed_time DESC FETCH FIRST 10 ROWS ONLY;
  • 在长时间运行的查询/报表期间
  • 在访问 LOB 列时

UNDO 是否足够,保留时间是否合适?

长查询从 UNDO 中读取自其开始以来被修改过的块的旧映像。若 UNDO 表空间太小或 undo_retention 短于查询时长,旧 undo 就会被覆盖。测量 UNDO 使用情况和保留时间。

SHOW PARAMETER undo_retention;
SELECT tablespace_name, SUM(bytes)/1024/1024 AS mb, status
FROM dba_undo_extents GROUP BY tablespace_name, status;
SELECT MAX(maxquerylen) AS longest_query_sec, MAX(tuned_undoretention) AS tuned_retention
FROM v$undostat;
  • UNDO 太小/保留时间短于查询时长
  • UNDO 足够,但提交非常频繁
  • 查询运行时间过长

根本原因:UNDO/保留时间不足

长查询所需的旧 undo 因保留期到期或表空间写满而被覆盖。扩大 UNDO,并将保留时间设置为能覆盖查询时长。

根本原因:undo 周转过快(频繁提交)

提交非常频繁的大量 DML 会快速循环使用 undo 块,抹掉长查询所需的旧映像。'commit cleanout' 效应会使情况更糟。

根本原因:查询时长过长

查询运行时间太长,即使合理的 undo_retention 也不够。永久的解决办法是加快查询或分流其负载。

根本原因:LOB 保留 / PCTVERSION

读取 LOB 时出现 ORA-01555,说明保存旧 LOB 版本的空间(RETENTION 或 PCTVERSION)不足。LOB 有单独的版本机制。

在 DBAtlas 中打开 →