首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >续《表扫描与索引扫描返回的行数不一致》

续《表扫描与索引扫描返回的行数不一致》

作者头像
bisal
发布2022-12-01 15:30:31
7480
发布2022-12-01 15:30:31
举报

续《表扫描与索引扫描返回的行数不一致

上篇文章主要介绍了如何从分析表得到的报错,以及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: 是索引段头相对于数据块的存储地址。

SQL> analyze table DEPT validate structure cascade; analyze table case7 validate structure cascade * ERROR at line 1: ORA-01499: table/index cross reference failure - see trace file

trace文件的实例:

row not found in index tsn: 5 rdba: 0x02c00061

哪些索引受影响?

包含ORA-1499的trace文件提供了与索引相关的段头rdba。查询dba_segments来明确索引:

SELECT owner, segment_name, segment_type, partition_name

FROM   DBA_SEGMENTS 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'));

&rdba值应该是删除’0x‘的十六进制的rdba,tsn是表空间编号。

例如:

SELECT owner, segment_name, segment_type, partition_name 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'));

明确受影响的键值

如果需要明确所有受影响的键,需要运行一次全表扫描和索引扫描:

在表中但未在索引的行:

SELECT /*+ FULL(t1) */ rowid, <indexed column list> FROM   <Table name> t1 MINUS SELECT /*+ index(t <Index name>) */ rowid, <indexed column list> FROM   <Table name> t;

在索引中但未在表中的行:

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;

实例:

表名 = DEPT,索引名 = I_DEPT1,在索引I_DEPT1中的索引列:DEPTNO,DNAME. SELECT /*+ FULL(t1) */ rowid, deptno, dname FROM   dept t1 MINUS SELECT /*+ index(t I_DEPT1) */ rowid, deptno, dname FROM   dept t;

确保查询语句的执行计划使用受影响的索引,例如I_DEPT1会展示在执行计划中。查询未使用索引的原因之一是因为索引列定义为允许NULL值。如果是这样,可以添加一个where子句,例如:where deptno is not null。 导致这种问题的根本原因就是表和索引之间的不一致,可能是由于Oracle的defect产生,或者Oracle外部问题,例如IO丢失。硬件或OS子系统问题可能导致IO丢失写入。如果出现IO丢失,包含表或索引的块修改操作就可能不会写入Oracle的数据文件中,引起键缺失。解决方法可以参考上一篇文章《表扫描与索引扫描返回的行数不一致》。当出现表和索引之间不一致的情况,即表中的行不在索引中,删除并重建索引是常用的一种合适方法。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2013-10-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档