miércoles, 20 de mayo de 2009

Script para limpiar conexiones inactivas en oracle

Cuando se usa alguna de las versiones gratuitas de oracle, solo es posible mantener cierto número de conexiones abiertas en determinado momento, por lo que es necesario, acabar con conexiones que no se estén utilizando. Aunque desde el código de la aplicación se puede hacer, existen ocasiones en las cuales, por algún motivo u otro, se quedan abiertas y es necesario cerrarlas. Para ver las conexiones registradas por Oracle, podemos ejecutar el siguiente comando:

SELECT * FROM SYS.V_$SESSION WHERE STATUS = 'INACTIVE' AND SCHEMANAME<>'SYS'

Con la condición, no queremos que nos muestre las conexiones al esquema SYS, ya que son las usadas por oracle. Nos mostrará las conexiones inactiva, podemos cambiar el la condición del campo STATUS a 'ACTIVE', 'INACTIVE' o 'KILLED'. Si quitamos esa condición nos mostrará todas las conexiones registradas en ese momento.

Al realizar la consulta, existen ciertos campos a los cuales presenta valiosa información, el primero es el campo llamado LAST_CALL_ET, el cual muestra el tiempo en segudos desde la última vez que la conexión "hizo" algo. A mayor valor, más tiempo ha estado de ociosa. La otra columna a la que hay que prestarle atención es WAIT_CLASS, que puede presentar varios valores, siendo IDLE es el nos convendría eliminar.

Con base a esta información podemos eliminar (kill) aquellas sesiones que estén inactivas, tengan un LAST_CALL_ET alto, y su WAIT_CLASS sea IDLE. Para eliminar (kill) una conexión, utilizamos el siguiente comando:

ALTER SYSTEM KILL SESSION '65,327'

Donde el primer número (67) indica la SID de la conexion, y el segundo (327) el SERIAL#. Adicionalmente, se le puede añadir la palabra INMEDIATE al final de la instrucción para ejecutar la eliminación de manera instantanea.

Por último es posible que se desee borrar de manera automática todas las conexiones que poseaan dichas características, incluso de manera periódica. Para ello es recomendable crear un script que lo haga por nosotros. Cabe resaltar, que en caso de que sea frecuente que nos pase el problema con las conexiones, lo más correcto es buscar la causa, ya sea por cuestiones de programación o de la red. Pero bueno, para hacer el borrado a la mala, podemos usar el siguiente script:

BEGIN

FOR R IN (SELECT SID, SERIAL# FROM SYS.V_$SESSION WHERE STATUS = 'INACTIVE' AND SCHEMANAME<>'SYS' )

LOOP
execute IMMEDIATE 'ALTER SYSTEM KILL SESSION ''' ||
R:SID || ',' || R.SERIAL# || '''';
END LOOP;

END;