viernes, 27 de febrero de 2009

Matar sesiones Oracle en Windows

A veces necesitamos matar sesiones de la base de datos Oracle, muchas veces estas sesiones se quedan “colgadas” e inactivas incluso por dias, otras veces aunque están en estado activo se nos pide que las eliminemos.

Para matar una sesión contamos con el comando ALTER SYSTEM KILL SESSION 'sid, serial#'

Previamente debo de conocer el sid y el serial# de la sesión que deseo eliminar, en este caso quiero matar al usuario QUICK:

SQL> select sid, serial#, username, status from v$session;


SID SERIAL# USERNAME STATUS
---------- ---------- ---------- --------
370 226 ACTIVE
373 557 QUICK INACTIVE
381 90 SYS ACTIVE
383 1 ACTIVE
385 1 ACTIVE
386 7 ACTIVE
389 3 ACTIVE
390 3 ACTIVE
391 4 ACTIVE
393 1 ACTIVE
394 1 ACTIVE
395 1 ACTIVE
396 1 ACTIVE
397 1 ACTIVE
398 1 ACTIVE
399 1 ACTIVE
400 1 ACTIVE

17 rows selected.




El comando para eliminar el sid 373 es el siguiente:



SQL> alter system kill session '373,557';

System altered.





Sin embargo hay ocasiones en que ALTER SYSTEM KILL SESSION no libera los bloqueos que tenía la sesión que matamos.
Esto sucede cuando una sesión no puede ser interrumpida hasta que terminie la operación que está realizando.
En este caso, la sesión mantiene todos los recursos que obtuvo de nuestro servidor hasta que termina la operación.
Normalmente, la sesión que ejecutó el ALTER SYSTEM KILL SESSION recibe el mensaje: “the session has been marked to be terminated”.
Y la sesión aparece en v$session con status “KILLED”



SQL> select sid, serial#, username, status from v$session;

SID SERIAL# USERNA STATUS
---------- ---------- ------ --------
370 108 ACTIVE
373 557 QUICK KILLED
381 90 SYS ACTIVE
383 1 ACTIVE
385 1 ACTIVE
386 7 ACTIVE
389 3 ACTIVE
390 3 ACTIVE
391 4 ACTIVE
393 1 ACTIVE
394 1 ACTIVE
395 1 ACTIVE
396 1 ACTIVE
397 1 ACTIVE
398 1 ACTIVE
399 1 ACTIVE
400 1 ACTIVE

17 rows selected.







En linux tenemos la ventaja de poder matar el proceso del usuario con un kill -9, conociendo previamente el proceso del usuario.

La arquitectura de Windows no nos permite observar los distintos procesos que tiene Oracle, solo percibimos un oracle.exe, en el cual existen varios threads.

Para que en Windows nos podamos liberar de la sesión que quedó en estatus “KILLED”, podemos hacer cualquiera de las siguientes opciones:
1.Shutdown/Startup de la base de datos
2.Utilizar la utilería ORAKILL para eliminar threads.

Primeramente encontramos el thread con el siguiente query (debemos de conocer el thread previamente a ejecutar el comando ALTER SYSTEM KILL SESSION, de otra manera Oracle perdería la referencia al thread en cuestión):



SQL> select p.spid Thread, s.username Username, s.program
2 from v$process p, v$session s
3 where p.addr = s.paddr and s.username is not null;

THREAD USERNAME PROGRAM
------------ -------- -------------
364 SYS sqlplus.exe
4524 QUICK sqlplus.exe


SQL> exit



C:\Documents and Settings\Erika>orakill -h


Usage: orakill sid thread

where sid = the Oracle instance to target
thread = the thread id of the thread to kill

The thread id should be retrieved from the spid column of a query such as:

select spid, osuser, s.program from
v$process p, v$session s where p.addr=s.paddr




El comando por lo tanto sería:



C:\Documents and Settings\Erika>orakill OAS 4524

Kill of thread id 4524 in instance OAS successfully signalled.




Puesto que mi servicio se llama OAS.

A continuación en v$session vemos que ya no existe la sesión del usuario QUICK



SQL> select sid, serial#, username, status from v$session;


SID SERIAL# USERNAME STATUS
---------- ---------- ---------- --------
370 226 ACTIVE
381 90 SYS ACTIVE
383 1 ACTIVE
385 1 ACTIVE
386 7 ACTIVE
389 3 ACTIVE
390 3 ACTIVE
391 4 ACTIVE
393 1 ACTIVE
394 1 ACTIVE
395 1 ACTIVE
396 1 ACTIVE
397 1 ACTIVE
398 1 ACTIVE
399 1 ACTIVE
400 1 ACTIVE

16 rows selected.


Hay que tener cuidado porque al utilizar el comando ORAKILL para matar un thread corremos el riesgo de matar el proceso ORACLE.EXE