Arrêter une autre session avec [Ctrl]+C et oradebug

Si vous utilisez SQL*Plus, vous savez qu’avec un « [Ctrl]+C », vous pouvez arrêter un ordre SQL sans arrêter votre session, ni votre transaction. Et bien, il est possible de lancer l’équivalent d’un « [Ctrl]+C » sur une autre session que la votre. Il est probablement très déconseillé de s’amuser à ça sur une production mais pour de faux, voici comment faire…

Exemple

Imaginons une requête en cours coûteuse… Lancez une session SQL*Plus et lancez par exemple la séquence d’ordres SQL qui suit :

sqlplus / as sysdba

set timing on

select count(*)
from dba_objects a, dba_objects b;

Lancer un « [Ctrl]+C » depuis une autre session

Lancez une autre session SQL*Plus et déterminez la session active (Attention, dans mon test, je n’ai qu’une session active; dans votre cas, il faudra sans doute filtrer votre requête sur plus de critères ou des critères différents :

sqlplus / as sysdba

col sid format 9999999 new_value sid
col serial# format 9999999 new_value serial
col sql_id format a15 new_value sql_id
select sql_id, sid, serial# from v$session
where status='ACTIVE'
and username is not null
and sid != sys_context('userenv', 'sid')
and program like 'sqlp%';

SQL_ID SID SERIAL#
------------- ---------- ----------
9dtkhfhpgt2sh 125 5


select * from table(dbms_xplan.display_cursor('&&sql_id'));

Une fois la session identifiée, vous pouvez récupérer le PID du process serveur, puis vous attacher avec oradebug :

col tracefile format a80
set lines 180
col spid format a10 new_value spid
select s.sid, p.spid, p.tracefile
from v$session s, v$process p
where s.paddr=p.addr
and s.sid=&&sid;

SID SPID TRACEFILE
--- ---- -----------------------------------------------------------------
125 2396 /u01/app/oracle/diag/rdbms/black/BLACK/trace/BLACK_ora_2396.trc


oradebug setospid &&spid
Oracle pid: 19, Unix process pid: 2396, image: oracle@arkzoyd (TNS V1-V3)

Pour lancer le [Ctrl]+C, tapez simplement les 2 lignes ci-dessous:

oradebug session_event 10237 trace name context forever, level 1 
oradebug session_event 10237 trace name context off;

Dans votre première session, vous voyez apparaître la ligne suivante; votre requête est arrêtée

       *
ERROR at line 3:
ORA-01013: user requested cancel of current operation

L’histoire ne dit pas si votre application s’en remettra.

Notes:
1- Si vous n’annulez pas l’event 10237, tous les ordres qui suivent finiront avec la même erreur. C’est peut-être ce que vous recherchez 😉
2- Vous pouvez également envoyer l’event avec dbms_system.set_ev comme ci-dessous :

exec dbms_system.set_ev(&&sid,&&serial,10237,1,'');
exec dbms_system.set_ev(&&sid,&&serial,10237,0,'');