Oracle Sessions und der steinige Weg ins Nirvana

Manchmal kommt es vor, dass man eine Oracle Session beenden möchte ohne gleich die ganze Datenbank durchstarten zu müssen 😉

Zum Beispiel wenn ein Workprozess im SAP gekillt wird, die aktuell laufende Aktion allerdings innerhalb des Oracles noch weiter ausgeführt wird und damit nicht nur Ressourcen bindet, sondern ggf. auch Locks auf Objekte hält.

Zunächst muss man die Sessions, die man beenden möchte identifizieren. Zum Beenden der Session braucht man die Session ID (sid) sowie die Seriennummer der Aktion innerhalb der SID (serial#). Diese bekommt man recht einfach über den View v$session. Meist dürfte die Session ID bereits über die SAP Transaktion DB02 bekannt sein, so dass hier lediglich die entsprechende Serial zu der Session ID gefunden werden muss. Da macht es natürlich Sinn die Abfrage entsprechend auf eine sid einzugrenzen. In einer RAC Umgebung müsste man übrigens auch noch die Instanz ID (inst_id) des entsprechenden Nodes mitgeben. Da SAP-Systeme eher selten auf RAC Umgebungen betrieben werden gehe ich nicht weiter darauf ein.

Das könnte etwa so aussehen:

SQL> set pages 200 lines 200
SQL> select SID, SERIAL#, PROGRAM, STATUS  from  v$session;

       SID    SERIAL# PROGRAM                                       STATUS
---------- ---------- --------------------------------------------- --------
         1      33845 oracle@sapserver-p1.sap.de (Q002)            ACTIVE
         4       3167 dw.sapSAP_D02@sapserver-p2 (TNS V1-V3)        INACTIVE
         5      56698 dw.sapSAP_D03@sapserver-p3 (TNS V1-V3)        INACTIVE
         7      25421 dw.sapSAP_D03@sapserver-p3 (TNS V1-V3)        INACTIVE
        11       3147 dw.sapSAP_D03@sapserver-p3 (TNS V1-V3)        INACTIVE
        17       4527 dw.sapSAP_D02@sapserver-p2 (TNS V1-V3)        INACTIVE
        28      15076 dw.sapSAP_D02@sapserver-p2 (TNS V1-V3)        INACTIVE
        76      33503 oracle@sapserver-p1.sap.de (Q003)            ACTIVE
        78       5048 dw.sapSAP_DVEBMGS00@sapserver-p1.sap.de (TNS INACTIVE
                       V1

        79      30944 dw.sapSAP_D02@sapserver-p2 (TNS V1-V3)        INACTIVE
[...]
1280 rows selected.

Um eine Session zu beenden wird sie mit folgendem Befehl für einen Kill vorgemerkt. Wichtig hierbei ist zu beachten, dass dies lediglich eine Vormerkung für ein Beenden der Session ist. Unter Umständen läuft die Session auch noch länger weiter. Im Gegensatz zu dem „kill bzw. kill -9“ auf *nix artigen Betriebssystemen wird hier nämlich nicht freundlich oder mit Nachdruck direkt der Prozess beendet, sondern lediglich die Session gefragt ob sie sich nicht beenden mag. Der SQL Befehl sieht dann wie folgt aus. Die Option „immediate“ gebe ich immer mit, damit der Befehl nicht das Terminal blockiert – ohne wartet der Befehl (synchron) auf das Feedback der Session:

alter system kill session 'sid,serail#' immediate;

Um die erste Session aus der oberen Liste zu beenden würde man jetzt also folgenden Befehl absetzen:

SQL> alter system kill session '1,33845' immediate; 

Wenn eine Session sich trotz des „kill session“ Kommandos nicht beenden lassen will hat man immer noch die Möglichkeit den entsprechenden Oracle Prozess über das Oracle oder über Betriebssystemmittel zu beenden. Gerade wenn man einen kill über das Betriebssystem von außerhalb der Datenbank absetzt sollte man mehr als nur einmal prüfen ob man den richtigen Prozess ausgewählt hat. Das könnte sonst – gerade auf stark ausgelasteten Produktionssystemen – zu ernsthaften Problemen führen.

Wenn man eine hängende Session hart per Oracle beenden will kann man das „alter system disconnect session“ Statement nutzen. Dies sorgt dafür, dass der entsprechende Serverprozess beendet wird und die Session somit stirbt. Es gibt zwei Optionen für die „disconnect session“ Methode und man muss eine von beiden nutzen: post_transaction oder immediate. Bei post_transaction wird gewartet bis die aktuell innerhalb der Session laufende Transaktion abgeschlossen ist (zum Beispiel ein Update auf eine Tabelle). Mit dem Schlüsselwort immediate wird ein sofortiges beenden erzwungen – dies geht dann mit einem sofortigem Rollback der abgebrochenen Transaktion einher. Ein solcher Rollback kann je nach Aktion und Einstellung der Priorität des smon Prozesses im Oracle sehr lange bis hin zu mehreren Tagen und sogar Wochen dauern. Zum Beispiel bei mehreren 100 Millionen inserts ohne erfolgten commit wird der insert per delete mit geringer Performance (default Settings smon) zurück gerollt.

alter system disconnect session 'sid,serail#' post_transaction;
alter system disconnect session 'sid,serail#' immediate;

Um die Session, die bereits im oberen Beispiel gebeten wurde sich zu beenden, unverzüglich zu killen würde man entsprechend folgenden Befehl absetzen:

SQL> alter system disconnect session '1,33845' immediate; 

Vergisst man übrigens eines der beiden Schlüsselwörter anzugeben reagiert das Oracle mit einem entsprechenden Hinweis:

SQL> alter system disconnect session '1,33845';
alter system disconnect session '1,33845'
                                        *
ERROR at line 1:
ORA-02000: missing POST_TRANSACTION or IMMEDIATE keyword

SQL>

About the author