7 x 24 在线支持!
解决Oracle ORA-1410 "invalid ROWID"
如果自己搞不定可以找诗檀软件专业ORACLE数据库修复团队成员帮您恢复!
诗檀软件专业数据库修复团队
服务热线 : 13764045638 QQ号:47079569 邮箱: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)
解码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支持人员。
- 一个在内存中错误,当硬件故障,和一个内存地址是坏的。我们希望,有可能是在OS错误日志信息中来验证错误。
- 一个rowid生成不正确,不管是生成于Oracl代码或者定制的应用代码。
毁损出现不仅可能是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语句时避免截断表或改变表分区。
3. 错误会再发生
如果ORA-1410是可再次发生的,从失败的语句中找到被访问FROM子句中的表。如果发生故障的语句引用了一个视图,找到视图定义中的基表,并继续下面的第4步:
4、验证表和索引
在表和索引上执行online语句验证错误:
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错误仍然存在,这可能是由于一个OracleBUG。参考下面的已知bug列表或打开一个服务请求与Oracle支持进行更深入的调查。如果打开一个服务请求一定要包括下列文件中所要求的信息:
Note:1671526.1 - Required Diagnostic Data Collection for ORA-01410
您可以通过点击相关按钮限定下面的列表中有可能影响下列版本之一的问题:
NB |
Prob |
Bug |
Fixed |
Description |
|
II |
12.1.0.2, 12.2.0.0 |
ORA-600 [25026] when running query on table being dropped |
V11020001 V11020002 V11020003 V11020004 V12010001 |
||
I |
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 |
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 |
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 |
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 |
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 |
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 |
11.2.0.2, 12.1.0.1 |
Analyze Table Validate Structure fails on ADG standby with several errors |
V11010006 V11010007 V11020001 |
||
+ |
II |
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 |
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 |
||
- |
11.2.0.2 |
ORA-8103 instead of ORA-1410 |
V11020001 |
||
- |
10.2.0.5, 11.1.0.6 |
ORA-8176 or ORA-1410 from SELECT with concurrent Partition Exchange |
V10020002 V10020003 V10020004 |
||
I |
10.2.0.4, 11.1.0.6 |
ORA-8103/ORA-1410 from concurrent INSERT / export on ASSM tables |
V10020002 V10020003 |
||
I |
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 |
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 |
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 |
|||
- |
9.2.0.6, 10.1.0.4, 10.2.0.1 |
Wrong results or ORA-1410 using stored outlines for CONNECT BY query |
|||
- |
Errors binding to LONG datatype with a multibyte database |
V09020008 |
|||
- |
9.2.0.5, 10.1.0.2 |
ORA-1410 / ORA-8103 from direct path export if concurrent DML occurs |
|||
- |
9.2.0.3, 10.1.0.2 |
OERI:[KCBGTCR_12] / ORA-8103 / ORA-1410 SELECTing from bitmap managed segment |
|||
- |
9.2.0.3, 10.1.0.2 |
False ORA-1410 accessing migrated Oracle7 table with ROWID= predicate |
|||
- |
10.1.0.2, 9.2.0.4 |
False ORA-1410 / ORA-8103 possible from ANALYZE COMPUTE/ESTIMATE STATISTICS |
|||
- |
9.2.0.6 |
ORA-1410 from select via synonym when re-created on other node |
|||
- |
9.2.0.1 |
Invalid ROWID from Scrollable ResultSet.getString() in JDBC |
|||
- |
9.2.0.1 |
Wrong results, ORA-1410, ORA-8103, OERI:25012 on SELECT of UNSCOPED REF with ROWID |
|||
- |
9.2.0.1 |
Incorrect LOB block data may be read when using CACHE READS - many possible errors (eg: ORA-1555) |
|||
- |
8.1.7.4, 9.0.1.0 |
ORA-1410 possible from SELECT .. FOR UPDATE from 8i client to 8.0 server |
|||
- |
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 |
|||
- |
7.3.3.6, 7.3.4.1 |
ORA:1578 or ORA:8103 selecting invalid ROWID |
|||
- |
8.0.5.2, 8.0.6.0 |
ORA-1410 possible in block cleanout under VERY HEAVY load |
|||
- |
7.3.3.2, 7.3.4.0 |
PLSQL: ORA-1410 when using SUBQUERY within PLSQL block |
|||
- |
8.0.3.0 |
ORA-1410 can occur after TRUNCATE / ALTER INDEX REBUILD |
-
'*' indicates that an alert exists for that issue.
-
'+' indicates a particularly notable issue / bug.
-
See Note:1944526.1 for details of other symbols used