Email: service@parnassusdata.com 7 x 24 online support!
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データ全体がアクセスできるサイズに設定してください。