Email: service@parnassusdata.com 7 x 24 online support!

ORA-1555の主な発生原因とその対処方法について

ORA-1555の主な発生原因とその対処方法について

 

ORACLEデータベース によくあるエラ の解決策

プロのOracle Databaseの復旧サービスを提供
携帯番号: +86 13764045638 メール:service@parnassusdata.com

 

適用範囲:

Oracle Database - Enterprise Edition - バージョン 7.3.4.0 以降

この文書の内容はすべてのプラットフォームに適用されます。

目的

 ORA-1555の主な発生原因とその対処方法について説明します。

トラブルシューティングの手順

[エラー・メッセージ]

ORA-01555 スナップショットが古すぎます: ロールバック・セグメント番号string、

名前 "string"が小さすぎます

--------------------------------------------------------------------------

原因:一貫した読込みに必要なロールバック・レコードが他のユーザーによって上書きさ

     れています。

処置:自動UNDO管理モードを使用している場合は、UNDO_RETENTIONの設定値を増やしてく

     ださい。使用していない場合は、さらに大きいロールバック・セグメント を使用し

     てください。

 

 

[技術的説明]

 

- エラー内容の概説と、エラー発生時の対処方法

 

  エラーの内容は、Oracleが読取り一貫性のために必要なビフォアイメージが、上書きさ

  れた等の理由で取得できなかったためにエラーとして出力しているというものです。

  ロールバック・セグメント(以降RBS)は多くのUNDOブロックからなり、ビフォアイメー

  ジはそのUNDOブロック上に格納されています。

 

  一般的に、エラーの原因は以下の2点です。

 

  1. RBSの数、サイズが不足していたため、読取り一貫性に必要なビフォアイメージが上

     書きされてしまった

  2. ORA-1555 を受けたSQLは長い時間実行していた(カーソルの場合では、openしてから

     長い時間経過していた)

 

  ORA-1555が発生した時の第一の対処方法は、ORA-1555が発生した処理を再実行することです。

  大抵の場合、再実行することでORA-1555のエラーは回避できます。

  但し、READ ONLYトランザクションを使用しているケース、ブロック障害、メディア障害

  等が発生している場合は再実行してもORA-1555が発生するため、そのトランザクションを

  終了させる、障害を回復させるといった対応をする必要があります。

  再度実行してもORA-1555が頻繁に発生するようなケースでは、本Krownで示される基本的な

  対処方法、詳細な原因と対処方法を参考に、ORA-1555が発生する要因を取り除いてやります。

 

- ORA-1555の発生を抑える対処方法

 

  ORA-1555の発生を抑える対処方法としては以下のとおりです。

 

  1. Oracle8i 以前、UNDO_MANAGEMENT=MANUAL の場合

      - RBSの数、サイズを増やす

     Oracle9i 以降で UNDO_MANAGEMENT=AUTOの場合

      - undo表領域のサイズを増やす

      - 初期化パラメータ UNDO_RETENTION の値を増やす

        UNDO_RETENTIONパラメータは、コミット後UNDOの情報を保持する期間(単位:秒)

        を示します。しかし、UNDO領域を十分に確保できない場合は保持すべきUNDOも順

        に上書きされてしまうため、UNDO表領域のサイズを合わせて増やす必要がありま

        す。

      - 基本的に、ORA-1555が検索文で発生する場合、UNDO_RETENTIONをその検索文の

        実行にかかる時間より大きな値に設定し、UNDO_RETENTIONで指定した期間のUNDO

        が保持できるようにundo表領域のサイズを増やすことで殆どのケースで問題を

        抑えることができます。

  2. アプリケーションやチューニングを見直し、

      - 長時間オープンするSQL文やカーソルを減らす

      - ORA-1555が発生するSQL文の実行中に、他のトランザクションによる更新処理を

        抑え、必要なUNDOブロックが上書きされにくくする

 

- エラー内容の詳細な説明

 

  Oracleでは最低でも各SQL文ごとの読取り一貫性が保証されています。つまり、ユーザ

  がSQL文を発行した時点の一貫性のとれているデータを返すことが保証されています。

  このため、検索を発行したユーザは、検索中に他のユーザによって変更されたデータ

  を見ることはありません。

 

  Oracleはシステム変更番号System Change Numbers (SCN)によって、データベースの状

  態を一意に識別します。SCNはコミットが発生するごとに増加しますので、時間が経つ

  につれて必ず大きくなります。このSCNを使って読取り一貫性を実現しています。

 

  読取り一貫性はRBSによって実現されています。

  トランザクションが何等かの変更をする度に、そのビフォアイメージがRBS上のUNDOブ

  ロックに格納されます。名前のとおり、このビフォアイメージを使用してロールバック

  は行われます。データブロックのヘッダー部分には、どこのRBSが使用されたかが記録

  され、同様に最後にコミットされたSCNの値をデータブロックは保持しています。

 

  これにより、検索中に他のユーザによりデータが書き換えられた場合でも、UNDOブロッ

  クを使用し、書き換えられたデータをロールバックすることで、そのユーザが更新する

  前のビフォアイメージを読み取ることができます。

  

  これらのビフォアイメージが保持される期間は、更新を行ったトランザクションがコミ

  ットするまでです。トランザクションがコミットした時点でUNDOブロックの内容が消去

  されるわけではありませんが、使用していたUNDOブロックは新しく発行されたトランザ

  クション等により使用され、上書きされて消えていきます。

 

  読取り一貫性のため、別のトランザクションによる変更前のデータをUNDOブロックを使

  用して読み込もうとしたが、必要なデータが格納されているUNDOブロックは既に入手不

  可能になっていた、というのが ORA-1555 のエラー内容になります。

 

  そのため、読み取り一貫性のために古いUNDOブロックの情報を見に行くことを減らすた

  めにトランザクションの実行時間を短くする、または、必要なUNDOブロックが上書きさ

  れることを防ぐためにRBSを大きくする、といったことが基本対処になります。

 

 

[原因の特定方法]

 

  このエラーが発生する際には、複数の原因が考えられます。

  詳細はこの後で記述がありますが、どれが原因で発生したのかを推測するために、いく

  つかの情報を収集します。

 

  1. どのSQL文でORA-1555が発生したのか

 

     これはアプリケーションのログ等からORA-1555が発生した際に実行していたSQL文を

     特定します。

 

     Oracle9i Database Release2 以降のバージョンでは、ORA-1555の発生時に以下のよ

     うなメッセージがアラートログに記録されることがあり、その場合はORA-1555が発生

     した際に実行していたSQL文がわかります(後述[原因4]のLOBのケースやSQL文を実行

     中でないケース(例:ダイレクト・パス・エクスポート)を除く)

 

     Wed Jul 30 15:04:53 2003

     ORA-01555 caused by SQL statement below (Query Duration=1 sec, SCN: 0x0000.000253f2):

     Wed Jul 30 15:04:53 2003

     select c1 from t1 where c2='1'

 

     この例では Query Duration が表示されています。UNDO_MANAGEMENT=AUTO の

     場合では、ここに記された値より大きな値を UNDO_RETENTION に設定することが

     一つの、そして大抵の場合充分な目安となります。

 

     それ以前のリリースでは、初期化パラメータに以下を追加します。

 

     event="1555 trace name errorstack level 1"

 

     データベースを再起動後、ORA-1555が発生した際にはトレースファイルが出力され、

     その先頭部に以下のようにORA-1555発生時のSQL文が記録されることがあります。

     (但し、後述[原因4]のLOBのケースやSQL文を実行中でないケース(例:ダイレクト

     ・パス・エクスポート)を除く)

 

     *** SESSION ID:(8.24) 2003-07-31 20:14:24.950

     *** 2003-07-31 20:14:24.950

     ksedmp: internal or fatal error

     ORA-01555: snapshot too old: rollback segment number 2 with name "???" too small

     Current SQL statement for this session:

     select c1 from t1 where c2='1'

 

  2. どのRBSでORA-1555が発生したのか (UNDO_MANAGEMENT=AUTO の場合はチェック不要)

 

     通常、エラーメッセージにRBSの番号、名称が記録されるため、それを利用します。

 

     ERROR at line 1:

     ORA-01555: snapshot too old: rollback segment number 2 with name "RBS2" too small

     ORA-06512: at line 2

 

     番号のみ記録された場合、RBSの名称は以下のSQL文で特定します

 

     SQL> select segment_name from dba_rollback_segs where segment_id=<rbs number>;

 

     SEGMENT_NAME

     ------------------------------

     RBS2

 

[発生原因と対処方法]

 

  ORA-1555 が発生する原因は数通りあります。ここではその各々について発生原因と対

  処方法を述べていきます。

  以下の例について、次の2つの事柄を念頭において読んでみるようお願いします。

  ・どのカーソル、SELECT文がORA-1555を受けているのか。

  ・RBSから発見できなかったのは、どの処理の、何時の情報なのか。

 

  (原因1)

    最も典型的なケース

 

    時間のかかる検索の実行中に、多数の他のトランザクションによる更新、コミット

    が行われた場合を想定します。

 

    SCN    TransactionA(TRAN:A)   TransactionB(TRAN:B)   Other Transactions

     10    select ... from TabA

     20       :                   update TabA

     30       :                   commit

     40       : select実行中                             多数の更新、コミット

              :

     50    ORA-1555

 

    このケースの場合、TRAN:Aが SCN:10 にて検索を開始しています。読取り一貫性のルー

    ルにより、TRAN:Aは SCN:10 の時点でのTabAのデータを読み込まなければなりません。

    ところが、TRAN:Bにより SCN:20 にてTabAが更新され、その後コミットが行われてし

    まいました。TRAN:AはTRAN:Bによる変更前のデータを読み込むため、TRAN:Bが使用し

    ていたRBSの内容を必要としますが、TRAN:Bは既にコミットを行っているため、TRAN:

    Bが使用していたRBSがTRAN:Aが必要とするよりも先に別のトランザクションにより上

    書きされ消えてしまっていることがあります。その結果、ORA-1555が発生します。

 

    また、上記例ではselect実行中となっており、Oracleが検索にそこそこ時間を要して

    いるケースになっていますが、SCN:10でカーソルをオープンし、その後SCN:50を過ぎ

    てもフェッチを行っていたようなケースでも同一の現象となります。

 

  (対処方法1)

    このケースの場合、以下の3つの要素が問題の原因となっています。

    1. TRAN:Aが長時間SQLを実行、又は長時間カーソルをオープンしていた

    2. TRAN:Aが検索を行っている表を、TRAN:Bが更新を行った

    3. TRAN:Bの使用していたUNDOブロックが上書き、または開放されてしまった

 

    そのため、対処方法は以下のようになります

    1. ORA-1555が発生する検索処理を短縮させるように検索文のチューニングや、アプ

       リケーションの見直しを行う

    2. ORA-1555が発生する検索の実行中には、検索の対象となっている表に対する更新

       処理を行わない

    3. UNDOブロックの上書きまたは開放を抑制する

       Oracle9i 以降で UNDO_MANAGEMENT=AUTOの場合:

         - 初期化パラメータ UNDO_RETENTION の値を増やす

         - undo表領域のサイズを増やす

       Oracle8i 以前、UNDO_MANAGEMENT=MANUAL の場合:

         - RBSの数、サイズを増やす

         - 大き目のRBSをあらかじめ用意しておき、TRAN:Bに明示的にその大きなRBSを

           割り当てる (SET TRANSACTION ROLLBACK SEGMENT ... を使用)

         - OPTIMALが設定してある場合、その設定を大きくする

 

  (原因2)

    コミットを挟んでカーソルを使用しているケース

 

    Oracleの仕様では、カーソルをオープン後コミットを実行した場合でも、引き続きそ

    のカーソルを利用してフェッチを実行し続けることができます。以下のようなケース

    を想定します。

 

     SCN    SessionA(SESS:A)

      10    open cursor (select ... from TabA)

      20    fetch row

      30    update TabA, commit

      40    fetch row

      50    update TabA, commit

      60    fetch row

              :

      70    fetch row --> ORA-1555

 

    この場合,カーソルにより取り出されるレコードはSCN:10の時点のTabAのデータであ

    り、SCN:30やSCN:50で更新された内容は反映されません。そのため、カーソルからレ

    コードを取り出す際には、SCN:30やSCN:50での変更前のデータを読み込む必要があり

    ます。この場合、SESS:A自体が[原因1]でのSESS:AとSESS:Bの両者の役割を果たして

    いる格好となり、SCN:30やSCN:50での更新時に使用したRBSが失われた場合には、

    ORA-1555が発生することになります。

 

  (対処方法2)

    このケースの場合、以下の2つの要素が問題の原因となっています。

    1. カーソルによる検索対象となっている表への更新を行っている

    2. 更新後、コミットを行っているためにUNDOブロックが上書きまたは開放されてし

       まう可能性がある

 

    そのため、対処方法は以下のようになります

    1. 検索と更新を同時に実行しないようにアプリケーションを見直す

    2. コミットを行わない、もしくはコミットの回数を減らしてUNDOブロックが

       上書きされる可能性を下げる

    3. UNDOブロックが上書きされるのを防ぐ

       Oracle9i 以降で UNDO_MANAGEMENT=AUTOの場合

         - 初期化パラメータ UNDO_RETENTION の値を増やす

         - UNDO表領域のサイズを増やす

       Oracle8i 以前、UNDO_MANAGEMENT=MANUAL の場合

         - RBSの数、サイズを増やす

         - 大き目のRBSをあらかじめ用意しておき、TRAN:Bに明示的にその大きなRBSを

           割り当てる (SET TRANSACTION ROLLBACK SEGMENT ... を使用)

         - OPTIMALが設定してある場合、その設定を大きくする

 

  (原因3)

    ブロッククリーンアウトが関連するケース

 

    上述の二つのケースは、いずれもORA-1555の発生する検索の実行中に、検索対象とな

    っている表に対する更新が行われていました。しかし、ブロッククリーンアウトが関

    連する場合、必ずしも検索の実行中に同じ表に更新が行われる必要はありません。

 

    トランザクションのコミット情報はデータブロック、それとRBSのトランザクション・

    テーブルの2箇所で保持されます。この情報には、コミット済みか否か、そしてコミッ

    ト時のSCN等の情報が含まれます。データブロックを更新した後にコミットを行なった

    時点では、RBSには必ずコミット情報が記録されますが、必ずしもデータブロックには

    コミット情報を記録しません。これは、コミットを高速に完了させるためです。別の

    トランザクションにおいて、該当のデータブロックが検索された際に

    「ブロッククリーンアウト」が発生します。この時点でデータブロックのトランザク

    ション情報が更新され、データブロックにもコミットされたことを示すフラグが立ち、

    コミットを行ったSCN、又は少なくともこのSCNではコミットを完了している、という

    情報が記録されます。

 

    これを踏まえて、以下のようなケースを想定してみます。

 

     SCN    TransactionA(TRAN:A)   TransactionB(TRAN:B)   Other Transactions

      10                           update TabA

      20                           commit;

      :

     110    select ... from TabA

     120       :

     130       :

     140       : select実行中                             多数の更新、コミット

               :

     150    ORA-1555

 

    TRAN:Aが検索を実行する前に、TRAN:Bが検索対象の表に対する更新を行っています

    この場合、TRAN:AはTRAN:Bが行った変更を読めばいいのですが、以下のようなシナ

    リオでORA-1555が発生し得ます

 

    1. TRAN:Bはコミットを行いましたが、更新対象のTabAのあるブロック(BL:1)に対し

       てはコミット情報の記録は行われていませんでした。BL:1上では、TRAN:Bによる

       更新は確定(コミット)されていない状態です。

 

  2. その後SCN:110でTRAN:AがTabAに対する検索を開始しました。但し、この時点でも

       BL:1に対するブロッククリーンアウトは行われていません。(つまりまだBL:1上

       では、TRAN:Bによる更新は確定(コミット)されていない状態です。)

 

    3. TRAN:AがTabAの検索を開始してからBL:1に対するブロッククリーンアウトが行わ

       れるまでの間にTRAN:A、B以外の多数のトランザクションが実行されました。これ

       らのトランザクションの中のあるものはTRAN:Bと同じRBSを使用し、TRAN:BがTabA

       の更新のために使用した情報を上書きしていきます。

 

    4. TRAN:AがBL:1を読み込みます。BL:1にはTRAN:Bが行った更新が未コミットの状態

    で残っています。TRAN:Aは読み取り一貫性のためTRAN:Bの状態を確認する必要が

       あります。もしTRAN:BがSCN:110より前にコミットしているのであればTRAN:Bの内

       容を読みこみ、SCN:110以降にコミットしているのであればTRAN:Bの変更前のビフォ

       アイメージを読み込まないといけません。

 

    5. TRAN:AはTRAN:Bの状態を確認するためにBL:1に残っているTRAN:Bが使用していた

       RBSの情報をもとにRBSを参照します。但し、3.のとおりTRAN:Bの情報は既に他の

       多数のトランザクションが実行されたために上書きされてしまっています。

 

    6. TRAN:Bが使用していたRBSの情報が他のトランザクションに上書きされているとい

       うことは、TRAN:B自体は完了していることを示しています。但し、TRAN:Bに関す

       る全ての情報が既に上書きされているため、TRAN:Bがコミットを行った正確なSCN

       を得ることができません。

 

    7. TRAN:AはTRAN:Bがコミットを行った正確なSCNを確認するために、TRAN:Bが使用し

       ていたRBSのトランザクション・テーブル自体に加えられた変更をロールバックし

       ていき、TRAN:Bがコミットを行ったSCNがSCN:110より前か後かを確認しようとし

       ます。これはトランザクション・テーブルに加えられた変更も、UNDOブロックに

       記録されているからです。

 

    8. TRAN:Bが使用していたRBSのトランザクション・テーブル自体に加えられた変更を

       ロールバックしていきましたが、最終的にトランザクション・テーブルのロール

       バックに必要なUNDOブロックが上書きされており、TRAN:BのコミットしたSCNと

       SCN:110との大小関係が確定できない場合はORA-1555が発生します。

 

    9. もしも、トランザクションテーブルをロールバックしていく最中で、TRAN:Bが

       使用していたスロットと同じスロットを利用しているトランザクションがあり、

       そのトランザクションが SCN:110 までにはコミットしていることが判明した場合、

       SCN:110 > そのトランザクション > TRAN:B という関係式が成り立つために

       TRAN:B は SCN:110 までにはコミット済み、で確定できます。

 

    この場合でも、必要なUNDOブロックが見つけられないためにORA-1555が発生してい

    るという点は同じです。

    また、その必要なUNDOブロックというのは **検索開始以降に作成されたもの** です。

    すなわち、SCN:110の時点にまでトランザクションテーブルをロールバックすることが

    できなかったために、TRAN:B と SCN:110 との大小関係が決定できずに

    ORA-1555 が発生しています。

 

    また、このケースでは、BL:1を更新後初めて読み込んだのはTRAN:Aとしていますが、

    TRAN:A以外のトランザクションがBL:1を読み込んだ場合でも同様の現象は発生します。

    読み込んだトランザクションがブロッククリーンアウトを行った時点で、前述ステッ

    プの5-6にて正確なコミットSCNがわからない場合は、その後TRAN:AがBL:1を読み込ん

    だ際に、前述と同様のステップを辿りTRAN:BがコミットしたSCNと自分が検索に使用す

    るSCN:110との大小関係が判断できず、ORA-1555が発生することが考えられます。

 

  (対処方法3)

    このケースの場合、以下の3つの要素が問題の原因となっています。

    1. TRAN:Aの検索の前にブロッククリーンアウトが行われていない

    2. TRAN:Aの検索の実行中に多数のトランザクションが実行されたために、TRAN:Bが

       使用していたトランザクション・テーブルが上書きされた

    3. TRAN:Bのトランザクション・テーブルを上書きした際のUNDOブロック情報が上書

       きまたは開放されて失われてしまった

 

    そのため、対処方法は以下のようになります

    1. Tab:Aが再度更新される前に、検索処理を再実行する

    2. ORA-1555が発生する検索処理の実行前に、ブロッククリーンアウトを行わせる

       通常、ブロッククリーンアウトは表に対して行えば十分ですが、索引ブロック

       に対するブロッククリーンアウトが必要となることもあります。

       表のブロッククリーンアウト:

          SQL> SELECT /*+ FULL(表名) */ COUNT(*) FROM 表名;

       索引のブロッククリーンアウト:

         - B-Tree索引が作成されている場合、

           SQL> SELECT /*+ INDEX(表名 索引名) */ COUNT(*) FROM 表名

            2 > WHERE 索引列 IS NOT NULL;

         - 複合索引の場合、検索対象列として全ての索引列を指定します。

           WHERE句の条件は 複合索引の先頭列 IS NOT NULL とします。

         - ビットマップ索引が作成されている場合

           SQL> SELECT /*+ INDEX(表名 索引名) */ count(*) FROM 表名

    3. ORA-1555が発生する検索処理を短縮させるように検索文のチューニングや、アプ

       リケーションの見直しを行う

    4. トランザクション・テーブルが上書きされる可能性を抑制する

         - コミットを行わない、もしくはコミットの回数を減らす

         - Oracle8i 以前、UNDO_MANAGEMENT=MANUAL の場合

           - RBSの数を増やす

           - TranBに相当する処理が特定できている場合は、TranBを実行させるための

             ロールバックセグメントを別に用意し、終了後オフラインにする。

             具体的には

             1. TranBの開始前にロールバックセグメント(以降 R1)をオンラインにする

             2. SET TRANSACTION USE ROLLBACK SEGMENT 句で明示的に指定、もしくは

                それ以外のロールバックセグメントをオフラインにし、TranB にロール

                バックセグメント R1 を使用させる

             3. TranBの処理の完了後、必要ならば shrink した上でロールバックセグ

                メント R1 をオフラインにする。

             4. 2.でオフラインにしたロールバックセグメント(あれば)をオンラインにする

    5. UNDOブロックが上書きされるのを防ぐ

       Oracle9i 以降で UNDO_MANAGEMENT=AUTOの場合

         - 初期化パラメータ UNDO_RETENTION の値を増やす

         - undo表領域のサイズを増やす

       Oracle8i 以前、UNDO_MANAGEMENT=MANUAL の場合

         - RBSの数、サイズを増やす

         - 大き目のRBSをあらかじめ用意しておき、TRAN:Bに明示的にその大きなRBSを

           割り当てる (SET TRANSACTION ROLLBACK SEGMENT ... を使用)

         - OPTIMALが設定してある場合、その設定を大きくする

 

    注 R9.0.1以降、ダイレクト・ロードあるいはダイレクトインサートによる変更は

       上記の方法ではクリーンアウトされなくなりました。これは検索時のパフォーマ

       ンスを上げるための変更です。

       そのため、TranBがダイレクト・ロードに相当しているケースでは、対処方法と

       して 2. 以外のものを採用してください。

 

  (原因4)

    LOBセグメントでORA-1555が発生するケース

 

    LOB列がLOBセグメントに格納されている場合、LOB列に対して加えられた変更のUNDO

    情報はRBSには書き込まれず、LOBセグメント内で処理が行われます。

 

    具体的には、更新を行った際にも、新しいブロックを取得し、そこに変更後のLOBデー

    タを書き込みます。変更前のLOBデータはそのまま残され、ロールバックが行われた

    際に再利用されます。コミットを行った後にも変更前のLOBデータはそのまま残され、

    読取り一貫性により使用されます。変更前のLOBデータは上書き可能な状態として残

    され、新規ブロックが必要となった場合に古いものから使用されていきます。

    読取り一貫性のために必要なデータが上書きされて消えていた場合にはORA-1555が発

  生します。

    # インラインLOB、すなわちLOB列が元の表と同じセグメントに格納されている場合

    # はUNDO情報は通常のケースと同様にRBSに書き込まれるため、原因1-3と同等の

    # ケースでのORA-1555が発生します。

 

    この場合の典型的なケースは以下のようになります。

    # TabAの列c1がLOB列とします。

     SCN    TransactionA(TRAN:A)  TransactionB(TRAN:B)   Other Transactions

      10    select c1 from TabA

      20       :                  update TabA.c1

      30       :                  commit

      40       : select実行中                            TabA.c1への多数の更新

               :

      50    ORA-1555

 

    1. TRAN:AはSCN:10の時点でのc1列のデータを必要とする検索を開始します

    2. TRAN:BはTRAN:Aが必要とする行のc1列の値を変更し、コミットを行います

       この時点では、更新前の列値はLOBセグメント上に残されたままです

    3. その他のc1列を更新するトランザクションにより、TRAN:Bによる更新前の

       データが上書きされます

    4. TRAN:Aは更新前のデータを読み取れず、ORA-1555となります

 

    このケースでは、以下のようなエラーメッセージを伴います。

    ORA-1555にはRBSの番号、名称は記されず、ORA-22924を伴うことに注意して下さい。

 

    SQL> select c2 from t1;

    ERROR:

    ORA-01555: snapshot too old: rollback segment number  with name "" too small

    ORA-22924: snapshot too old

 

  (対処方法4)

    このケースの場合、以下の2つの要素が問題の原因となっています。

    1. TRAN:Aの検索の実行中にLOB列への多数の更新処理が行われた

    2. TRAN:Bの更新前のデータが上書きされた

 

    そのため、対処方法は以下のようになります

    1. 検索と更新を同時に実行しないようにアプリケーションを見直す

    2. 更新前のデータが残されているLOBセグメントが上書きされるのを抑えるために、

       LOBセグメントのPCTVERSIONの値を大きくする

 

       LOB列のPCTVERSIONの値は以下のSQLにより確認できます

 

    SQL> select pctversion from user_lobs

     2   where table_name='<表名>' and column_name='<列名>';

 

    PCTVERSION

    ----------

            10

 

    PCTVERSIONの値は以下のSQLにより変更できます

 

    SQL> alter table <表名> modify lob ( <列名> ) (pctversion <新規PCTVERSION値>);

 

 

  (原因5)

    READ ONLYトランザクションを使用しているケース

 

    OracleのREAD ONLYトランザクションは、トランザクション開始時のデータを読み込

    む、というレベルでの読取り一貫性を行います。通常のREAD WRITEトランザクション

    では、SQL文単位での読取り一貫性なので、それよりも古い時点でのデータを読み込

    む必要があります。そのため、通常のREAD WRITEトランザクションよりもORA-1555が

    発生しやすくなります。(原因1)のケースを例に取ると

 

     SCN    TransactionA(TRAN:A)         TransactionB(TRAN:B)   Other

      10    set transasction read only;

      20                                 update TabA

      30                                 commit

      40                                                  多数の更新、コミット

      50    select from TabA

 

    1. SCN:10でTRAN:AがREAD ONLYトランザクションを開始します

    2. TRAN:BによりTabAの更新が行われ、変更はコミットされます

    3. 多数のトランザクションにより、TRAN:Bが使用していたUNDOブロックは上書きさ

       れます

    4. TRAN:AがTabAへの検索を実行します。TRAN:AはSCN:10の時点でのTabAのデータを

       必要とします。

    5. TabAはTRAN:Bにより更新が行われているため、TRAN:AはTRAN:Bが使用したUNDOブ

       ロックを利用してビフォアイメージを作成しようとしますが、すでにUNDOブロッ

       クは上書きされているためにORA-1555が発生します。

 

    READ ONLYトランザクションのケースでは、これまでと異なり検索文の実行中に更新、

    コミットが行われる必要がありません。そのため、ORA-1555が発生し易くなります。

 

  (対処方法5)

    このケースの場合、これまでのケースに加え以下の2つの要素が問題の原因となって

    います。

    1. TRAN:AがREAD ONLYトランザクションを使用している

    2. READ ONLYトランザクションの実行中に、READ ONLYトランザクションが検索対象

       とする表への更新を行っている

 

    そのため、対処方法は以下のようになります

    1. READ ONLYトランザクションを使用しない

    2. READ ONLYトランザクションの実行中に、READ ONLYトランザクションが検索対象

       とする表への更新を行わない

 

 

  (原因6)

    RBSが削除されている、または破壊されている

 

    これまでに紹介してきたような例で、RBSへの参照を行ったときにそのRBSが

    drop rollback segmentにより削除されているような場合を考えます。その場合、

    RBSの内容は参照できないため、ORA-1555のエラーが発生します。但し、トランザク

    ションの正確なコミット時刻を知るためにRBSを参照した場合は、RBSを削除した際の

    SCNがデータベース上に残されるため、少なくともそのSCNではトランザクションはコ

    ミットを行っていた、という情報として使用します。

 

    また、RBSがブロック障害等で破壊している場合も、RBSの内容を参照できないため

    ORA-1555のエラー(と、ブロック障害を示すエラー)が発生し得ます。

 

  (対処方法6)

    ブロック障害、メディア障害で破壊されているようなケースでは、再試行を行った場合

    でもORA-1555が発生すると考えられるため、まず障害のリカバリを行います。

    RBSが削除されたためにORA-1555が発生しているようなケースでは、RBSの削除を可能

    な限り行わないようにします。

 

 

  (原因7)

    データベース・リンクを使用しているケース

 

    データベース・リンクを使用した分散トランザクションでは、これまでに概説して

    きた単体のデータベースにのみアクセスしている時よりも複雑な問題が発生する

    ことがあります。これは、データベース・リンクで結ばれているデータベースで

    それぞれSCNを管理しているためです。

 

    詳細については、Document 1744230.1(KROWN:130846) をご参照下さい。

 

    例として、マテリアライズド・ビューの refresh 時に予想外に ORA-1555 が

    発生することがあります。詳細な内容、対処方法は Document 1731156.1(KROWN:99762) をご参照下さい。

 

 

[取得情報]

 

  上記の調査、対処の後にもORA-1555の発生が抑えられない場合は、ここまでの調査結果

  に加え、エラーが発生したアプリケーションの処理内容、エラー発生時に実行されてい

  た他のトランザクションの情報、ORA-1555発生時のエラーメッセージを添えて新規TAR

  を登録してください。