Invaild Objects nach einem Oracle Upgrade

Während eines Oracle Upgrades kann es vorkommen, dass nach dem Upgrade Objekete ungültig sind. Das ist normal und das kennt man (eigentlich) auch.

Während der PRE Upgrade Phase wird quasi einen Bestandsaufnahme der (ungültigen) Objekte vorgenommen, die nach dem Upgrade mit dem dann vorherrschenden Objektzustand verglichen wird (Post Upgrade Phase). Sollte es hier zu einer Differenz kommen so muss diese bearbeitet werden.

Dies wird normaler weise über das Script $ORACLE_HOME/rdbms/admin/utlrp.sql erledigt. Wenn die entsprechenden Objekte hier jedoch nicht berücksichtigt werden und man trotzdem Meldungen wie unten gezeigte bekommt muss eine andere Lösung her. Mit den Standardscripten kommt man hier leider nicht weiter.

Der View ist nicht mehr gültig, damit ist dann auch das Synonym, das auf den View zeigt, defekt. Das Einfachste ist jetzt auf den View zuzugreifen. In der Regel wird er dann – wenn noch nicht geschehen – kompiliert. Funktionier dies nicht wird der View eben neu kompiliert.

SQL> spool invalid_objects_after_utlrp.txt
set cmdsep on
set lines 150 pages 40
col compiled_at for a30; col compiled_by for a10; col owner for a10; col object_name for a35;
col object_type for a12; col object_id for 999999 head obj_id
select do.owner,do.object_name,do.object_type,urc.*
from utl_recomp_compiled urc, dba_objects do where urc.obj# = do.object_id order by compiled_at;
select owner,object_name,object_id,object_type,created,last_ddl_time,timestamp,status
from dba_objects where status = 'INVALID' order by object_name;
spool off
OWNER OBJECT_NAME OBJECT_TYPE OBJ# BATCH# COMPILED_AT COMPILED_B
---------- ----------------------------------- ------------ ---------- ---------- ------------------------------ ----------
SYS S$LOGMNR_REGION VIEW 485367 0 08-DEC-15 03.38.20.816707 PM 0
PUBLIC X$LOGMNR_REGION SYNONYM 485368 1 08-DEC-15 03.38.20.827709 PM 0
PUBLIC X$LOGMNR_REGION SYNONYM 485368 -1 08-DEC-15 03.38.21.476370 PM 0

OWNER OBJECT_NAME obj_id OBJECT_TYPE CREATED LAST_DDL_TIME TIMESTAMP STATUS
---------- ----------------------------------- ------- ------------ --------------- --------------- ------------------- -------
SYS S$LOGMNR_REGION 485367 VIEW 06-JUN-14 08-DEC-15 2015-12-08:15:38:21 INVALID
PUBLIC X$LOGMNR_REGION 485368 SYNONYM 06-JUN-14 08-DEC-15 2015-12-08:15:38:22 INVALID

Oder die Kurzform:

SQL> SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE STATUS = 'INVALID'; 

OBJECT_NAME
--------------------------------------------------------------------------------
S$LOGMNR_REGION
X$LOGMNR_REGION

SQL>

Das manuelle Kompilieren kann man zum Beispiel so anstoßen:

SQL> alter view "SYS"."S$LOGMNR_REGION" compile;

Warning: View altered with compilation errors.

SQL>

Leider bringt dies hier keinen Erfolg.

Als nächstes kann man dann mit „show errors view“ die Fehlermeldungen sehen.

SQL> show errors view "SYS"."S$LOGMNR_REGION";
Errors for VIEW "SYS"."S$LOGMNR_REGION":

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      ORA-00904: "MEMSTATE": invalid identifier
SQL>

Manchmal sind die Views ungültig, weil sich die genutzten Tabellen in ihrer Struktur geändert haben. Es fallen zum Beispiel Felder weg oder werden umbenannt. Wenn der View nicht upgedated wird enthält dieser ein falsches Statement. Das Statement des Views kann man sich wie folgt ansehen:

SQL> select text FROM all_views WHERE view_name like '%S$LOGMNR_REGION%';

TEXT
--------------------------------------------------------------------------------
select "ADDR","INDX","INST_ID","MEMSTATE","STATE","OWNING_PROCESS" from X$LOGMNR

SQL>

Wenn man weiß wo der Fehler liegt muss man nur den View anpassen. In diesem Fall existiert die Quelltabelle nicht mehr und in der neuen Tabelle fehlt das Feld „MEMSTATE“. Somit muss der VIEW angepasst werden. Das geht jedoch nicht über „alter view“, sondern per „create or replace“:

SQL> create or replace view S$LOGMNR_REGION as select "ADDR","INDX","INST_ID","STATE","OWNING_PROCESS" from X$LOGMNR_REGION;

View created.

SQL>

Ein select * auf den VIEW sollte ihn kompilieren. Wenn nicht den manuellen Kompiliervorgang wie oben beschrieben ausführen. Dieser muss ebenfalls für das Synonym erfolgen.

VIEW kompilieren:

SQL> alter view "SYS"."S$LOGMNR_REGION" compile;

View altered.

SQL>show errors view "SYS"."S$LOGMNR_REGION"
No errors.
SQL>

Die Syntax für das Synonym ist ähnlich:

SQL> alter PUBLIC SYNONYM "X$LOGMNR_REGION" compile;

Synonym altered.

SQL>

Noch kurz in der Tabelle überprüft:

SQL> select OWNER,SUBSTR(OBJECT_NAME,1,18) as SUBSTR, OBJECT_TYPE,CREATED,STATUS from dba_objects where OBJECT_NAME like '%$LOGMNR_REGION%';

OWNER                          SUBSTR                                                 OBJECT_TYPE         CREATED         STATUS
------------------------------ ------------------------------------------------------ ------------------- --------------- -------
SYS                            V_$LOGMNR_REGION                                       VIEW                05-FEB-10       VALID
PUBLIC                         V$LOGMNR_REGION                                        SYNONYM             05-FEB-10       VALID
SYS                            GV_$LOGMNR_REGION                                      VIEW                05-FEB-10       VALID
PUBLIC                         GV$LOGMNR_REGION                                       SYNONYM             05-FEB-10       VALID
SYS                            S$LOGMNR_REGION                                        VIEW                09-DEC-15       VALID
PUBLIC                         X$LOGMNR_REGION                                        SYNONYM             06-JUN-14       VALID

6 rows selected.

SQL>

Die Objekte sind wieder Valide.

About the author