7 x 24 在线支持!
Oracle ORA-1410 の主な発生原因とその対処方法について
ORACLEデータベース によくあるエラ の解決策
プロのOracle Databaseの復旧サービスを提供
携帯番号: +86 13764045638 メール:[email protected]
[エラー・メッセージ]
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 が返さ
れます。

沪公网安备 31010802001377号