Ошибка index key not found

Found some ORA-08102 errors during executions of SQL statements like this:

ERROR at line 1:
ORA-08102: index key not found, obj# 98830, file 69, block 120164 (2)

ERROR at line 1:
ORA-08102: index key not found, obj# 98832, file 69, block 120172 (2)

ERROR at line 1:
ORA-08102: index key not found, obj# 98831, file 69, block 120140 (2)

Solutions

index key not found? I suspected that the above indexes has been corrupted logically.

1. Rebuild Indexes

The first solution to ORA-08102 is to rebuild those indexes. First of all, we use those object id to compose rebuild statements like this:

SQL> column stmts format a50;
SQL> select 'ALTER ' || object_type || ' ' || owner || '.' || object_name || ' REBUILD;' stmt from dba_objects where object_id in (98829, 98830, 98831) and object_type = 'INDEX';

STMT
--------------------------------------------------
ALTER INDEX ERPAPP.FINNS5S1 REBUILD;
ALTER INDEX ERPAPP.FINNS6S1 REBUILD;
ALTER INDEX ERPAPP.FINNS7S1 REBUILD;

Then we use these statements to rebuild the indexes.

SQL> ALTER INDEX ERPAPP.FINNS5S1 REBUILD;

Index altered.

SQL> ALTER INDEX ERPAPP.FINNS6S1 REBUILD;

Index altered.

SQL> ALTER INDEX ERPAPP.FINNS7S1 REBUILD;

Index altered.

Some indexes may not be fixed by rebuilding it. You need a stronger treatment.

2. Recreate Indexes

Rebuilding problematic indexes should have solved ORA-08102, but in some cases, you have to use DROP then CREATE INDEX instead.

SQL> select 'DROP INDEX ' || b.owner || '.' || b.index_name || ';' || chr(10) || 'CREATE INDEX ' || b.owner || '.' || b.index_name || ' ON ' || c.table_owner || '.' || c.table_name || ' (' || c.column_name || ') TABLESPACE ' || b.tablespace_name || ';' stmt from dba_objects a inner join dba_indexes b on a.object_type = 'INDEX' and a.owner = b.owner and a.object_name = b.index_name inner join dba_ind_columns c on b.owner = c.index_owner and b.index_name = c.index_name where a.object_id in (98829, 98830, 98831);

STMT
--------------------------------------------------------------------------------
DROP INDEX ERPAPP.FINNS5S1;
CREATE INDEX ERPAPP.FINNS5S1 ON ERPAPP.FINLOC1S025 (SWITCH_SUM_PH) TABLESPACE FINCCORP;

DROP INDEX ERPAPP.FINNS6S1;
CREATE INDEX ERPAPP.FINN65S1 ON ERPAPP.FINLOEC1S026 (SWITCH_SUM_PH) TABLESPACE FINCCORP;

DROP INDEX ERPAPP.FINNS7S1;
CREATE INDEX ERPAPP.FINNS7S1 ON ERPAPP.FINLN1S027 (SWITCH_SUM_PH) TABLESPACE FINCCORP;

Then execute the above statements.

So i have a table with an index called IDX_ATS_CALC_END_TIME. The column is a timestamp value. This column also has a trigger that automatically populates the column when another column (Interval_duration) is populated or updated.

The trigger is below:

TRIGGER "DATAMART"."TRG_ATS_CALC_END_TIME" 
    BEFORE INSERT OR UPDATE OF INTERVAL_DURATION ON DATAMART.AGG_TIME_SUMMARY
    FOR EACH ROW
    DECLARE
BEGIN
IF :New.INTERVAL_DURATION > 0 THEN
   :New.calc_end_time := :New.start_date_time  + pb_util.secondtointerval(:New.INTERVAL_DURATION);
ELSE
:NEW.CALC_END_TIME := :New.start_date_time;
END IF;

    EXCEPTION
    WHEN OTHERS THEN
      pb_util.logdata(1, 'TRG_ATS_CALC_END_TIME', 'Exception Thrown in interval:  ' || :New.Interval_DURATION, SQLERRM  || ' stack: ' || dbms_utility.format_error_backtrace);

END TRG_ATS_CALC_END_TIME;

When my table is initially populated there are no problems. My problem is that when i go to perform an insert/update on the table and try to modify this column by either directly changing the column or just updating the interval_duration column i have this error thrown:

ORA-08102: index key not found, obj# 97523, file 4, block 244 (2)

The index mentioned is a functioned based index. The function being used on the index is a sys_extract_utc on the calc_end_time column.

I’ve spent several days trying to solve this issue. I’ve rebuilt the index, i have tried deleting and recreating the index. These two seem to be the common answer for this problem, but they did not work for me.
I’ve analyzed the index using the following:

ANALYZE INDEX IDX_ATS_CALC_END_TIME VALIDATE STRUCTURE;

and it came back with no problems.

The only time i have been able to successfully update this column without getting this error was by disabling the trigger, performing the update, and then enabling the trigger once again. This is not a viable solution for me.

So i would like to know if anyone has ever encountered this type of problem and what other steps i can try to fix this error.

UPDATE:
below you will find the function pb_util.secondtointerval() code:

FUNCTION SecondToInterval
  (Seconds_IN NUMBER
  )
RETURN CONST.PBInterval
IS
  sec            NUMBER(20, 9);
  days           NUMBER;
  hours          NUMBER;
  minutes        NUMBER;
  seconds        NUMBER(20, 9);
  IntervalAsText NVARCHAR2(32);
  ReturnInterval INTERVAL DAY(9) TO SECOND(9);
begin
  sec     := NVL(Seconds_IN, 0);

  days    := trunc(sec/(24*60*60));
  sec     := sec - days*24*60*60;

  hours   := trunc(sec/(60*60));
  sec     := sec - hours*60*60;

  minutes := trunc(sec/60);
  sec     := sec - minutes*60;

  seconds := trunc(sec);

  sec     := sec - seconds;
  sec     := trunc(1000000000*sec);

  IntervalAsText := cast(days as nvarchar2)
    || ' ' || cast(hours as nvarchar2)
    || ':' || substr('00' || cast(minutes as nvarchar2), -2, 2)
    || ':' || substr('00' || cast(seconds as nvarchar2), -2, 2)
    || '.' || substr('000000000' || cast(sec as nvarchar2), -9, 9);

  --dbms_output.put_line(intervalastext);

  ReturnInterval := TO_DSInterval(IntervalAsText);
  --ReturnInterval := TO_DSInterval('999999999 23:59:59.999999999');
  --dbms_output.put_line(ReturnInterval);

  RETURN ReturnInterval;
EXCEPTION
    WHEN OTHERS THEN
   pb_util.logdata(1, 'PB_UTIL.SecondToInterval', 'ERROR(99A): ', intervalastext);
                dbms_output.put_line(intervalastext);
                RAISE;

end SecondToInterval;

this was written by my predecessor but basically all it does is turn the given numeric value and converts it into an interval value.

Any help or suggestions are greatly appreciated.

Thank you.

In one of our test databases we encountered the following error during an overnight PL/SQL purge job:

ORA-08102: index key not found, obj# 124885, file 48, block 55492 (2) 01-FEB-12

The purpose of the job is to delete data introduced since more than 6 days respecting for that several hierarchical parent-child relationships.  It has been working without any relatives problems since more than 2 years until it started crashing out with the above ORA-08102 error. I aim via this blog article to show how I have resolved this problem.

The first thing I did is of course to identify the corrupted object via the following select:

mhouri.world> ed
    Wrote file afiedt.buf
  1  select substr(object_name,1,30), object_type
  2  from user_objects
  3* where object_id = 154711
;

 SUBSTR(OBJECT_NAME,1,30)       OBJECT_TYPE
------------------------------ ----------------
XXX_ZZZ_UK                        INDEX

The naming standard (_UK) is as such that I immediately identified this index as an automatic index created to enforce a unique constraint. I thought first that I need to rebuild this unique index:

mhouri.world> alter index XXX_ZZZ_UK rebuild;

Index altered.

Unfortunately, when I launched again the purge batch the same error has been raised again. So my second tentative was to drop and recreate the unique constraint and implicitly the unique index.

mhouri.world> alter table t1 drop constraint XXX_ZZZ_UK;

Table altered.

mhouri.world > alter table t1 add constraint XXX_ZZZ_UK unique (id1, id2, dat1);

Table altered.

Of course that you have first to get the DDL definition of the constraint before dropping it so that you will be able to re-created it again.

When the purge process has been re-started following this last intervention, it, unfortunately, raised again the same ORA-08102 on the same object. Finally I have decided to work on the underneath table instead of its unique constraint and unique index.

mhouri.world>> alter table t1 move;

 Command that has invalidated all attached indexes and which obliged me to re-build them:

mhouri.world > select 'alter index ' || index_name || ' rebuild;'
from user_indexes
where status != 'VALID';

Once all indexes rebuilt, I launched again the purge job which surprisingly completed successfully.

Frankly speaking I don’t know if I would have been able to work around this error if I have tried instead of the move command a rebuild or shrink command. But what I have learnt from this experience is that when an index is corrupted it could be repaired by moving table data instead of dropping and recreating the corrupted index as initially indicated by the ORA-08102 error. I have also to admit that I don’t know yet the side effect of the move command and will certainly write something about that if eventually I will come to learn something about that.
.

December 25, 2019
ORACLE

During the index rebuild process, if some of the blocks belonging to the index are on a corrupted datafile, you receive the error “ORA-08102: index key not found, obj # XXXXX, file X, block XXXX (2)”. To resolve the error, the relevant index must be moved to a different tablespace, or dropped and recreated.

The error is as follows.

SQL> ALTER INDEX ADURUOZ.IDX_TESTR REBUILD PARALLEL 16 ONLINE;

ALTER INDEX ADURUOZ.IDX_TESTR REBUILD PARALLEL 16 ONLINE

*

ERROR at line 1:

ORA08102: index key not found, obj# 84300, file 9, block 90039831 (2)

Loading

ORA-08102 means there is a mismatch between keys (values) stored in an index and values of indexed column in the table.

[oracle@joedb~]$ oerr ora 08102
08102, 00000, "index key not found, obj# %s, file %s, block %s (%s)"
// *Cause:  Internal error: possible inconsistency in index
// *Action:  Send trace file to your customer support representative, along
//           with information on reproducing the error

After an index has been created for a while, some kind of corruption happens which causes either the data in table or index changed — mismatching.

When this happens, the application will get the ORA-08102 errors during accessing the corresponding table(index). You won’t see the error explicitly in the alert.log, but something like:

*****************************************************************
2021-03-18T02:06:22.424310-05:00
Errors in file /opt/oracle/diag/rdbms/prod/PROD/trace/PROD_ora_4611.trc:
2021-03-18T02:06:27.408745-05:00
*****************************************************************

The trace file actually has the information about it like:

oer 8102.2 - obj# <object id>, rdba: <rdba value>(afn <file#>, blk# <block#>)

So searching trace file with the pattern “oer 8102” will tell how many trace files generated during a period for this error. With the information of object#, file#, block# we can easily identify which file and which index has this mismtach:

SQL> select file#, TS#, name, STATUS, enabled from v$datafile where file#=34;

SQL> select owner, object_name, object_type from dba_objects where object_id = 35775;

SQL> select tablespace_name, segment_type, owner, segment_name from dba_extents where file_id = 34 and 5830 between block_id AND block_id + blocks-1;

DBV might not find anything if you run it against the data file affected unless there is a real block corruption.It is the same for RMAN validate.

[oracle@joedb ]$ dbv file=/dbase/data/PROD/data_ind_115.dbf BLOCKSIZE=8192

DBVERIFY: Release 19.0.0.0.0 - Production on Thu Mar 18 17:04:58 2021

Copyright (c) 1982, 2019, Oracle and/or its affiliates.  All rights reserved.

DBVERIFY - Verification starting : FILE = /dbase/data/PROD/data_ind_115.dbf


DBVERIFY - Verification complete

Total Pages Examined         : 2097152
Total Pages Processed (Data) : 0
Total Pages Failing   (Data) : 0
Total Pages Processed (Index): 1365090
Total Pages Failing   (Index): 0
Total Pages Processed (Other): 732061
Total Pages Processed (Seg)  : 0
Total Pages Failing   (Seg)  : 0
Total Pages Empty            : 1
Total Pages Marked Corrupt   : 0
Total Pages Influx           : 0
Total Pages Encrypted        : 0
Highest block SCN            : 347811302333 (80.4213918653)

Additionally we can run “analyze index/table <index/table name> validate structure” to detect the corruption. Nevertheless, rebuild the index is sufficient if the table is good.

When considering rebuild an index, there are two options,

  1. use rebuild clause with alter index. It’s faster and when using with online clause, the application can still access the index. However, it uses the existing index as the data source. In this case, it might not solve the mismatch.
  2. drop the index, then create. It needs to re-scan the table, slower, but will solve the mismatch issue if the underlying table is good.

An important thing here is when the index is a function-based index, double check the index defintion and make sure the function is deterministic, especially for a user defined function which must be declared as DETERMINISTIC and the plsql exception handler should not ignore error ORA-4091. That’s because index keys is based on the returned values of the fucntion used in the index definition.

A deterministic function must return the same value on two distinct invocations if the arguments provided to the two invocations are the same.

Oracle doesn’t verify if a function is DETERMINISTIC when it is declared so. That means whoever writes the function has to make sure the function is actually deterministic, not just declare it is.

Non-deterministic Functional indexes like the ones depending on NLS settings are exposed to ORA-8102.

References:

  1. Master Note for Handling Oracle Database Corruption Issues (Doc ID 1088018.1)
  2. OERR: ORA-8102 “index key not found, obj# %s, file %s, block %s (%s)” (Doc ID 8102.1)
  3. ORA-8102 On Select / Update with Function Based Index using Timestamp Column (Doc ID 568005.1)
  4. ORA-8102 at update when having a FunctionBasedIndex(FBI) index present based on incorrect function (Doc ID 1067112.1)

Понравилась статья? Поделить с друзьями:
  • Ошибка increased emissions на бмв
  • Ошибка incorrect syntax near the keyword with
  • Ошибка incorrect rage multiplayer installation
  • Ошибка incorrect key file for table
  • Ошибка incorrect id 154 easy anti cheat