La invalidación de objetos de bases de datos pueden ser de dos tipos: 1) invalidaciones por error de sintaxis o de alcance, es decir por un error en la escritura de código sql o pl/sql o por falta de permisos sobre objetos referenciados en otros esquemas y 2) invalidaciones por dependencias. Esta nota se va a centrar principalmente en el segundo tipo ya que estas invalidaciones son mas complicadas de anticipar y suelen ocasionar cancelaciones de procesos batch o errores en aplicativos en forma imprevista.
El primer tipo de invalidación se da cuando, por ejemplo, un objeto de código pl/sql (function, procedure, package, type o trigger) compila con errores, ya sea porque hay errores de escritura o porque un objeto que se referencia no existe o no se tiene alcance al mismo, es decir faltan privilegios. Hay que recordar que los privilegios deben ser otorgados en forma directa, y no mediante roles, ya que por definición los roles se deshabilitan en tiempo de ejecución de las unidades de código. En el caso de las vistas, que se definen en base a una sentencia sql, los errores mas comunes son referencias a columnas que no existen, ya sea porque se escribieron mal cuando se armó la vista o por cambios de definición en la tablas subyacentes. Oracle 11g permite tener una dependencia de granularidad mas fina que minimiza estos tipos de errores.
En el segundo tipo de invalidación, Oracle maneja las dependencias locales, y algunas remotas, automáticamente, si un objeto A que depende de otro objeto B y el objeto B se invalida, el objeto A, al ser dependiente, se invalidará. Una vez que el objeto B se valide el objeto B no se validará hasta su próxima ejecución. Este enfoque evita recompilaciones innecesarias, ya que en el transcurso de un despliegue un objeto podría requerir multiples recompilaciones, pero por otro lado hay que ser muy cuidadoso en sistemas de alta transaccionabilidad (OLTP) ya que si se deja que el objeto se valide automáticamente al referenciarse por primera vez, y si esta invocación ocurre durante un pico de actividad de la base se podría ocasionar un lockeo en memoria (latch).
Las invalidaciones por dependencias mas problematicas son las que se dan por dependencias remotas, es decir las que se producen sobre objetos que referencian objetos remotos via dblinks. Dichas dependencias estan gobernadas por el parámetro remote_dependencies_mode que puede tener los siguientes valores: TIMESTAMP (default) y SIGNATURE. Es importante aclarar que Oracle solo maneja dependencias entre objetos de código, por ejemplo, Si un procedure Px en BD1 referencia una tabla remota T1 en B2 y la tabla se elimina, Px nunca se invalida (en vista dba_objects la columna status siempre será VALID para Px), por otro lado, si un procedure Px en BD1 referencia un procedure Py en BD2 y Py se invalida, entoces Px se invalidará en la próxima ejecución.
Modo Timestamp
- Cada vez que un procedimiento local llama a un procedimiento remoto, Oracle compara el timestamp que el primero local tiene del segundo y lo compara con el timestamp corriente del procedimiento remoto. Si los dos timestamp coinciden, ambos procedimientos se ejecutan.
- Si los timestamps no coinciden, el procedimiento local se invalida y se retorna un error al entorno que lo invocó.
- Cuando se compila un objeto dependiente se registra el timestamp de todos los procedimientos referenciados.
- El procedimiento local se invalida recién cuando se invoca el procedimiento remoto inválido por lo cual las sentencias que precedieron a la llamada corren normalmente.
- Las DML ‘s que precedieron la llamada que invalida al procedimiento local solo se “rollbackean” si están en el mismo bloque pl.
Modo Signature
Un RPC Signature cambia cuando al menos uno de los siguientes cambios son efecuados:
- Nombre
- Número de parámetros
- Tipo de datos de los parámetros
- Modo de cada parámetro
- Tipo de datos de valor de retorno (en funciones)
Para minimizar errores por dependencias remotas
- No abusar del uso de dblinks
- Declarar los registros con el atributo %ROWTYPE
- Declarar las variables con el atributo %TYPE
- Incluir la lista de columnas en los INSERT y SELECT
- Paquetizar los procedimientos y funciones
- Evitar realizar compilaciones en la ventana online
- Agregar nuevos procedimientos/funciones al final del paquete.
- Recompilar dependencias de primer y segundo nivel luego de cada nuevo desplique en BD.
Tipificación de Invalidaciones por Dependencias
El siguiente cuadro muestra los distintos escenarios de dependencias entre objetos y como Oracle resuelve cada uno:
|
Sesion 1 BD1
|
Sesion 2 BD2
|
Descripción
|
T0
|
create or replace procedure
sp_bd1
is
begin
sp_bd2@testinv;
end;
|
create or replace procedure
sp_bd2
is
cnt int;
begin
select count(1) into cnt from t;
end;
|
|
T1
|
VALID
2012-11-14 14:41:44
2012-11-14:14:41:44
|
VALID
2012-11-14 14:35:23
2012-11-14:14:35:23
|
|
T2
|
|
alter table t rename to u;
|
Se renombra la tabla
referenciada por sp_bd2 para que se invalide
|
T3
|
VALID
2012-11-14 14:41:44
2012-11-14:14:41:44
|
INVALID
2012-11-14 14:35:23
2012-11-14:14:35:23
|
|
T4
|
SQL> exec sp_bd1;
BEGIN sp_bd1; END;
*
ERROR en linea 1:
ORA-04063: procedure
"ROP.SP_BD2" tiene errores
ORA-06512: en
"ROP.SP_BD1", linea 4
ORA-06512: en linea 1
|
|
Falla la ejecución de sp_bd1
porque el objeto remoto referenciado esta invalido
|
T5
|
INVALID
2012-11-14 14:41:44
2012-11-14:14:41:44
|
INVALID
2012-11-14 14:38:50
2012-11-14:14:38:50
|
Con la ejecución de sp_bd1
cambió el last_ddl y el timestamp del sp referenciado en sp_bd2 y se invalidó
sp_bd1
|
T6
|
SQL> exec sp_bd1;
BEGIN sp_bd1; END;
*
ERROR en linea 1:
ORA-06550: linea 1, columna
7:
PLS-00905: el objeto
ROP.SP_BD1 no es valido
ORA-06550: linea 1, columna
7:
PL/SQL: Statement ignored
|
|
Al ejecutar la segunda vez
cambia el mensaje de error ya que el objeto ahora esta invalido.
|
T7
|
INVALID
2012-11-14 14:49:50
2012-11-14:14:49:50
|
INVALID
2012-11-14 14:38:50
2012-11-14:14:38:50
|
Cambió el last_dd y el
timestamp de sp_bd1 y no el de sp_bd2
|
T8
|
|
alter table u rename to t
|
Se renombra la tabla a
su nombre original, que es el usado en
sp_bd2
|
T9
|
INVALID
2012-11-14 14:49:50
2012-11-14:14:49:50
|
INVALID
2012-11-14 14:38:50
2012-11-14:14:38:50
|
Si bien ahora no hay errores
ni el sp local ni el remoto detectaron el cambio y siguen invalidos con los
mismas fechas
|
T10
|
|
SQL> exec sp_bd2;
|
Se ejecuta el sp_bd2 y no da
errores
|
T11
|
INVALID
2012-11-14 14:49:50
2012-11-14:14:49:50
|
VALID
2012-11-14 14:49:20
2012-11-14:14:49:20
|
Al ejecutarse y no tener mas
errores el sp se compila automáticamente con la primera invocación.
(validación local transparente). El sp_bd1 sigue invalido
|
T12
|
SQL> exec sp_bd1;
BEGIN sp_bd1; END;
*
ERROR en linea 1:
ORA-06550: linea 1, columna
7:
PLS-00905: el objeto
ROP.SP_BD1 no es valido
ORA-06550: linea 1, columna
7:
PL/SQL: Statement ignored
|
|
Se ejecuta el sp_bd1 y da
error porque esta invalido y no se valida automáticamente, aunque se vuelva a
ejecutar mas de una vez
|
T13
|
INVALID
2012-11-14 14:49:50
2012-11-14:14:49:50
|
|
|
T14
|
alter procedure sp_bd1
compile;
|
|
Se compila manualmente sp_bd1
|
T15
|
VALID
2012-11-14 15:00:22
2012-11-14:15:00:22
|
|
El procedimiento requirió
compilación manual para validarse.
|
No hay comentarios:
Publicar un comentario