Wednesday, April 11, 2012

How to Recompile Invalid Objects

You often need to recompile invalid objects in a database e.g. if you have just updated some application software which is about to be tested. In the past, I have used my own script to do this or found some suitable SQL on the Internet. I recently discovered that Oracle supply a file of their own, which works just as well. It is called utlrp.sql and you can find it in $ORACLE_HOME/rdbms/admin. In the example below, I have just done an import and my database has 3 invalid objects (although I often have many more). After running utlrp.sql, the invalid objects disappeared: 

ORACLE10 /oracle/app/oracle/product/10.2.0/rdbms/admin > sqlplus / as sysdba
 
SQL*Plus: Release 10.2.0.3.0 - Production on Mon Apr 2 16:16:49 2012
 
Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.
 
Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
 
SQL> select count(*) from dba_objects
  2  where status = 'INVALID'
  3  /
 
  COUNT(*)
----------
         3
 
SQL> @utlrp
 
TIMESTAMP
--------------------------------------------------------------------------------
COMP_TIMESTAMP UTLRP_BGN  2012-04-02 16:17:21
 
DOC>   The following PL/SQL block invokes UTL_RECOMP to recompile invalid
DOC>   objects in the database. Recompilation time is proportional to the
DOC>   number of invalid objects in the database, so this command may take
DOC>   a long time to execute on a database with a large number of invalid
DOC>   objects.
DOC>
DOC>   Use the following queries to track recompilation progress:
DOC>
DOC>   1. Query returning the number of invalid objects remaining. This
DOC>      number should decrease with time.
DOC>         SELECT COUNT(*) FROM obj$ WHERE status IN (4, 5, 6);
DOC>
DOC>   2. Query returning the number of objects compiled so far. This number
DOC>      should increase with time.
DOC>         SELECT COUNT(*) FROM UTL_RECOMP_COMPILED;
DOC>
DOC>   This script automatically chooses serial or parallel recompilation
DOC>   based on the number of CPUs available (parameter cpu_count) multiplied
DOC>   by the number of threads per CPU (parameter parallel_threads_per_cpu).
DOC>   On RAC, this number is added across all RAC nodes.
DOC>
DOC>   UTL_RECOMP uses DBMS_SCHEDULER to create jobs for parallel
DOC>   recompilation. Jobs are created without instance affinity so that they
DOC>   can migrate across RAC nodes. Use the following queries to verify
DOC>   whether UTL_RECOMP jobs are being created and run correctly:
DOC>
DOC>   1. Query showing jobs created by UTL_RECOMP
DOC>         SELECT job_name FROM dba_scheduler_jobs
DOC>            WHERE job_name like 'UTL_RECOMP_SLAVE_%';
DOC>
DOC>   2. Query showing UTL_RECOMP jobs that are running
DOC>         SELECT job_name FROM dba_scheduler_running_jobs
DOC>            WHERE job_name like 'UTL_RECOMP_SLAVE_%';
DOC>#
 
PL/SQL procedure successfully completed.
 
TIMESTAMP
--------------------------------------------------------------------------------
COMP_TIMESTAMP UTLRP_END  2012-04-02 16:17:29
 
PL/SQL procedure successfully completed.
 
DOC> The following query reports the number of objects that have compiled
DOC> with errors (objects that compile with errors have status set to 3 in
DOC> obj$). If the number is higher than expected, please examine the error
DOC> messages reported with each object (using SHOW ERRORS) to see if they
DOC> point to system misconfiguration or resource constraints that must be
DOC> fixed before attempting to recompile these objects.
DOC>#
 
OBJECTS WITH ERRORS
-------------------
                  0
 
DOC> The following query reports the number of errors caught during
DOC> recompilation. If this number is non-zero, please query the error
DOC> messages in the table UTL_RECOMP_ERRORS to see if any of these errors
DOC> are due to misconfiguration or resource constraints that must be
DOC> fixed before objects can compile successfully.
DOC>#
 
ERRORS DURING RECOMPILATION
---------------------------
                          0
 
PL/SQL procedure successfully completed.
 
SQL> select count(*) from dba_objects
  2  where status = 'INVALID'
  3  /
 
  COUNT(*)
----------
         0
 
SQL> 

1 comment:

chandu reddy said...

Really very useful blog, the same post with different approach here:

http://www.chandu208.blogspot.com/