ORA-01555
エラーメッセージ
ORA-01555 スナップショットが古すぎます: ロールバック・セグメント番号string、名前 "string"が小さすぎます ORA-01555: snapshot too old: rollback segment number string with name "string" too small
基本的なエラーの内容
SQLを発行すると読み取り一貫性の為に、UNDOブロックを参照する場合がありますが、参照しようとしたUNDOブロックが上書きされたなどの理由でUNDO表領域上からなくなっている場合にORA-01555が発生します。
このエラーが発生する典型的なケースとしては、select文が長時間実行されている場合に、他のトランザクションによりデータの更新が行われた場合が考えられます。
確認事項および対応
クライアント側での対応
- データベースの負荷が低いタイミングでSQLを実行する。
- 同じタイミングで実行されている、他のトランザクションによるデータベースへの更新を抑える
- SQLが長時間実行されるものである場合、処理を分けて1回あたりの実行時間を短くする
- ORA-1555が発生するSQLを実行する前に、参照するテーブルに対してselectを実行しブロッククリーンアウトを行う。
表のブロッククリーンアウト:
sql> select /*+ full(表明) */ count(*) from 表名;
索引のブロッククリーンアウト:
sql> select /*+ index(表名 索引名) */ count(*) from 表名;
サーバー側での対応
[UNDO_MANAGEMENT=MANUAL の場合]
- UNDOセグメントの数やサイズを増やす
[UNDO_MANAGEMENT=AUTO の場合]
- UNDO_RETENTION 初期化パラメータの値を大きくする
- UNDO表領域のサイズを大きくする
詳細
Oracleではどのようなトランザクションでもデータの更新を行うと、ロールバックに備えて修正前のデータはUNDO表領域上のUNDOブロックに格納されます。
UNDO表領域には格納できる上限(領域のサイズまたは時間)が設定されている為、上限を超えて更新が行われた場合には古いUNDOブロックが上書きされます。
読み取り一貫性の為に参照しようとしたUNDOブロックが既に上書きされていた場合などにORA-01555が発生します。
※UNDOブロックが参照されるのはselect文の時だけではない為、select以外のSQLでもORA-01555が発生する可能性があります。
Oracle内部ではトランザクションのcommitごとに SCN (System Change Number)が割り当てられており、SCNを使ってタイミングの比較をすることで読み取り一貫性を行っています。
以下の例では説明上分かりやすくするために UNDO表領域に修正前のデータが999件(before1〜before999)まで格納可能とします。
例1:通常時の読み取り一貫性 SCN トランザクション1 トランザクション2 UNDO表領域の情報 100| select * from tabXXX; : : | <参照処理開始> : : | : : : | : : : | : update AA->BB 1000行目 [before1]tabXXX,1000行目 200| : commit; SCN:200でAA->BB | : : 400| 1000行目 : | SCN:200 で BBに更新されている : | このトランザクションはSCN100 : | 時点で開始されている為、 : | 読み取り一貫性でSCN100時点を : | UNDO[before1]から確認する −−−ー−−−−> [before1]を参照 | AA であったことが分かる <−−−ー−−− | : | : 900| select の結果が返る(1000行目はAA) |
例2:ORA-1555 発生時 SCN トランザクション1 トランザクション2 UNDO表領域の情報 100| select * from tabXXX; : : | <参照処理開始> : : | : : : | : : : | : update AA->BB 1000行目 [before1]tabXXX,1000行目 200| : commit; SCN:200でAA->BB | : : | : : | : : | : <他のトランザクションで | : 多量にcommit | : [before999]に到達> | : ↓ | : <UNDO領域が足りなくなり | : [before1]を上書き> | : : | : : | 1000行目参照 : | SCN:200 で BBB : | このトランザクションはSCN100 : | 時点で開始されている為、 : | 読み取り一貫性で : | UNDO[before1]から確認する −−−−−−−> [before1]を参照 | 上書きされている!! | ORA-01555発生 <−−−ー−−−
上記のような動作にから、UNDO表領域の上書きの可能性を減らすような対応(select実行中の更新を減らす、UNDO表領域を大きくするなど)がエラーの対応となります。
UNDO_RETENTION 初期化パラメータは上記で言うとUNDO表領域のデータの件数(before[1000]まで)ではなく、時間(1800秒など)を指定して修正前データが上書きされないようにするものです。