上篇文章主要介绍了如何从分析表得到的报错,以及trace中的信息,判断表返回的记录与索引返回记录不一致时的处理方式。下面这篇文章则介绍了针对ORA-1499进行问题排查的一些基本方法。
OERR: ORA-1499 table/Index Cross Reference Failure - see trace file (文档 ID 1499.1)
Error: ORA 1499
Text: table/Index Cross Reference Failure - see trace file
-------------------------------------------------------------------------------
Cause: An error occurred when validating an index or a table using the
ANALYZE command.
One or more entries does not point to the appropriate cross-reference.
Action: Check the trace file for more descriptive messages about the problem.
Correct these errors.
ORA-1499的错误是通过“"ANALIZE TABLE|CLUSTER <name> VALIDATE STRUCTURE CASCADE”分析得出的,它的含义是表或聚类和索引之间存在不一致性,具体来讲是索引键值未出现在索引中,或者相反。
trace文件中包含:
<description>: tsn: <tablespace number> rdba: <relative dba>
description有以下值:
"row not found in index"
"Table/Index row count mismatch"
"row mismatch in index dba"
"Table row count/Bitmap index bit count mismatch"
"kdavls: kdcchk returns %d when checking cluster dba 0x%08lx objn %d\n"
tsn: Tablespace Number表示的是索引存储的表空间编号。
rdba: 是索引段头相对于数据块的存储地址。
analyze table case7 validate structure cascade
*
ERROR at line 1:
ORA-01499: table/index cross reference failure - see trace file
trace文件的实例:
WHERE header_file = (SELECT file#
FROM v$datafile
WHERE rfile# = dbms_utility.data_block_address_file(to_number('&rdba','XXXXXXXX'))
AND ts#= &tsn)
AND header_block = dbms_utility.data_block_address_block(to_number('&rdba','XXXXXXXX'));
FROM DBA_SEGMENTS
WHERE header_file = (SELECT file#
FROM v$datafile
WHERE rfile# = dbms_utility.data_block_address_file(to_number('02c00061','XXXXXXXX'))
AND ts#= 5)
AND header_block = dbms_utility.data_block_address_block(to_number('02c00061','XXXXXXXX'));
FROM <Table name> t1
MINUS
SELECT /*+ index(t <Index name>) */ rowid, <indexed column list>
FROM <Table name> t;
MINUS
SELECT /*+ FULL(t1) */ rowid, <indexed column list>
FROM <Table name> t1;
SELECT /*+ FULL(t1) */ rowid, deptno, dname
FROM dept t1
MINUS
SELECT /*+ index(t I_DEPT1) */ rowid, deptno, dname
FROM dept t;
导致这种问题的根本原因就是表和索引之间的不一致,可能是由于Oracle的defect产生,或者Oracle外部问题,例如IO丢失。硬件或OS子系统问题可能导致IO丢失写入。如果出现IO丢失,包含表或索引的块修改操作就可能不会写入Oracle的数据文件中,引起键缺失。解决方法可以参考上一篇文章《表扫描与索引扫描返回的行数不一致》。当出现表和索引之间不一致的情况,即表中的行不在索引中,删除并重建索引是常用的一种合适方法。