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 で開く →