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.