Email: service@parnassusdata.com 7 x 24 online support!
Oracle ORA-1410 の主な発生原因とその対処方法について
ORACLEデータベース によくあるエラ の解決策
プロのOracle Databaseの復旧サービスを提供
携帯番号: +86 13764045638 メール:service@parnassusdata.com
[エラー・メッセージ] ORA-01410: ROWIDが無効です。 [技術的説明] - ROWID の説明 ROWID は行に直接アクセスするためのアドレスです。ROWID には、オブジェ クト番号、相対ファイル番号、ブロック番号、ブロックのスロット番号の情報 が含まれます。 Oracle8 以降のバージョンでは、以下の形式となっています。 ------------------------------- OOOOOOFFFBBBBBBSSS O:オブジェクト番号 (データ長:6) F:相対ファイル番号 (データ長:3) B:ブロック番号 (データ長:6) S:スロット番号 (データ長:3) ------------------------------- - エラー内容説明 ORA-1410 は ROWID が不正であることを示します。 ROWID の解析時に、該当の行が存在しないと ORA-1410 が発生する可能性が あります。 - 相対ファイル番号およびブロック番号は正しいが、行スロットが存在しな い場合には「レコードが選択されませんでした」というメッセージが返さ れます。 - スロット番号以外の箇所に問題がある場合、ORA-1410 が返されます。 [ORA-1410 の主な発生原因] 1.ブロック破損により発生 2. ROWID の破損により発生 ROWID が破損した場合、ROWID のコピー(例:索引)、また上書きされた ROWID が示す表が破損する可能性があります。索引が破損した場合、索引に は誤った ROWID が格納されているために、行データにアクセスした時に ORA-1410 が発生します。同様に、もし行データが破損した場合、ブロック・ アドレスが上書きされ、索引に格納された正しい ROWID では、行データを 見つけることができなくなります。 ROWID の破損には以下の原因が考えられます。 2-1.SQL文によって誤った ROWID が挿入された、またはユーザが作成した PL/SQLプロシージャの誤ったロジックによって不正な ROWID が生成され た。 2-2.ハードウェア障害により、内部的に生成された ROWID がメモリ上で破損 した。 この場合、OS エラーのメッセージを確認してください。 2-3.破損した索引から ROWID を読み込んだ。 このケースでは、多くの場合 ORA-1410 に伴って、その他の破損に関す るエラーが返されます。 2-4.長時間かかる検索を実行中に、検索対象のオブジェクトに対して DDL文 を実行した。 例えば、索引を利用した検索を実行中に、その索引を再作成すると ORA-1410 が発生します。 2-5.ROWID は正しいが、データ・ブロックまたはデータファイルが上書きさ れて破損し、ブロック・アドレスが不正になった。 このケースでは、多くの場合 ORA-1410 に伴って、その他の破損に関す るエラーが返されます。 2-6.ROWID は正しいが、直前にポインタが動いた。 SQL文の実行中に、表が切り捨てられた時などに発生します。これは、 SQL文はキャッシュされた ROWID を使用してアクセスしようするのに対し、 ブロックは表の切り捨てによって削除されているためです。 SQL文の実行中に、表パーティションの交換が行われた時にも同様の事象 が発生します。 2-7.Oracle、OS の不具合や、その他アプリケーションの不具合によるもの。 Oracle の不具合である場合は、日本オラクルカスタマーサポートセンター に連絡してください。 [現象発生時の対処方法] 1.エラーの再現が可能か確認 ORA-1410 の再現が可能であれば、トレース・ファイルを取得します。 トレース・ファイルが生成されない場合には、強制的に取得する必要があり ます。 トレース・ファイルを強制的に取得するには、エラースタック・イベントを セットし、エラーを再現します。 エラースタック・イベントは以下のように設定します。 SQL> alter system set events '1410 trace name ERRORSTACK level 3'; トレース・ファイルから失敗した SQL文を特定します。失敗した SQL文は トレース・ファイルの上部に記されています。トレース・ファイルの解析が 難しい場合は 日本オラクルカスタマーサポートセンター連絡し、トレース・ ファイルを提供してください。 2.エラーが再現しない場合 もし再現できない場合は、エラーが発生した時刻の前後に表の切り捨て、 または表パーティションの交換を実行していないかを確認します。 もしどちらかを実行していた場合は、エラーは一時的なものです。該当の表 を読み込んでいる間は表の切り捨て、表パーティションの交換は行わないよ うにしてください。スケジュールを見直すことをお勧めします。 3.エラーが再現可能な場合 ORA-1410 が再現可能な場合、失敗した SQL文でアクセスしている表を特定 します。SQL文 の FROM句で指定している表が該当の表です。もしビューを 参照している場合には、ビューの定義から元となっている表を探します。 4.表と索引の検証 3 で特定した表が破損しているか調べるために検証を実行します。 "ANALYZE ・・・ VALIDATE" は表のロックが必要になります。もしユーザが 表を更新するためにアクセスしている場合は、ユーザの処理が終わるまで VALIDATE 実行することはできません。もし VALIDATE を実行できた場合は、 VALIDATE が終了するまで、ユーザは表を更新することはできません。 参考: Document 1706766.1(KROWN:22496) ANALYZE中のDML処理について 表の検証、表に作成された索引の検証は、以下のように行います。 SQL> analyze table <owner>.<table_name> validate structure; SQL> analyze index <owner>.<index_name> validate structure; パーティション表については Document 1703145.1(KROWN:13655) や Note 111990.1 をご確認くだ さい。 参考: Document 1703145.1(KROWN:13655) パーティション表の検査のために analyze を実行すると ORA-14508 が発生する 4-1. "VALIDATE"にエラーが返る場合は表が破損していますので、最新の バックアップからリカバリする必要があります。 4-2. ORA-1410 が発生せずにテーブル・フルスキャンができる場合、テーブ ルの再作成( export/import ユーティリティの利用、create table as select による再作成)を行います。 4-3.索引の"VALIDATE" でエラーが返る場合は、索引を削除して再作成する 必要があります。 4-4.表とすべての索引の"VALIDATE"が問題なく行われる場合には、誤った ROWID がメモリ上にキャッシュされた可能性があるため、共有プールの フラッシュによりクリアします。共有プールのフラッシュは、共有プール が通常の状態に戻るまで、一時的にパフォーマンスに影響を与える可能性 があります。索引の ROWID がメモリ上で不正になっている場合にも、 バッファキャッシュのフラッシュは有効ですが、索引がディスク上で破 損している場合には、初めに索引を使用した時に ORA-1410 が再び返さ れます。 SQL> alter system flush shared_pool; 以上の対処を行っても ORA-1410 が発生し続ける場合、Oracle の不具合であ る可能性があります。詳細な調査を行うため、日本オラクルカスタマー サポートセンターにお問い合わせください。 [既知の問題] Document 1738872.1(KROWN:124422) 2 億件以上のデータに対し、テキスト索引を作成した場合にエラー発生 [補足事項] - ROWID の復号 dbms_rowid パッケージの rowid_info プロシージャを使用して ROWID を復号 することができます。以下は、PL/SQL 無名ブロックを用いて ROWID を復号 した例です。 例: SQL> set serveroutput on SQL> declare my_rowid rowid := 'AAAR6tAAEAAAACeAAA'; -- 復号する ROWID を指定 rowid_type number; object_number number; relative_fno number; block_number number; row_number number; begin dbms_rowid.rowid_info(my_rowid, rowid_type, object_number, relative_fno, block_number, row_number); dbms_output.put_line('ROWID: ' || my_rowid); dbms_output.put_line('Object#: ' || object_number); dbms_output.put_line('RelFile#: ' || relative_fno); dbms_output.put_line('Block#: ' || block_number); dbms_output.put_line('Row#: ' || row_number); end; / ROWID: AAAR6tAAEAAAACeAAA Object#: 73389 RelFile#: 4 Block#: 158 Row#: 0 PL/SQLプロシージャが正常に完了しました。 -- オブジェクト名の検索 (オブジェクト番号:73389) SQL> col owner for a10 SQL> col object_name for a30 SQL> select owner,object_name,object_type,data_object_id from dba_objects where data_object_id = 73389; -- データファイル名の検索 (相対ファイル番号:4) SQL> select file_name from dba_data_files where file_id = 4; - ORA-1410 を発生させる例 ここでは ORA-1410 をさせる簡単な例について説明します。 例: 1.簡単な表を作成し、2行挿入する -- 簡単な表の作成 SQL> create table tab1 (col1 varchar(2), col2 varchar2(2)) > tablespace users; 表が作成されました。 -- 2 行追加、コミット SQL> insert into tab1 values('aa','11'); 1行が作成されました。 SQL> insert into tab1 values('aa','22'); 1行が作成されました。 SQL> commit; -- ROWID の表示 SQL> select rowid from tab1; ROWID ------------------ AAAR6tAAEAAAACeAAA AAAR6tAAEAAAACeAAB 2.不正なスロット番号(ROWID の末尾3桁)を使用した検索 ROWID の末尾3桁 はスロット番号を表します。スロット番号 のみ変更し、 存在しない ROWID で検索をすると「レコードが選択されませんでした。」 というメッセージが返されます。 SQL> select * from tab1 where rowid = 'AAAR6tAAEAAAACeAAC'; レコードが選択されませんでした。 3.不正なブロック番号(ROWID の10-15桁目)を使用した検索 ブロック番号を故意に不正なものに変更し、検索します。 SQL> select * from tab1 where rowid = 'AAAR6tAAEFFFFCeAAC'; select * from tab1 where rowid = 'AAAR6tAAEFFFFCeAAC' * 行1でエラーが発生しました。: ORA-01410: ROWIDが無効です。 これは ROWID が破損した場合の例となります。 4.オブジェクトの操作により正しい ROWID で ORA-1410 が発生する例 この例では、表を TRUNCATE して、ROWID にどのような影響があるかを見ます。 -- 表の ROWID を確認 SQL> select rowid from tab1; ROWID ------------------ AAAR6tAAEAAAACeAAA AAAR6tAAEAAAACeAAB -- rowid を使用して表のすべての列を検索 SQL> select * from tab1 where rowid = 'AAAR6tAAEAAAACeAAA'; CO CO -- -- aa 11 -- TRUNCATE TABLE SQL> truncate table tab1; 表が切り捨てられました。 -- 先ほどの SELECT文を使用し正しい ROWID で検索 SQL> select * from tab1 where rowid = 'AAAR6jAAEAAAACPAAA'; select * from tab1 where rowid = 'AAAR6jAAEAAAACPAAA' * 行1でエラーが発生しました。: ORA-01410: ROWIDが無効です。 これは、よく発生する ORA-1410 の例です。SQL文は ROWID をメモリ上 にキャッシュしていますが、表は切り捨てられており、表のすべての ブロックはなくなっています。キャッシュされた ROWID で検索すると、 ORA-1410 が発生します。 表パーティションを交換して非パーティション表にする時にも同じ現象 が発生します。このケースではファイル番号が変わるため、メモリ上に キャッシュされたROWID を使用した SQL文にはすべて ORA-1410 が返さ れます。