WRH$_SYSMETRIC_HISTORY_INDEX UNUSABLE After 18c Upgrade

The index WRH$_SYSMETRIC_HISTORY_INDEX became UNUSABLE a couple of days after an Oracle 18c upgrade. Rebuilding the index helped only temporarily, because it became UNUSABLE again. Interestingly, while I’ve been observing this problem on every database upgraded from 12c, none of the databases created on 18c were affected.

The first clue came from the alert log:

2019-09-13T00:28:11.009410+02:00
Some indexes or index [sub]partitions of table SYS.WRH$_SYSMETRIC_HISTORY have been marked unusable

V$ACTIVE_SESSION_HISTORY showed only some MMAN_SLAVE activity around this time, but the captured statements weren’t really related to this problem. Therefore, I set up the SQL trace for MMAN_SLAVE:

begin 
  dbms_monitor.serv_mod_act_trace_enable( 
    service_name=>'SYS$BACKGROUND', module_name=>'MMON_SLAVE', binds=>TRUE
  ); 
end; 
/ 

begin 
  dbms_monitor.serv_mod_act_trace_disable(
    service_name=>'SYS$BACKGROUND', module_name=>'MMON_SLAVE'
  ); 
end; 
/

The trace containing the following statements, among others, indeed revealed the problem:

alter table WRH$_SYSMETRIC_HISTORY drop partition WRH$_SYSMETRIC_HISTORY_1896533961_17248
LOCK TABLE "WRH$_SYSMETRIC_HISTORY" PARTITION ("WRH$_SYSMETRIC_HISTORY_1896533961_17439")  IN EXCLUSIVE MODE  NOWAIT
alter table WRH$_SYSMETRIC_HISTORY split partition WRH$_SYSMETRIC_HISTORY_1896533961_17439 at (1896533961,17464) into (partition WRH$_SYSMETRIC_HISTORY_1896533961_17439, partition WRH$_SYSMETRIC_HISTORY_1896533961_17464 tablespace SYSAUX) update indexes

It was the first statement (that is, ALTER TABLE DROP PARTITION) that invalidated the index. That happened because the index WRH$_SYSMETRIC_HISTORY_INDEX is global:

select partitioned from dba_indexes 
  where index_name = 'WRH$_SYSMETRIC_HISTORY_INDEX' ;

PAR
---
NO

A global index will become UNUSABLE when DROP PARTITION is issued without UPDATE INDEXES (or at least UPDATE GLOBAL INDEXES) [McDonald].

In contrast, the same index is local in a newly created 18c database:

column owner format a3
column name format a30
column column_name format a7

select owner,name,column_name from dba_part_key_columns 
  where name in ('WRH$_SYSMETRIC_HISTORY', 'WRH$_SYSMETRIC_HISTORY_INDEX')
  order by 1,2,3;

OWN NAME                           COLUMN_
--- ------------------------------ -------
SYS WRH$_SYSMETRIC_HISTORY         DBID
SYS WRH$_SYSMETRIC_HISTORY         SNAP_ID
SYS WRH$_SYSMETRIC_HISTORY_INDEX   DBID
SYS WRH$_SYSMETRIC_HISTORY_INDEX   SNAP_ID

For local indexes, DROP PARTITION doesn’t require UPDATE INDEXES, because ALTER TABLE DROP PARTITION drops the related index partition as well. It is precisely the reason why this problem doesn’t occur on a new 18c database.

In my opinion, it’s a bug in the upgrade script, which doesn’t replace the global index with the local one. Until there’s an official procedure to fix this problem you can safely ignore it, unless your queries on WRH$_SYSMETRIC_HISTORY get slow. In this case, you can rebuild the index, which usually remains VALID for a couple of days:

alter index SYS.WRH$_SYSMETRIC_HISTORY_INDEX rebuild online ;

Since the problem recurs, I automatically rebuild this index whenever it becomes UNUSABLE.

Lastly, I dropped the global and created the local index on a test database:

drop index sys.wrh$_sysmetric_history_index ;

create index sys.wrh$_sysmetric_history_index on sys.wrh$_sysmetric_history (
  dbid, snap_id, instance_number, group_id, metric_id, begin_time, con_dbid
) local tablespace sysaux ;

The index haven’t become UNUSABLE any more and I haven’t observed any side-effects. Mind, however, that this is unsupported and, therefore, should be only done after getting clearance from the Oracle support.

References:

[McDonald] Conor McDonald. (September 20, 2017). Updating indexes with partition maintenance

Thanks for sharing

Nenad Noveljic

7 Comments

  1. Hi Nenad
    Did you create a SR?

    I couldn’t reproduce

    SQL> select * from v$version where banner like ‘%Database%’;

    BANNER
    ——————————————————————————–
    Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 – 64bit Production

    SQL> ho cat /etc/redhat-release
    Red Hat Enterprise Linux Server release 7.7 (Maipo)

    SQL> select count(*) from cdb_indexes where status=’UNUSABLE’;

    COUNT(*)
    ———-
    0

    dbua

    SQL> select BANNER_FULL from v$version where banner like ‘%Database%’;

    BANNER_FULL
    ———————————————————————-
    Oracle Database 18c Enterprise Edition Release 18.0.0.0.0 – Production

    Version 18.5.0.0.0

    SQL> select count(*) from cdb_indexes where status=’INVALID’;

    COUNT(*)
    ———-
    0

    SQL> select status from cdb_indexes where index_name = ‘WRH$_SYSMETRIC_HISTORY_INDEX’;

    STATUS
    —————
    VALID

    Cheers
    Laurent

    • Hi Laurent,

      The index becomes UNUSABLE during the night maintenance, when MMON_SLAVE executes drop partition on the table. However, it doesn’t happen every night. You can check for LAST_DDL_TIME to see if the partition was dropped.

      I haven’t opened an SR so far.

      Best regards,

      Nenad

  2. Hi Nenad

    select status from cdb_indexes where index_name = ‘WRH$_SYSMETRIC_HISTORY_INDEX’;
    STATUS
    ——–
    UNUSABLE

    I confirm the behavior, the index is now unusable.

    Best regards
    Laurent

  3. This solution is cleared : Index WRH$_SYSMETRIC_HISTORY_INDEX Status Unusable (Doc ID 2426391.1)

    Thank you

    • Does anyone know how to solve that problem on SE database ? There is no partition option so it is not possible to recreate index.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.