sábado, 9 de julio de 2011

ora-06508: PL/SQL: could not find program unit being called

Este error se presenta si se realizan cambios en los objetos de base de datos, procedimientos almacenados y sobre todo si estos procedimientos u objetos tiene relación de dependencia por otros objetos.


Cuando se realiza una modificación en cualquier objeto de base de datos, Oracle automáticamente invalida el objeto en la librería de objetos y si existen sesiones de usuarios trabajando con estos objetos, a estas sesiones se le presentara mensaje de error de objetos invalidos.


Aunque durante esta modificación de tabla, vista, sequencia, procedicmiento, etc no quede invalido podría aun persistir su invelidez en la librería de objetos de la sesion de los usuarios. Que podriamos hacer para que esta libreria se actualice?


1.- Lo que primero que debemos hacer es confirmar que no existan objetos invalidos.
--Revisión de objetos invalidos de un esquema en específico.
--Si deseamos de culquier esquema solo debemos quitar la condición OWNER
select object_type,count(*) from all_objects
where owner='SISOWN'
and status = 'INVALID'
group by object_type;



2.- Si existen objetos invalidos debemos de recompilarlos y luego realizar de nuevo el paso 1 para comprobar si no existen objetos discompilados. Si aun  siguen descompilados habra que revisar la lógica dentro del código o definición del objeto para ver el error.
--Utilidad del DBM_UTILITY para la recompilación de los objetos de un esquema.
call dbms_utility.compile_schema('SISOWN')


3.-Si ya no existen y siguen presentadose errores debemos de vaciar la SHARED_POOL de la SGA. Con esto logramos liberar la memoria de la librería de objetos y la libreria SQL
--Vaciado de la SHARED_POOL
alter system flush shared_pool;

Para entender mejor a continuación una gráfica de la arquitectura del Oracle Database Server donde revisaremos el componente SHARED_POOL de la SGA. No voy a explcar detenidamente cada uno de los componentes pero si el que se vió afectado.

Estructura del Oracle Server Database


Veamos los compnntes de la SHARED POOL que son los que mas tiene relación con los problemas de descompilación.



Me ha pasado que aun no existiendo objetos descompilados y no se han realizado alteraciones en la base de datos  se siguen presentando en ciertos momentos errores de ora-06508: PL/SQL: could not find program unit being called. Este error deja de aparecer realizado un vaciado de la SHARED_POOL(alter system flush shared_pool) pero es una solución momentanea.

Una solución momentanea fué programar un job para que realice un vaciado de la SHARED_POOL cada 10 minutos (Es como si tuvieramos una gotera y lo que hacemos es poner un recipiente para que no se riegue en el piso, pero lo que realmente tenemos que hacer es sellar los huecos por donde hay filtraciones). Esto no es era una solución coherente por lo que se investigó en el metalink de oracle en donde describian dos posibles causas:


CAUSA 1.
Shared pool se esta quedando corta en la SGA. Esto es por la administración automática de la SAGA no esta asignado valores correctos a los diferentes componentes de memoria po lo que hay que cambiar a gestión manual.

Recomendaciones:
Aumentara el tamaño de la shared pool y configurar el parametro de base de datos¨"shared pool reserved size" a un 10% al tamaño asignado a la shared pool.

Aciones:
Se aumento a 5gb el tamaño para la shared pool
alter system set shared_pool_size=5G  scope=BOTH;


Se deja el 10% de 5G es  decir 500Mb para reservar la shared pool.Con esto se logra que cuando el tamaño disponible de los 5G llegue a 500Mb la shared pool se autolibere y no realizar un flush a la shared pool.
alter system set shared_pool_reserved_size=500M scope=both;


CAUSA 2
Existen diferencias en la fecha de compilación en los objetos relacionados. Adjunto la consulta mágica que nos lo dirá.
select
 do.name dname,
 od.object_type dtipoob ,
 po.name pname,
 op.object_type ptipoob,
 p_timestamp,
 po.stime p_stime,
 do.owner# do_owner_id,
 po.owner# po_owner_id
from    sys.obj$ do,
  sys.dependency$ d,
  sys.obj$ po,
  all_objects od,
  all_objects op
where p_obj#=po.obj#(+)
and d_obj#=do.obj#
and do.status=1 /*dependent is valid*/
and po.status=1 /*parent is valid*/
and po.stime!=p_timestamp /*parent timestamp does not match*/
and do.type# not in (28,29,30) /*dependent type is not java*/
and po.type# not in (28,29,30) /*parent type is not java*/
and do.OBJ#=od.OBJECT_ID
and po.OBJ#=op.OBJECT_ID
  --and do.owner#=845
order by 2,1;


Recomendación:
Recompilar todos los objetos que estan en el lado DNAME y realizar la consulta. Repetir este proceso hasta que la consulta no de mas resultados.

Acciones:
Se realizó script para la recompilación de los objetos que aparecen en la subconsulta. Se filtran solo los objetos del esquema SISOWN.
begin
    for v in (
      select do.name dname, od.object_type dtipoob , po.name pname, op.object_type ptipoob, p_timestamp, po.stime p_stime
      from sys.obj$ do, sys.dependency$ d, sys.obj$ po,
      all_objects od, all_objects op
      where p_obj#=po.obj#(+)
      and d_obj#=do.obj#
      and do.status=1 /*dependent is valid*/
      and po.status=1 /*parent is valid*/
      and po.stime!=p_timestamp /*parent timestamp does not match*/
      and do.type# not in (28,29,30) /*dependent type is not java*/
      and po.type# not in (28,29,30) /*parent type is not java*/
      and do.owner# in (select USER_ID from dba_users where username in ('SISOWN'))
      and do.OBJ#=od.OBJECT_ID
      and po.OBJ#=op.OBJECT_ID
      order by 2,1
    )loop
        case
        when v.dtipoob like 'PACKAGE%' then
            execute immediate 'alter package '||v.dname||' compile';
        when v.dtipoob like 'PROCEDURE%' then
            execute immediate 'alter procedure '||v.dname||' compile';
        when v.dtipoob like 'FUNCTION%' then
            execute immediate 'alter function '||v.dname||' compile';
        when v.dtipoob like 'VIEW%' then
            execute immediate 'alter view '||v.dname||' compile';
        else
            dbms_output.put_line(v.dname);
        end case;
    end loop;
end;


De las dos causas expuesta aplicando la segunda fue la que funciono.

Ya con esto implementamos como política que todo pase a producción que intervenga alteraciones en la base debe de realizarse las revisiones de diferencias en fechas.

Espero que esto les sirva para solucionar los problemas que se me presentaron.

No hay comentarios:

Publicar un comentario