Erheben von statistischen Informationen für einen SQL Server Teil 2

In Ergänzung zum Teil 1 und Nachfragen von Lesern möchte ich hier noch eine kurze Konkretisierung des Themas nachreichen: Natürlich gibt es diverse Monitoringtools, mit denen man in die Lage versetzt wird, diverse Informationen über Lastzustände oder ähnliches zu ermitteln. Mit meinen Artikel hierzu möchte ich mich allerdings auf die Möglichkeiten beschränken, welche sich mit den Bordmitteln des MS SQL Servers bieten.

In Teil 2 meines Artikels zum Erheben von statistischen Informationen für einen SQL Server möchte ich mit dem Thema der offenen Verbindungen und der angemeldeten Benutzer auseinandersetzen. Für allgemeine Informationen gibt es verschiedene Möglichkeiten, diese mittels SQL-Statements zu ermitteln.

Wie im letzten Artikel beginnen wir mit einem kurzen, einfachen Überblick über offene Verbindungen zu unserem SQL Server. Hierzu ist eine Stored Procedure vorgesehen:

sp_who

Das Resultset davon sieht in etwa so aus:

sp_whoDie hiermit erhobenen Informationen  sind allerdings noch nicht sehr vielsagend. Mehr Aussagekraft besitzt dafür die komplette Aufstellung aller Prozesse, die auf dem SQL Server gerade aktiv sind. Diese können über die Tabelle SysProcesses in der Master-Datenbank abgefragt werden.

Select * from Master..SysProcesses

Im Resultset finden wir schon detaillierter Informationen über laufende Prozesse. Allerdings haben wir hier auch alle Systemprozesse, unter anderem auch dem Vaterprozess mit der SPID 1, welcher uns im letzten Artikel schonmal untergekommen ist. Wollen wir nun nur eine Aufstellung aller Prozesse haben, welche nicht zu den reinen Systemprozessen gehören, sprich alle die, welche von Diensten oder Benutzern geöffnet wurden, können wir das Statement ein wenig modifizieren:

Select * from master..sysprocesses where IsNull(HostName, “) <> “ and IsNull(program_name, “) <> “ and isnull(hostprocess, “) <> “

Wie wir anhand dieses Statements feststellen, werden für Systemprozesse weder ein Hostname, ein Programmname noch ein entsprechender Hostprozess abgebildet, was bei Dienstprozessen oder Benutzerprozessen durchaus der Fall ist. Dies ist hier auch unser Unterscheidungskriterium. Wie wir im Resultset feststellen werden, ist es auf den ersten Blick ohne das Auswendiglernen sämtlicher Datenbank-ID’s nicht möglich zu erkennen, wer auf welcher Datenbank angemeldet ist. Dazu müssen wir das Statement noch ein wenig weiter ausbauen:

Select p.spid, p.login_time, p.last_batch, p.open_tran, p.status, p.nt_domain, p.nt_username, p.loginame,
p.hostname, p.program_name,
isnull(d.name, ’n/a‘) as DBName,
datediff(mi, p.login_time, getdate()) as ConnectionTime
from master..sysprocesses p left outer join master..sysdatabases d
on p.dbid = d.dbid
where IsNull(p.HostName, “) <> “ and IsNull(p.program_name, “) <> “ and isnull(p.hostprocess, “) <> “

Ich habe mich hier auf die meiner Meinung nach relevantesten Datenspalten beschränkt. Weitere können bei Bedarf gerne wieder hinzugefügt werden. Zusätzlich finden wir in diesem Statement noch eine Auflistung, welche Verbindung bereits wie lange in Minuten geöffnet ist. Somit ist es uns möglich, einen Überblick über angemeldete Benutzer und / oder Dienste sowie der entsprechenden Verbindungszeiten auf schnellem Wege zu liefern.

Und für alle die es noch nicht wissen: Eine geöffnete Verbindung kann man in der Rolle des sysadmin auch ohne die Mitwirkung des Anwenders manuell trennen: Hierzu wird das Kommando kill in Verbindung mit der (möglicherweise mittels eines Statements aus diesem Artikel) ermittelten SPID verwendet. Mehr dazu bei MSDN: KILL (Transact-SQL)