Welche Ereignisinformationen kann ich standardmäßig von SQL Server erhalten?

60

Ich sehe oft Fragen, wo die Leute wissen wollen, ob etwas passiert ist oder wann es passiert ist oder wer die Aktion ausgeführt hat. In vielen Fällen protokolliert SQL Server diese Informationen einfach nicht alleine. Zum Beispiel:

  • Wer hat die gespeicherte Prozedur zuletzt ausgeführt dbo.MyProcedure?
  • Wer hat die salarySpalte in der dbo.EmployeesTabelle aktualisiert ?
  • Wer hat die dbo.OrdersTabelle zuletzt von Management Studio aus abgefragt ?

Aber es gibt mehrere andere Ereignisse, die SQL Server nicht vorübergehend standardmäßig verfolgen und kann nativ beantworten Fragen zu, wie zum Beispiel:

  • Wann fand zum letzten Mal ein automatisches Wachstum in der AdventureWorks-Datenbank statt und wie lange hat es gedauert?
  • Wer löschte den dbo.EmployeeAuditDataTisch und wann?
  • Wie viele Speicherfehler sind heute aufgetreten?

Wie erhalte ich diese Informationen und wie lange bleiben sie verfügbar?

Aaron Bertrand
quelle

Antworten:

65

Es gibt eine Menge wertvoller Informationen, die SQL Server standardmäßig für Sie protokolliert. Seit SQL Server 2005 gibt es eine "Standardablaufverfolgung", die im Hintergrund ausgeführt wird, und seit SQL Server 2008 wird automatisch eine erweiterte Ereignissitzung mit dem Namen "Extended Events" ausgeführt system_health.

Sie können auch bestimmte Informationen aus dem SQL Server-Fehlerprotokoll, dem SQL Server-Agentenprotokoll, den Windows-Ereignisprotokollen und zusätzlichen Protokollen von Dingen wie SQL Server-Überwachung , Management Data Warehouse , Ereignisbenachrichtigungen , DML-Triggern , DDL-Triggern , SCOM / System Center abrufen , Ihre eigenen serverseitigen Traces oder Extended Events-Sitzungen oder Überwachungslösungen von Drittanbietern (wie die von meinem Arbeitgeber SQL Sentry ). Optional können Sie auch einen sogenannten "Blackbox-Trace" aktivieren , um die Fehlerbehebung zu unterstützen .

In diesem Beitrag werde ich mich jedoch auf Dinge konzentrieren, die im Allgemeinen überall aktiviert sind: die Standardablaufverfolgung, erweiterte Ereignissitzungen und das Fehlerprotokoll.

Standard-Trace

Der Standard-Trace wird normalerweise auf den meisten Systemen ausgeführt, sofern Sie ihn nicht mit deaktiviert habensp_configure . Solange es aktiviert ist, kann dies eine wertvolle Informationsquelle sein. In der folgenden Liste sind die erfassten Ablaufverfolgungsereignisse aufgeführt:

DECLARE @TraceID INT;

SELECT @TraceID = id FROM sys.traces WHERE is_default = 1;

SELECT t.EventID, e.name as Event_Description
  FROM sys.fn_trace_geteventinfo(@TraceID) t
  JOIN sys.trace_events e ON t.eventID = e.trace_event_id
  GROUP BY t.EventID, e.name;

Sie können detaillierter werden, indem Sie sich anmelden, um sys.trace_columnszu sehen, welche Ereignisse mit welchen Daten einhergehen. Ich werde dies jedoch überspringen, da Sie sehen können, was Sie haben, wenn Sie die Ablaufverfolgungsdaten für bestimmte Ereignisse tatsächlich abfragen. Dies sind die Ereignisse, die auf meinem System verfügbar sind (Sie sollten die Abfrage auf Ihrem System ausführen, um sicherzustellen, dass sie übereinstimmen, obwohl dies immer noch dieselbe Ereignisgruppe über SQL Server 2019 CTP 2.4 ist):

EventID  Event_Description
-------  ----------------------------------------------
18       Audit Server Starts And Stops
20       Audit Login Failed
22       ErrorLog
46       Object:Created
47       Object:Deleted
55       Hash Warning
69       Sort Warnings
79       Missing Column Statistics
80       Missing Join Predicate
81       Server Memory Change
92       Data File Auto Grow
93       Log File Auto Grow
94       Data File Auto Shrink
95       Log File Auto Shrink
102      Audit Database Scope GDR Event
103      Audit Schema Object GDR Event
104      Audit Addlogin Event
105      Audit Login GDR Event
106      Audit Login Change Property Event
108      Audit Add Login to Server Role Event
109      Audit Add DB User Event
110      Audit Add Member to DB Role Event
111      Audit Add Role Event
115      Audit Backup/Restore Event
116      Audit DBCC Event
117      Audit Change Audit Event
152      Audit Change Database Owner
153      Audit Schema Object Take Ownership Event
155      FT:Crawl Started
156      FT:Crawl Stopped
164      Object:Altered
167      Database Mirroring State Change
175      Audit Server Alter Trace Event
218      Plan Guide Unsuccessful

Beachten Sie, dass der Standard-Trace Rollover-Dateien verwendet und die Ihnen zur Verfügung stehenden Daten nur bis zu diesem Zeitpunkt zurückgehen. Der Datumsbereich der verfügbaren Daten hängt davon ab, wie viele der oben genannten Ereignisse mit welcher Häufigkeit erfasst werden. Wenn Sie sicherstellen möchten, dass Sie einen längeren Verlauf beibehalten, können Sie einen Job einrichten, der die derzeit inaktiven Dateien, die dem Trace zugeordnet sind, regelmäßig archiviert.

Beispiele

In der Frage habe ich ein paar Fragen gestellt, die ich gefunden habe. Im Folgenden finden Sie Beispielabfragen zum Abrufen dieser spezifischen Informationen aus der Standardablaufverfolgung.

Frage: Wann fand das letzte Mal ein automatisches Wachstum in der AdventureWorks-Datenbank statt und wie lange hat es gedauert?

Diese Abfrage ruft alle AutoGrow-Ereignisse in der AdventureWorks-Datenbank für Protokoll- und Datendateien ab, die sich noch in den Standard-Ablaufverfolgungsprotokolldateien befinden:

DECLARE @path NVARCHAR(260);

SELECT 
   @path = REVERSE(SUBSTRING(REVERSE([path]), 
   CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM    sys.traces
WHERE   is_default = 1;

SELECT 
   DatabaseName,
   [FileName],
   SPID,
   Duration,
   StartTime,
   EndTime,
   FileType = CASE EventClass WHEN 92 THEN 'Data' ELSE 'Log' END
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE EventClass IN (92,93)
AND DatabaseName = N'AdventureWorks'
ORDER BY StartTime DESC;

Frage: Wer hat die Tabelle dbo.EmployeeAuditData wann gelöscht?

Dadurch werden alle DROPEreignisse für ein Objekt mit dem Namen zurückgegeben EmployeeAuditData. Wenn Sie sicherstellen möchten, dass nur DROPEreignisse für Tabellen erkannt werden, können Sie einen Filter hinzufügen: ObjectType = 8277(Die vollständige Liste ist hier dokumentiert. ) Wenn Sie den Suchraum zu einer bestimmten Datenbank beschränken möchten, können Sie einen Filter hinzufügen: DatabaseName = N'db_name'.

DECLARE @path NVARCHAR(260);

SELECT 
   @path = REVERSE(SUBSTRING(REVERSE([path]), 
   CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM    sys.traces
WHERE   is_default = 1;

SELECT 
  LoginName,
  HostName,
  StartTime,
  ObjectName,
  TextData
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE EventClass = 47    -- Object:Deleted
AND EventSubClass = 1
AND ObjectName = N'EmployeeAuditData'
ORDER BY StartTime DESC;

Es gibt hier eine Komplikation, und es ist sehr Randfall, aber es war ratsam, es trotzdem zu erwähnen. Wenn Sie mehrere Schemas verwenden und in mehreren Schemas möglicherweise denselben Objektnamen haben, können Sie nicht feststellen, um welches es sich handelt (es sei denn, die Gegenstücke existieren noch). Es gibt einen äußeren Fall, in dem BenutzerA SchemaA.Tabellenname gelöscht hat, während BenutzerB SchemaA.Tabellenname gelöscht hat. Die Standardablaufverfolgung verfolgt nicht das Schema des Objekts (und erfasst auch nicht TextDatafür dieses Ereignis)ObjectIDDie Angabe in der Ablaufverfolgung ist für eine direkte Übereinstimmung nicht hilfreich (da das Objekt gelöscht wurde und nicht mehr vorhanden ist). In diesem Fall kann es hilfreich sein, diese Spalte in die Ausgabe aufzunehmen, um Querverweise auf Kopien der Tabelle mit demselben Namen zu erstellen, die noch vorhanden sind. Befindet sich das System jedoch in dieser Unordnung (oder wurden alle Kopien gelöscht) Es ist immer noch keine verlässliche Möglichkeit zu erraten, welche Kopie der Tabelle von wem abgelegt wurde.

Erweiterte Veranstaltungen

Von Unterstützung von SQL Server 2008: Die system_health Sitzung (SQLCSS Blog) , die im Anschluss an die Liste der Daten , die Sie aus der keulen können system_healthSitzung in SQL Server 2008 und 2008 R2:

  • Der sql_text und die session_id für alle Sitzungen, bei denen ein Fehler mit einem Schweregrad> = 20 auftritt
  • Der sql_text und die session_id für alle Sitzungen, bei denen ein "Speicher" -Fehler auftritt, z. B. 17803, 701 usw. (wir haben dies hinzugefügt, da nicht alle Speicherfehler den Schweregrad> = 20 haben.)
  • Eine Aufzeichnung aller "nicht nachgebenden" Probleme (Sie haben diese manchmal im ERRORLOG als Nachricht 17883 gesehen)
  • Alle erkannten Deadlocks
  • Callstack, sql_text und session_id für alle Sitzungen, die länger als 15 Sekunden auf Latches (oder andere interessante Ressourcen) gewartet haben
  • Callstack, sql_text und session_id für alle Sitzungen, die länger als 30 Sekunden auf Sperren gewartet haben
  • Callstack, sql_text und session_id für jede Sitzung, die längere Zeit auf "externe" Wartezeiten oder "präventive Wartezeiten" gewartet hat.

Unter Verwenden der Ereignissitzung system_health (MSDN) wird die Liste in SQL Server 2012 etwas erweitert (und bleibt für SQL Server 2014 unverändert):

  • Der sql_text und die session_id für alle Sitzungen, bei denen ein Fehler mit einem Schweregrad> = 20 auftritt.
  • Der sql_text und die session_id für alle Sitzungen, bei denen ein Speicherfehler auftritt. Die Fehler umfassen 17803, 701, 802, 8645, 8651, 8657 und 8902.
  • Eine Aufzeichnung aller nicht ergebenden Scheduler-Probleme. (Diese werden im SQL Server-Fehlerprotokoll als Fehler 17883 angezeigt.)
  • Alle erkannten Deadlocks.
  • Callstack, sql_text und session_id für alle Sitzungen, die länger als 15 Sekunden auf Latches (oder andere interessante Ressourcen) gewartet haben.
  • Callstack, sql_text und session_id für alle Sitzungen, die länger als 30 Sekunden auf Sperren gewartet haben.
  • Callstack, sql_text und session_id für alle Sitzungen, die lange auf vorbeugende Wartezeiten gewartet haben. Die Dauer variiert je nach Wartezeit. Bei einer vorbeugenden Wartezeit wartet SQL Server auf externe API-Aufrufe.
  • Die Aufrufliste und die Sitzungs-ID für CLR-Zuordnungs- und virtuelle Zuordnungsfehler.
  • Die ring_buffer-Ereignisse für den Speicherbroker, den Scheduler-Monitor, das OOM des Speicherknotens, die Sicherheit und die Konnektivität.
  • Systemkomponente ergibt sich aus sp_server_diagnostics.
  • Von scheduler_monitor_system_health_ring_buffer_recorded erfasster Zustand der Instanz.
  • CLR-Zuordnungsfehler.
  • Verbindungsfehler mit connectivity_ring_buffer_recorded.
  • Sicherheitsfehler mit security_error_ring_buffer_recorded.

In SQL Server 2016 werden zwei weitere Ereignisse erfasst:

  • Wenn ein Prozess mit dem KILLBefehl beendet wird.
  • Wenn das Herunterfahren von SQL Server gestartet wurde.

(Die Dokumentation wurde noch nicht aktualisiert, aber ich habe gebloggt, wie ich diese und andere Änderungen entdecke .)

Sie können die folgende Abfrage immer direkt ausführen, um die für Ihre bestimmte Version geeignetere Konfiguration zu erhalten. Sie müssen jedoch die Namen interpretieren und die Prädikate analysieren, um sie mit den oben genannten Listen natürlicherer Sprachen abzugleichen:

SELECT e.package, e.event_id, e.name, e.predicate
  FROM sys.server_event_session_events AS e
  INNER JOIN sys.server_event_sessions AS s
  ON e.event_session_id = s.event_session_id
 WHERE s.name = N'system_health'
 ORDER BY e.package, e.name;

Wenn Sie Verfügbarkeitsgruppen verwenden, werden zwei neue Sitzungen ausgeführt: AlwaysOn_failoverund AlwaysOn_health. Sie können die gesammelten Daten mit der folgenden Abfrage anzeigen:

SELECT s.name, e.package, e.event_id, e.name, e.predicate
  FROM sys.server_event_session_events AS e
  INNER JOIN sys.server_event_sessions AS s
  ON e.event_session_id = s.event_session_id
 WHERE s.name LIKE N'AlwaysOn[_]%'
 ORDER BY s.name, e.package, e.name;

In diesen Ereignissitzungen werden Ringpufferziele zum Speichern der Daten verwendet. Daher werden ältere Ereignisse - wie der Pufferpool und der Plan-Cache - auslaufen, sodass Sie nicht unbedingt Ereignisse aus dem gewünschten Datumsbereich abrufen können.

Beispiel

In der Frage stellte ich diese fiktive Frage:

Wie viele Speicherfehler sind heute aufgetreten?

Hier ist eine Beispielabfrage (und wahrscheinlich nicht sehr effizient), mit der diese Informationen aus der system_healthSitzung abgerufen werden können:

;WITH src(x) AS
(
  SELECT y.query('.')
  FROM
  (
    SELECT x = CONVERT(XML, t.target_data)
      FROM sys.dm_xe_sessions AS s
      INNER JOIN sys.dm_xe_session_targets AS t
      ON s.[address] = t.event_session_address
      WHERE s.name = N'system_health'
  ) AS x
  CROSS APPLY x.x.nodes('/RingBufferTarget/event') AS y(y)
)
SELECT 
  x, ts = CONVERT(DATETIME, NULL), err = CONVERT(INT, NULL)
INTO #blat FROM src;

DELETE #blat WHERE x.value('(/event/@name)[1]', 'varchar(255)') <> 'error_reported';

UPDATE #blat SET ts = x.value('(/event/@timestamp)[1]', 'datetime');

UPDATE #blat SET err = x.value('(/event/data/value)[1]', 'int');

SELECT err, number_of_events = COUNT(*)
  FROM #blat
  WHERE err IN (17803, 701, 802, 8645, 8651, 8657, 8902)
  AND ts >= CONVERT(DATE, CURRENT_TIMESTAMP)
  GROUP BY err;

DROP TABLE #blat;

(Dieses Beispiel ist lose aus Amit Banerjees einleitendem Blogbeitrag zur system_healthSitzung entlehnt .)

Weitere Informationen zu erweiterten Ereignissen (einschließlich vieler Beispiele, in denen Sie bestimmte Daten abfragen können) finden Sie in dieser 31-teiligen Blog-Reihe von Jonathan Kehayias:

https://www.sqlskills.com/blogs/jonathan/an-xevent-a-day-31-days-of-extended-events/

Fehlerprotokoll

SQL Server behält standardmäßig die aktuellen plus 6 neuesten Fehlerprotokolldateien bei (dies kann jedoch geändert werden ). Dort sind zahlreiche Informationen gespeichert, einschließlich Startinformationen (wie viele Kerne verwendet werden, ob Seiten im Speicher gesperrt sind, Authentifizierungsmodus usw.) sowie Fehler und andere Szenarien, die schwerwiegend genug sind, um dokumentiert zu werden (und nicht an anderer Stelle erfasst werden). Ein aktuelles Beispiel war jemand, der suchte, als eine Datenbank offline geschaltet wurde. Sie können dies feststellen, indem Sie die letzten 7 Fehlerprotokolle nach dem Text durchsuchen Setting database option OFFLINE:

EXEC sys.sp_readerrorlog 0,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 1,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 2,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 3,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 4,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 5,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 6,1,'Setting database option OFFLINE';

Ich habe in der letzten Antwort einige andere Details behandelt , und es gibt auch einige gute Hintergrundinformationen bei toadworld und auch in der offiziellen Dokumentation .

Eine Gruppe von "Fehlern", die das Fehlerprotokoll standardmäßig protokolliert - und die dazu führen kann, dass wichtige Informationen viel schneller abhanden kommen - ist jede erfolgreiche Sicherungsnachricht. Sie können verhindern, dass diese das Fehlerprotokoll mit Rauschen füllen, indem Sie das Ablaufverfolgungsflag 3226 aktivieren .

Aaron Bertrand
quelle