Einleitung Administration Assistant for Windows

Werbung
Betrifft:
Oracle-Threads unter Win32-Systemen killen
Autor:
Dirk Nachbar
Art der Info:
Technische Background Info
Quelle:
Aus unserer Projekterfahrung
Einleitung
Von Zeit zu Zeit muss ein Oracle DBA eine Session eines Users killen und verwendet
zumeist den SQL-Befehl „alter system kill session ...“. Unter den meisten Umständen ist die
Antwortzeit für diesen Vorgang zu lang und auch oftmals wird nach Beendigung des „kill
session“-Befehls das Problem nicht sofort bereinigt (CPU-Belastung usw.).
Eine weitere Variante die Problemsession zu beenden ist den Oracle Service zu beenden
oder via den Task-Manager den gesamten Oracle-Prozess zu beenden, was zumeist als
letzte Notlösung verwendet wird und zur Folge hat, dass alle Usersessions beendet werden
.
Ein prägnanter Unterschied zwischen Oracle unter UNIX-Derivaten und Windows
Plattformen ist die Prozessstruktur. Unter UNIX Derivaten lassen sich problemlos alle
Oracle Prozesse auflisten (ps-Befehl) und explizit beenden (kill -9), aber unter Windows
Plattformen sieht man nur einen „großen“ Oracle Prozess, welcher sich in mehrere Threads
unterteilt. Aber auch hierfür stellt Oracle Tools zur Verfügung um einzelne Threads zu
killen, ohne gleich die gesamte Instanz zu stoppen. Diese Threads lassen sich zwar auch
mittels diverser Tools darstellen, aber wie findet man nun den entsprechenden Thread
eindeutig heraus?
Administration Assistant for Windows
Oracle bietet mittels dem Administration Assistent for Windows eine grafische Möglichkeit
sich die Oracle Threads anzeigen zu lassen und explizit zu „killen“.
Über das Kontextmenü „Prozessinformationen ...“ erhält mal eine ziemlich detailiierte
Auflistung der aktuellen Threads mit Programmnamen, Typ, Oracle-Benutzer, Thread-ID
und CPU-Belastung.
Hier muss man nur den entsprechenden Thread markieren und sodann den Button „Thread
abbrechen“ betätigen.
In Umgebungen, in denen jeder Anwender mit seinem eigenen Oracle-Benutzer sich an
die Datenbank anmeldet ist dieses Tool eine gute Wahl, doch in einigen Umgebungen
melden sich die Anwender mit nur einem Oracle-Benutzer an, so dass man keine Chance
hat mittels dieses Tools den richtigen Thread zu killen.
Orakill – CommandLine Utility
Bereits seit Oracle 7.3 gibt es unter Windows das kaum beachtete Command-Line Utility
orakill.
C:\> orakill -?
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
C:\>
Führt man das oben angeführte SQL Script aus, erhält man zwar die Thread ID (spid), den
Betriebssystembenutzer und das Programm welche zu dem Thread gehören, aber jedoch
nicht den Oraclebenutzer bzw. den Oracleprozess (PMON, SMON usw) und die ClientWorkstation.
SQL> select spid, osuser, s.program from
2 v$process p, v$session s where p.addr=s.paddr;
SPID
--------
OSUSER
-------------------
PROGRAM
--------------------
300
1468
..
..
..
2488
2492
2496
2504
2512
2532
1544
2304
SYSTEM
SYSTEM
ORACLE.EXE
ORACLE.EXE
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\din
TRIVADIS\din
TRIVADIS\din
JRE.EXE
JRE.EXE
JRE.EXE
JRE.EXE
JRE.EXE
MMC.EXE
SQLPLUS.EXE
SQLPLUS.EXE
28 Zeilen ausgewählt
Erweitern man das Statement wie nachfolgend dargestellt, erhält man alle „Oracle Threads“
und die Angabe der Client-Workstation.
SQL> select p.spid "OS Th", b.name "Name-User", s.osuser,
2 s.program, s.terminal
3 from v$process p, v$session s, v$bgprocess b
4
where p.addr = s.paddr
5
and p.addr = b.paddr UNION ALL
6
select p.spid "OS Th", s.username "Name-User",
7
s.osuser, s.program, s.terminal
8
from v$process p, v$session s
9
where p.addr = s.paddr
10
and s.username is not null;
OS Th
-----
Name-User
--------------
OSUSER
--------------
PROGRAM
------------
TERMINAL
----------
300
1468
..
..
..
2488
2492
2496
2504
2512
2532
1544
2304
PMON
DBW0
SYSTEM
SYSTEM
ORACLE.EXE
ORACLE.EXE
LTDIN
LTDIN
OEM_LTDIN_PROD
OEM_LTDIN_PROD
OEM_LTDIN_PROD
OEM_LTDIN_PROD
OEM_LTDIN_PROD
OEM_LTDIN_PROD
SCOTT
SCOTT
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\LTDIN$
TRIVADIS\din
TRIVADIS\din
TRIVADIS\din
JRE.EXE
JRE.EXE
JRE.EXE
JRE.EXE
JRE.EXE
MMC.EXE
SQLPLUS.EXE
SQLPLUS.EXE
LTDIN
LTDIN
LTDIN
LTDIN
LTDIN
LTDIN
LTDIN
LTTEST
28 Zeilen ausgewählt
Nun ist der DBA in der Lage, den gesuchten Thread eindeutig zu identifizieren und zu
„killen“, auch wenn sich der Anwender von mehreren Client-Workstations aus mit dem
gleichen Betriebssystembenutzer connected hat.
C:\> orakill PROD 1544
Kill of thread id 1544 in instance PROD successfully signalled.
C:\>
Versucht der Benutzer nach dem „Thread-Kill“ eine Aktion auf der Datenbank, erhält er
folgende Fehlermeldung:
SQL> select * from dual;
select * from dual
*
FEHLER in Zeile 1:
ORA-12571: TNS:packet writer failure
Erweitert man das oben stehende Statement folgendermassen, werden alle Threads
angezeigt und interaktiv wird ein Commandline-Batch erzeugt, welcher eine Nachricht via
„net send“ an die entsprechende Client-Workstation sendet das seine
Datenbankverbindung beendet wird und anschliessend der ausgewählte Thread mittels
orakill beendet wird.
select p.spid "OS Th", b.name "Name-User", s.osuser,
s.program, s.terminal
from v$process p, v$session s, v$bgprocess b
where p.addr = s.paddr
and p.addr = b.paddr UNION ALL
select p.spid "OS Th", s.username "Name-User",
s.osuser, s.program, s.terminal
from v$process p, v$session s
where p.addr = s.paddr
and s.username is not null;
set echo off
set feedback off
set verify off
ACCEPT threadid PROMPT 'Please enter Thread ID (spid): '
ACCEPT sid PROMPT 'Please enter SID: '
set termout off
set heading off
spool kill_thread.bat
select 'net send '||s.terminal||' Your Database Connect will be
closed' from v$process p, v$session s where
p.addr=s.paddr and spid=&threadid
/
select 'orakill &sid '||spid||'' from v$process
where spid=&threaded
/
spool off
set heading on
set termout on
PROMPT Commandline Batch is finished and named kill_thread.bat
Diese Methode funktioniert von Oracle 7.3.x bis hoch zur aktuellen Oracle 9i.
Hinweis:
Das Oracle Utility orakill verwendet den Systemaufruf TerminateThread(). Dieser Aufruf
bewirkt nicht, dass der Stackbereich freigegeben wird. Doch dieser Stackbereich bleibt
allozier- und verwendbar für den Oracle-Prozess. ☺
Falls Sie noch mehr über Oracle 9i erfahren wollen, dann würde es uns freuen, Sie in
einem unserer 9i-Kurse (NF9i, AI9-A, AI9-B) begrüßen zu dürfen.
Viel Spaß und wenige zu killende Threads wünscht
Dirk Nachbar
Trivadis GmbH
Dirk Nachbar
Cityforum im Eichsfeld
Ferdinand-Stuttmann-Str. 13
D-65428 Rüsselsheim
Internet: http://www.trivadis.com
Mail:
[email protected]
Tel:
Fax:
+49 6142 210 18 0
+49 6142 210 18 29
Herunterladen