Identify and Fix Invalid Objects in Oracle Database
How to Identify and Fix Invalid Objects in an Oracle Database
Purpose
A list of invalid objects tells you more than it first seems to. Ten invalid objects in one application schema right after a release can point to one changed table. Hundreds of invalid objects across many schemas more often follow a patch or an upgrade. The size and the shape of the list is the first clue to the cause.
This check reads DBA_OBJECTS and keeps only the rows where STATUS is INVALID. It shows the owner, the name and the type of each object. A second query counts the invalid objects by owner and type, so you see the pattern before you read the detail. Two more queries trace one object back to the objects it depends on and to the compile errors it holds.
Finding the objects and deciding what to do with them is the subject here. The commands that recompile objects are in Recompile Invalid Objects in Oracle Database. How to read a compile error is in SHOW ERRORS and dba_errors Explained.
Code
1-- 1. List every invalid object
2set lines 200 pages 999
3col "obj" format a40
4select owner || '.' || object_name "obj",
5object_type
6from dba_objects
7where status = 'INVALID'
8/
9
10-- 2. Count invalid objects by owner and type
11select owner, object_type, count(*) invalid_count
12from dba_objects
13where status = 'INVALID'
14group by owner, object_type
15order by owner, object_type
16/
17
18-- 3. See when each invalid object was last changed by DDL
19select owner || '.' || object_name "obj", object_type, last_ddl_time
20from dba_objects
21where status = 'INVALID'
22order by last_ddl_time desc
23/
24
25-- 4. For one invalid object, list what it depends on
26select referenced_owner, referenced_name, referenced_type
27from dba_dependencies
28where owner = 'WEBUSER'
29and name = 'MAILER'
30and type = 'PACKAGE'
31/
32
33-- 5. For one invalid object, read the stored compile errors
34select text
35from dba_errors
36where owner = 'WEBUSER'
37and name = 'MAILER'
38and type = 'PACKAGE'
39/
Sample Oracle Output
1OBJ OBJECT_TYPE
2---------------------------------------- --------------------
3WEBUSER.CHECK PACKAGE BODY
4WEBUSER.MAILER PACKAGE
5WEBUSER.APP_FUNCS PACKAGE BODY
6PUBLIC.DBA_HIST_FILESTATXS SYNONYM
7PUBLIC.DBA_HIST_SQLSTAT SYNONYM
8PUBLIC.DBA_HIST_SQLBIND SYNONYM
9PUBLIC.DBA_HIST_TABLESPACE_STAT SYNONYM
10PUBLIC.DBA_HIST_SERVICE_STAT SYNONYM
11PUBLIC.DBA_HIST_SERVICE_WAIT_CLASS SYNONYM
The names WEBUSER, MAILER and PACKAGE in queries 4 and 5 are examples. Replace them with a row from your own query 1 output.
Code Breakdown
Query 1: the full list
set lines 200 pages 999sets two SQL*Plus display options.SET LINESIZEsets the total number of characters SQL*Plus displays on one line before it begins a new line.SET PAGESIZEsets the number of lines on each page of output. A page size of 999 means the column headings repeat less often on a long result.col "obj" format a40gives the combined name a width of 40 characters.owner || '.' || object_name "obj"joins the owner, a dot and the object name into one column. You readWEBUSER.MAILERat a glance.from dba_objectsis the right source for a database-wide check.DBA_OBJECTSdescribes all objects in the database.where status = 'INVALID'keeps the rows you care about. TheSTATUScolumn holds one of three values:VALID,INVALIDorN/A.
Query 2: the count by owner and type
Query 2 groups the same rows by owner and object_type. Read it before you read query 1. A count such as 3 package bodies in one schema is a small job. A count such as 400 views and 900 synonyms across many schemas is a different job, and you handle it in bulk.
Query 3: the timing clue
LAST_DDL_TIME is the timestamp for the last modification of the object and dependent objects resulting from a DDL statement. If many invalid objects share a recent time, one DDL change or one patch run probably caused them. Compare that time with your change log.
Queries 4 and 5: the cause
dba_dependenciesdescribes dependencies in the database between procedures, packages, functions, package bodies, and triggers, including dependencies on views created without any database links. Thereferenced_*columns name the objects that your invalid object points to. Check each one for a recent change, a drop, or an invalid status of its own.dba_errorsdescribes the current errors on all stored objects in the database. Thetextcolumn holds the text of the error. Read it for each invalid object that matters to you.
Key Points
- Invalid is not always a fault. An object becomes invalid when its compile-time references cannot be resolved, or when a referenced object changes in a way that might affect it. The database tracks these links on its own.
- Invalidation spreads. Dependent objects are cascade invalidated. If any object becomes invalid for any reason, all of that object's dependent objects are immediately invalidated. One bad table can produce a long list.
- Privilege changes count. If you revoke any object privileges on a schema object, dependent objects are cascade invalidated.
- The database fixes many of them for you. An invalid dependent object must be recompiled against the new definition of a referenced object before it can be used. Recompilation occurs automatically when the invalid dependent object is referenced.
- Automatic repair has a cost. An invalid object must be revalidated before an application can use it. Revalidation adds latency to application execution. If the number of invalid objects is large, the added latency on the first execution can be significant.
- Other sessions can fail. Invalidation of a procedure, function or package can cause exceptions in other sessions that run it at the same time. Those exceptions must be remedied by restarting application sessions following a patch.
Insights and Best Practices
Decide by count and by cause
Use the output of queries 2 to 5 to place the list in one of three groups.
- A few objects, a known recent change. Recompile them by hand with the
COMPILEclause of the matchingALTERstatement, then run query 1 again. - Many objects after a patch or upgrade. Use the bulk method. If you know that there are a large number of invalid objects, use the
UTL_RECOMPPL/SQL package to perform a mass recompilation. The steps are in the recompile post linked above. - Objects that return to invalid after a recompile. Do not recompile them again. Read their rows in
dba_errorsand fix the code or the missing referenced object first.
Know what a normal baseline looks like
In a typical running application, you would not expect to see views or stored procedures become invalid, because applications typically do not change table structures or change view or stored procedure definitions during normal execution. Changes to tables, views, or PL/SQL units typically occur when an application is patched or upgraded using a patch script or ad-hoc DDL statements. Dependent objects might be left invalid after a patch has been applied to change a set of referenced objects.
So a non-zero count on a quiet system with no change window is worth a closer look. A non-zero count right after a change window is expected, and you clear it as part of the change.
Save the count before and after each change
Run query 2 before a patch, and save the output. Run it again after the patch and after the repair. Compare the three results. Any object that was valid before and invalid after is a regression you can name. Any object that was already invalid before the patch is not yours to fix in this change.
Repair before users arrive
After an application upgrade or patch, revalidate invalid objects so that users do not pay the on-demand latency. Do this inside the change window. Run query 1 at the end and confirm it returns no rows, or only the rows you expected.
Add the check to routine monitoring
Oracle Enterprise Manager Cloud Control displays an alert on the Database Home page when schema objects become invalid. If you do not use it, schedule query 2 with your own job tool and send the result to the team when the count rises.
Be careful with the sample output
The sample output above lists some public synonyms. Do not assume that a synonym is safe to ignore. Run query 5 for it and read the result. Treat each type in the list on its own merits.
When to Run This
- Straight after a patch, an upgrade or a release script.
- After any change to a table, view or package that others depend on.
- After you revoke privileges from a schema or a role.
- When an application raises an error about a package or procedure that worked before.
- When a first call to an application feels slow after a change window.
- As part of a daily or weekly health check.
- Before you hand a database to another team or promote a copy to a new environment.
Troubleshooting Common Issues
The list is empty but the application still fails. Query 1 only shows objects that are marked invalid now. An object can be valid and still hold a logic fault. Read the application error first and use query 5 on the object it names.
The list is very long and keeps growing. Dependents are cascade invalidated, so one root object can invalidate many others. Use query 4 to walk from a dependent object back to what it references. Find the object at the end of the chain that has its own error. Fix that one first and the rest may clear when they are recompiled.
An object is invalid but dba_errors has no rows for it. Check its row in query 4 for a referenced object that changed. Recompile it by hand and then run query 5 again.
An object comes back invalid after each recompile. Read the text column from query 5, fix the cause, then recompile.
A referenced object does not exist. If a nonexistent object is created later, all dependent objects must be invalidated so that dependent objects can be recompiled and verified. Expect that kind of invalidation when you create an object whose name other code already uses.
Recompiling blocks or runs slowly. Do not start a mass recompile while other DDL runs. Pick a quiet period and run it once.
References
- Oracle Database Administrator's Guide 19c - Managing Schema Objects - The section on object dependencies and invalidation, the query for invalid objects, and UTL_RECOMP mass revalidation
- Oracle Database Reference 19c - DBA_OBJECTS - Column definitions for STATUS, OBJECT_TYPE, OWNER and LAST_DDL_TIME
- Oracle Database Reference 19c - DBA_DEPENDENCIES - Describes the dependency view used to trace what an invalid object points to
- Oracle Database Reference 19c - DBA_ERRORS - Describes the view that holds current errors on stored objects
- SQL*Plus User's Guide 19c - SET system variable summary - Defines the LINESIZE and PAGESIZE settings used in the query
- ORACLE-BASE - Recompiling Invalid Schema Objects - A community article that lists invalid objects in DBA_OBJECTS and compares the recompile methods
Posts in this series
- Oracle Recompile Invalid Objects with utlrp.sql
- Identify and Fix Invalid Objects in Oracle Database
- Search Objects in Oracle Database
- Query The Oracle Database Procedure Source Code
- Oracle DBA_OBJECTS: List All Objects Owned by a User
- Unveiling the Mystery Oracle for Object Size Analysis
- Find Tables Containing a Specific Column in Oracle Database
- Oracle DBMS_METADATA.GET_DDL: Extract Object DDL
- dba_segments: Find Oracle Table Storage Usage by User
- Oracle PL/SQL: SHOW ERRORS and dba_errors Explained
- Redefine a Table Online with DBMS_REDEFINITION, No DML Blocking