Oracle ORA-1410 “invalid ROWID”を解決する

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

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

 

適用範囲

Oracleデータベース – エンタプライズバーション – 8.0.6.0 から12.1.0.2まで [Release 8.0.6 to 12.1]
このファイルの情報はどのプラットフォームにも適用できる。

目的

ORA-1410の原因について探る。Rowidを研究し、トラブルがどうやって起きたのか探ってみよう。

範囲

ORA-1410エラを診断してみよう。

细节

ORA-1410エラを研究する

ORA-1410はROWIDが無効と意味している。このエラはオペレーションがあるテーブルのROWIDを参考したが、該当するラインを返されていない。

ROWIDは何だろう?

ROWIDはデータをアクセスするための構造であり、オブジェクト番号、データファイル番号、ブロック番号及びブロックのライン番号情報も含んでいる。

Oracle 8あるいはより高いバーションには以下のようなフォーマットのROWIDを含んでいる:

OOOOOOFFFBBBBBBSSS
O=Data Object Number (length=6)
F=Relative File Number (length=3)
B=Block Number (length=6)
S=Slot Number (length=3)

Decoding ROWID

dbms_rowidパッケージ(rowid_info プロセス)ROWIDの構造をデコーディングするために利用できる。

次のPL/SQLブロックはROWIDをデコーディングする:

SQL> set serveroutput on
SQL> declare
my_rowid rowid := ‘AAAQUeAAEAAAAGkAAB’;   — or any 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:   AAAQUeAAEAAAAGkAAB
Object#:      66846
RelFile#:     4
Block#:       420
Row#:         1

PL/SQL procedure successfully completed.

— To identify the object name (object# 66486)
SQL> select *
from dba_objects
where data_object_id = 66846;

— To find the datafile name (Relfile# 4)
SQL> select file_id, file_name
from dba_data_files
where RELATIVE_FNO = 4;

ORA-1410が起こった原因

Oracleがrowid(ファイル番号、ブロック番号、ライン番号情報)を解析する。ラインが存在していなければ、ORA-1410エラになる:

  • もしファイル番号もブロック番号も有効であれば、ライン番号だけがトラブルになった場合に、”no rows selected”が返される。
  • もしrowidにトラブルが起こったら、ORA-1410エラになる。 ORA-1410とはROWIDのBLOCKがそのテーブルに含んでいない
  • ORA-1410はよくブロック損害とつながる。これはよくエラを引き起こすから。でも別の原因も含んでいる。

ここでORA-1410になる原因をリストする:

1、あるSQL文で、人工的に誤ったrowidを入力する、あるいはロジックが誤ったPL/SQLプロセスに誤ったrowidを作成する.

2、rowidは内部的に作成されたが、メモリで壊れた。

3、この壊れたrowidはインディクスから再び獲得したもので、ORA-1410エラ及び付きそう関連情報にも注目してください。

4、この間に、これらのオブジェクトのクエリDDLオブジェクトにアクセスしてください。例えば、インディクスを再構造することで、ORA-1410にSQL文がインディクスをアクセスする。

5、もしrowidは有効だが、そのデータベースあるいはデータファイルが壊れた(上書きされた)場合に、ブロックアドレスもエラになるかもしれない。では、ORA-1410エラの情報に注目してください。

6、rowidは有効だが、指定したブロックが移動された。これはあるプロセスで、SQL文があるテーブルを切ったからである。それで、SQLがあるrowidをメモリした。けどブロックは既に削除された。この場合にあるSQL文の実行プロセスでテーブルパーティションを変更した。この場合に、ファイル番号も変更された。SQL文がORA-1410エラになる。

7、データベースBUG,オペレーションシステムBUG あるいは別のアプリBUG。

どうやってORA-1410エラを作成する例

第一步、まずは簡単なテーブルを作成し、一行か二行のデータを追加する

  • First create a simple table with one or two columns.
  • Then insert a couple of rows and commit.
  • Then display the rowids

— Create a simple table
SQL> create table tab1 (col1 varchar(2), col2 varchar2(2)) tablespace users;
Table created.

— Add a couple of rows and commit
SQL> insert into tab1 values(‘aa’,’11’);
1 row created.

SQL> insert into tab1 values(‘aa’,’22’);
1 row created.

SQL> commit;
Commit complete.

— Display the rowids
SQL> select rowid from tab1;
ROWID
——————
AAAQUYAAEAAAAGkAAA
AAAQUYAAEAAAAGkAAB

第二步,增长一下行号,看会出现什么结果(修改一下rowid的最后三位)

  • Increment the last rowid slot by 1 (so . . . . AAB becomes . . . . . .AAC), and select from the table using this non-existent rowid. Since we changed only the last value, only the slot was changed, and no rows were selected.

The example is using rowid AAAQUYAAEAAAAGkAAB:

— Increment the slot number by 1 (AAB becomes AAC).
SQL> select * from tab1 where rowid = ‘AAAQUYAAEAAAAGkAAC’;
no rows selected

OR
— overwrite the slot value with FFF
SQL> select * from tab1 where rowid = ‘AAAQUYAAEAAAAGkFFF’;
no rows selected

在上面的例子,简单的修改了行号,结果是显示“没找到行”,这是没有什么恶意的信息。

第三步 rowidのブロック番号を変更し、どういう結果に導かれるか探ってみよう

— Now change the block number (AAAAGk becomes FFFFGk) and select.

SQL> select * from tab1 where rowid = ‘AAAQUYAAEFFFFGkAAB’;
select * from tab1 where rowid = ‘AAAQUYAAEFFFFGkAAB’
*
ERROR at line 1:
ORA-01410: invalid ROWID

前の例で、rowidのブロックアドレスが変更された。その原因は以下の通り:

  • あるコードがメモリに書き込まれた。このコードはOracleに属していてoracle bugかもしれない。もしコードがオペレーションシステムに属していれば、オペレーションbugかもしれない。コードがアプリに属していれば、スポンサーに連絡してください。Oracle bugなら、Oracle技術サポートに連絡してください。
  • あるメモリがエラになって、ハードウェアが故障した場合に、メモリアドレスも壊れる。
  • あるrowidの作成が誤った。Oracleコードも手製したアプリコードも関係ない。

損害がrowidを壊すだけじゃなく、インディクスオブジェクト、テーブルオブジェクトも壊れるかもしれない。インディクスが破壊されたら、インディクスrowidに誤った部品があるかもしれない。ORA-1410になる。これで、データラインをアクセスする。そのようで、データの部分(テーブル)が破壊され、ブロックアドレスが上書きされるかもしれない。それに、インディクスから有効なrowidがそのブロックを見つけられない場合にORA-1410が再び現れる。

第四步 データオブジェクト番号を変更し、ORA-1410になった例:
In this example, the table is TRUNCATEd; observe the effect on the rowid.

— Show the two rowids in the table
SQL> select rowid from tab1;
ROWID
——————
AAAQUYAAEAAAAGkAAA
AAAQUYAAEAAAAGkAAB

— Select all columns from the table using one of the  rowids.
SQL> select * from tab1 where rowid = ‘AAAQUYAAEAAAAGkAAA’;
CO CO
— —
aa 11

— Now truncate the table
SQL> truncate table tab1;
Table truncated.

— Rerun the previous select statement using the known valid rowid.
SQL> select * from tab1 where rowid = ‘AAAQUYAAEAAAAGkAAA’;
select * from tab1 where rowid = ‘AAAQUYAAEAAAAGkAAA’
*
ERROR at line 1:
ORA-01410: invalid ROWID

前の例ではORA-1410エラになる原因を示した。あるSQL文が一部ののROWIDをメモリに格納する。テーブルで一部のデータを選ぶ。同時にそのテーブルが切られたとはそのテーブルにすべてのブロックが存在しなくなった。それで、これは実行したクエリ文のROWIDで、ORA-1410になった。もしあるテーブルパーティションが変わって、独立したテーブルになり、どんなSQLを実行してもORA-1410になる。

解決策

1、第一步,エラが再び現れるかどうか探ってみよう
ORA-1410が再び現れるなら、トレースファイルを作成することが大切になる。

もしエラが再び現れないなら、強制的に作成してください。エラスタックトランザクションを設定して、エラを再現する:

alter system set events ‘1410 trace name ERRORSTACK level 3’;
alter session set events ‘10236 trace name context forever, level 1′;
alter session set tracefile_identifier=’ORA1410’;
— Then reproduce the error.

トレースファイルから失敗した文を探し出して、ファイルヘッダの近くにあるはずである。

トレースファイルが分からなければ、Oracle技術サポートに連絡してください。

トラブルを確認して、再び実行し、ORA-1410になる原因となった文を確認して、トレースファイルからエラ文を探し出す。

 

2、エラが再び現れない

再び現れない場合に、エラが現れた場合にテーブルが切られたか確認してください。あるいはどこのテーブルパーティションが変更されたか確認する。その解決策とは、テーブルを読み取るSQL文を実行する場合に、テーブルを切ることとテーブルパーティションを変更することを避ける。

 

  1. エラが再び現れる.

もしORA-1410が再び現れるなら、失敗した文からアクセスされたFROMサブ文のテーブルを見つけ出す。故障した文であるビュを使った。ビュ定義のベーステーブルを探し出して、次のステップに移してください:

4、テーブルとインディクスを確認する

テーブルとインディクスでオンライン文を実行して、エラを検証する:

SQL> analyze table <owner>.<table_name> validate structure ONLINE;

–For each index on the table, run a validate also
SQL> analyze index <owner>.<index_name> validate structure ONLINE.

–For a partitioned table, refer to Doc ID 111990.1

  • もしテーブル検証であるエラが返されたら、テーブルが壊れたと意味している。最新のバックアップからリカバリしてください。
  • インディクス検証でエラが返されたら、インディクスを削除して再構造する。
  • もしテーブルに数々の検証にエラがなければ、壊れたrowidがメモリにあると意味している。これはバッファキャッシュをフラッシュすることで、あるいは共有プールで解決できる:

SQL> alter system flush buffer_cache;

SQL> alter system flush shared_pool;

最後に、もしORA-1410エラがなかなか解決出来ないなら、Oracle BUGについて考えてください。以下のようなbugリストを参考して、より深刻な調査を実行してください:

Note:1671526.1 – Required Diagnostic Data Collection for ORA-01410:

NB Prob Bug Fixed Description
II 17604137 12.1.0.2, 12.2.0.0 ORA-600 [25026] when running query on table being dropped V11020001 V11020002 V11020003 V11020004 V12010001
I 17204397 12.1.0.2, 12.2.0.0 ORA-8005 ORA-8103 ORA-1410 ORA-600 [kdsgrp1] on Bitmap Index. Root Block may be repeatedly pinned/unpinned V10020002 V10020003 V10020004 V10020005 V11010006 V11010007 V11020001 V11020002 V11020003 V11020004 V12010001
II 12821418 11.2.0.3.8, 11.2.0.3.BP18, 11.2.0.4, 12.1.0.1 Direct NFS appears to be sending zero length windows to storage device. It may also cause Lost Writes V11010006 V11010007 V11020001 V11020002 V11020003
III 10385812 11.2.0.2.BP20, 11.2.0.3, 12.1.0.1 ORA-1410 or ORA-8103 by queries with DIRECT READ while concurrent DIRECT INSERT V11020001 V11020002
+ II 10209232 11.1.0.7.7, 11.2.0.1.BP08, 11.2.0.2.1, 11.2.0.2.BP02, 11.2.0.2.GIBUNDLE01, 11.2.0.3, 12.1.0.1 ORA-1578 / ORA-600 [3020] Corruption. Misplaced Blocks and Lost Write in ASM V11010006 V11010007 V11020001 V11020002
II 9275027 11.2.0.2, 12.1.0.1 ORA-600 [kcbnew_3] can occur after TRUNCATE / DROP V10020002 V10020003 V10020004 V10020005 V11010006 V11010007 V11020001
III 8740993 11.1.0.7.8, 11.2.0.2, 12.1.0.1 ORA-1410 / ORA-8103 on ADG STANDBY during table scan after DROP/TRUNCATE/SHRINK in PRIMARY V11010006 V11010007 V11020001
II 8716064 11.2.0.2, 12.1.0.1 Analyze Table Validate Structure fails on ADG standby with several errors V11010006 V11010007 V11020001
+ II 8597106 11.2.0.1.BP06, 11.2.0.2, 12.1.0.1 Lost Write in ASM when normal redundancy is used V11010006 V11010007 V11020001
II 7710827 11.2.0.2, 12.1.0.1 Index rebuild or Merge partition causes wrong results in concurrent reads instead of ORA-8103 V10020002 V10020003 V10020004 V10020005 V11010006 V11010007 V11020001
9167831 11.2.0.2 ORA-8103 instead of ORA-1410 V11020001
6621068 10.2.0.5, 11.1.0.6 ORA-8176 or ORA-1410 from SELECT with concurrent Partition Exchange V10020002 V10020003 V10020004
I 5637976 10.2.0.4, 11.1.0.6 ORA-8103/ORA-1410 from concurrent INSERT / export on ASSM tables V10020002 V10020003
I 5596325 10.2.0.4, 11.1.0.6 Text query gives wrong results or fails with ORA-1410 ORA-29903 V09020008 V10010005 V10020002 V10020003
II 4592596 10.2.0.4, 11.1.0.6 Corruption (ORA-1410 / ORA-8103) from multi-table insert with direct load V09020008 V10010005 V10020002 V10020003
I 3868753 9.2.0.7, 10.1.0.5, 10.2.0.1 Concurrent export / INSERT of ASSM segment can fail with ORA-1410 / ORA-8103
3497949 9.2.0.6, 10.1.0.4, 10.2.0.1 Wrong results or ORA-1410 using stored outlines for CONNECT BY query
3729078 Errors binding to LONG datatype with a multibyte database V09020008
3083560 9.2.0.5, 10.1.0.2 ORA-1410 / ORA-8103 from direct path export if concurrent DML occurs
2619867 9.2.0.3, 10.1.0.2 OERI:[KCBGTCR_12] / ORA-8103 / ORA-1410 SELECTing from bitmap managed segment
2598043 9.2.0.3, 10.1.0.2 False ORA-1410 accessing migrated Oracle7 table with ROWID= predicate
2551000 10.1.0.2, 9.2.0.4 False ORA-1410 / ORA-8103 possible from ANALYZE COMPUTE/ESTIMATE STATISTICS
3489963 9.2.0.6 ORA-1410 from select via synonym when re-created on other node
1508914 9.2.0.1 Invalid ROWID from Scrollable ResultSet.getString() in JDBC
1698789 9.2.0.1 Wrong results, ORA-1410, ORA-8103, OERI:25012 on SELECT of UNSCOPED REF with ROWID
1668041 9.2.0.1 Incorrect LOB block data may be read when using CACHE READS – many possible errors (eg: ORA-1555)
1888129 8.1.7.4, 9.0.1.0 ORA-1410 possible from SELECT .. FOR UPDATE from 8i client to 8.0 server
1322919 8.1.7.2, 9.0.1.0 ORA-1410/ORA-3116 using “WHERE CURRENT OF cursor” over DBLINK from 8i to 8.0/7
589855 7.3.3.6, 7.3.4.1 ORA:1578 or ORA:8103 selecting invalid ROWID
685702 8.0.5.2, 8.0.6.0 ORA-1410 possible in block cleanout under VERY HEAVY load
395797 7.3.3.2, 7.3.4.0 PLSQL: ORA-1410 when using SUBQUERY within PLSQL block
1133853 8.0.3.0 ORA-1410 can occur after TRUNCATE / ALTER INDEX REBUILD

关注刘相兵的新浪微博

扫码加入微信Oracle小密圈,了解Oracle最新技术下载分享资源

Speak Your Mind

沪ICP备14014813号

沪公网安备 31010802001379号

TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569