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

Oracle リカバリ時にORA-600[3020]が発生

Oracle リカバリ時にORA-600[3020]が発生

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

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

 

[起こりうる現象]

リカバリにおいてREDOを適用する際に、ORA-600[3020]が発生する場合があります。

※ORA-600[3020]は、リカバリ時におけるREDOの情報とそのREDOを適用しようと
したブロックの情報に不整合を検知した場合に発生します。

[対象リリース]
問題が発生するリリース  :Oracle8i (8.1.X)
                         Oracle9i Database(9.0.1)
問題を修正したリリース  :Oracle9i Database Release2 (9.2.0)
問題を修正したPSR       :なし
問題を修正予定のPSR     :なし


[対象プラットフォーム]
すべてのプラットフォーム


[起こりうる条件]
下記の2つの条件を満たした場合に本件の現象が発生します。

(1) 同一LOBブロックに対して同一トランザクション内で複数回更新を行う
(2)  (1)を実行後にそれによって生成されたREDOを適用する


[原因]
製品の不具合です。
REDO適用時における、ダイレクト・オペレーションが実行されたブロックへ
のREDOの判定方法に問題がありORA-600[3020]が発生します。
作成されているREDO自体に問題はありません。


[回避策]
有効な回避策はありません。


[現象発生時の対処方法]
下記のいずれかの対処を実行して下さい。

1) [起こりうる条件]を満たさない条件下で生成されたREDOを適用してリカバリ
  を行う

他のタイミングで取得したバックアップに対して上記の[起こりうる条件]を満た
さない条件下で生成されたREDOが存在する状態であれば、これらを使用してリカ
バリすることをお奨めします。

2)エラーが発生する前まで不完全リカバリを行う

3) Oracle9iでは、allow 1 corruption 句を使用してリカバリを行なう

この方法ではORA-600[3020]が発生したブロックのLOBデータは失われ、
テーブルの再作成が必要になります。具体的には、以下の手順となります。

3-1)allow 1 corruption 句を使用してリカバリを行ない、DBをOPENさせる。

allow 1 corruption 句の詳細については下記のマニュアルのP5-8をご参照下さい。

Oracle9i ユーザー管理バックアップおよびリカバリ・ガイド リリース1(9.0.1)
部品番号:J04126-01


3-2) ORA-600[3020]の第一引数から、テーブルを特定します。

ORA-600 [3020], [180369706], [1],[47068], [46424], [248], [], []
ORA-600の第一引数は上記の例の場合は、180369706となります。
ORA-600の第一引数を使用し、以下のSQL文にて該当のオブジェクトを特定します。
以下の例では、第一引数が180369706の場合です。

 select owner,segment_name,segment_type
 from dba_extents
 where file_id = dbms_utility.data_block_address_file(180369706)
 and dbms_utility.data_block_address_block(180369706) 
     between block_id and (block_id + blocks -1) ;

3-3) 3-2)で特定したテーブルを再作成します。
テーブルの元データが存在し、データを入れ直すことができる場合には、
テーブルの削除、再作成後にデータを入れ直してください。
テーブルのEXPORT時にも エラーが発生することがあります。
EXPORTできない場合には、アクセスできない行を特定して、その行のLOBデータ
以外のデータを救い出して再作成してください。
 例:
   1. テーブルのROWIDのリストを作成
       SQL> select rowid from <エラーが発生する表名>;
   2. アクセスできる部分のみを抽出するための同じ構成の表を作成
       SQL> create table <抽出表名>
            as select * from <エラーが発生する表名> where 1=0;
      ※ STORAGE句やLOB属性などは必要に応じて指定してください。
   3. WHERE句にROWIDを指定して検索し、1行ずつコピー
       SQL> insert into <抽出表名> select * from <エラーが発生する表名>
            where rowid = '<1で得たROWID>';
       --> エラーが出ない行はLOBデータを含めて抽出表にコピーされます。
           エラーになった行はLOBデータにアクセスできない行です。
   4. アクセスできない行はLOBデータ以外を抽出
       SQL> insert into <抽出表名> (<LOB以外のカラムのリスト>)
            select <LOB以外のカラムのリスト> from <エラーが発生する表名>
            where rowid = '<3.でエラーが発生したrowid>';

  3 (エラーが発生した場合は4)をすべての行に対して行うことで、抽出表の方
 にアクセス可能な部分が抽出されます。
  抽出表を作成する領域を確保できない場合は、1行ずつselectしながらエラー
 が発生する行を特定することもできますが、その場合はSQL*Plusのシステム
 変数LONGの値を、LOBデータ全体がアクセスできるサイズに設定してください。