miércoles, 25 de enero de 2012

Matar sesiones a nivel Sistema Operativo (Windows)

A veces nos encontramos con que mandamos a matar una sesión y esta queda marcada para "eliminar", y ahí persiste.

Podemos eliminar la sesión a nivel sistema operativo (matar el proceso de SO de la sesión) de la siguiente forma:

Primero, verificar que la sesión no esté haciendo operaciones de rollback

SELECT s.username,
       s.sid,
       s.serial#,
       t.used_ublk,
       t.used_urec,
       rs.segment_name,
       r.rssize,
       r.status
FROM   v$transaction t,
       v$session s,
       v$rollstat r,
       dba_rollback_segs rs
WHERE  s.saddr = t.ses_addr
AND    t.xidusn = r.usn
AND    rs.segment_id = t.xidusn
ORDER BY t.used_ublk DESC;

Si el campo used_urec tiene una cantidad distinta de cero y esta va decreciendo, hay que esperar para que termine de hacer rollback a sus operaciones.

Ya cuando no tenga operaciones de rollback pendientes (no aparecera como resultado del query), se procede a obtener el SPID (Server Process ID) de la sesión con la siguiente consulta:


select v.sid, a.SPID, v.serial#, v.username, v.OSUSER, v.program, v.MACHINE, v.LOGON_TIME
from user_users u, v$session v, v$process a
where v.user# = u.user_id
and v.paddr = a.addr;

Ya con el SPID y el nombre de la instancia de Base de Datos (que se obtiene con esto select sys_context('USERENV','DB_NAME') as Instance from dual;) se procede a ejecutar el comando ORAKILL desde una consola de MSDOS en el servidor.

El comando ORAKILL pide como parametros el nombre de la instancia y el SPID de la sesión a eliminar.

El comando quedaría de la siguiente manera:

C:\>orakill MiBaseDeDatos 7559

Al ejecutarse con éxito, muestra el siguiente mensaje


Kill of thread id  7559 in instance  MiBaseDeDatos  successfully signalled.

Fuentes:
http://cajondesastreoracle.wordpress.com/scripts-sql-curiosos/session_undo-sql/
http://vitocosan.wordpress.com/2009/06/03/orakill-matar-una-conexion-activa-de-oracle/