Oracle DBAであれば必ず遭遇する「ORA-01555 スナップショットが古すぎます」について、原因と対処方法を説明します。
エラー内容
アラートログに以下の内容が表示されます。
ORA-01555: snapshot too old: rollback segment number string with name "string" too small
原因
ORA-01555は、Oracle Databaseの読み取り一貫性アーキテクチャによって引き起こされます。
例えばSQLを1:00から5時間長時間実行された場合でも、Oracleはすべての行が1:00時点になっていることを保証しています。
OracleはこれをオンラインのUNDOセグメントから変更された行の「更新前情報」を読み取ることで実現しています。
更新が多くSQLが長時間実行され、UNDOが小さすぎる場合、ORA-01555エラーが表示されます。
ドキュメントを見ると、ORA-01555は、不十分なUNDOサイズまたはundo_retentionパラメータの小さすぎる値が関連していることがわかります。
対処方法
自動UNDO管理モードの場合、UNDO_RETENTIONの設定を大きくしてください。
UNDO_RETENTIONが十分な値であれば、大きなロールバックセグメントを使用するようにしてください。
また、大きなUNDOを使用していても、小さすぎるUNDO_RETENTIONでORA-01555が発生することがあります。
しかし、undo_retentionに非常に大きな値を設定しても、ORA-01555エラーは発生しますので、以下のコミット頻度とORA-01555エラーに関する以下の施策も検討してみてください。
長時間実行されるクエリのスケジュールを、システムの負荷が少ない時間帯に変更する
長時間実行されるSQLやトランザクションを負荷の少ない時間帯にスケジュールし、スナップショットのSCN以降に行われた変更をロールバックする必要がないように一貫性を保ちます。
これを行うと、Oracle Databaseの負荷も減るので、全体的なパフォーマンスを向上にも繋がります。
コミット間にフェッチしない
カーソルによってクエリされるデータが現在のセッションで変更されている場合は、最後のコミットより前にオープンされたカーソルでフェッチしないようにします。
同時に実行されるSQL、特にPL/SQLプロシージャでは、コミットの頻度を少なくして、トランザクションスロットの再利用を減らす施策も有効です。