it-swarm.com.de

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

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

  • Wer hat zuletzt die gespeicherte Prozedur dbo.MyProcedure Ausgeführt?
  • Wer hat die Spalte salary in der Tabelle dbo.Employees Aktualisiert?
  • Wer hat zuletzt die Tabelle dbo.Orders Von Management Studio abgefragt?

Es gibt jedoch mehrere andere Ereignisse, die SQL Server tut standardmäßig vorübergehend verfolgt und nativ Fragen beantworten kann, z. B.:

  • Wann wurde das letzte Mal automatisch in der AdventureWorks-Datenbank gewachsen und wie lange hat es gedauert?
  • Wer hat die Tabelle dbo.EmployeeAuditData Wann gelöscht?
  • Wie viele Speicherfehler sind heute aufgetreten?

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

61
Aaron Bertrand

Es gibt eine Menge wertvoller Informationen, die SQL Server standardmäßig für Sie verfolgt. 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 system_health Ausgeführt.

Sie finden bestimmte Informationen auch im SQL Server-Fehlerprotokoll, im SQL Server-Agentenprotokoll, in Windows-Ereignisprotokollen und in der zusätzlichen Protokollierung unter anderem in SQL Server Audit , Management Data Warehouse , Ereignisbenachrichtigungen , DML-Trigger , DDL-Trigger , SCOM/System Center , Ihre eigenen serverseitigen Traces oder Erweiterte Ereignissitzungen 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, Sitzungen mit erweiterten Ereignissen und das Fehlerprotokoll.

Standard-Trace

Die Standardablaufverfolgung wird normalerweise auf den meisten Systemen ausgeführt, es sei denn, Sie haben mit sp_configure deaktiviert. Solange es aktiviert ist, kann dies eine reichhaltige Quelle wertvoller Informationen sein. Im Folgenden werden die erfassten Ablaufverfolgungsereignisse aufgelistet:

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 bei sys.trace_columns Verbinden, um zu sehen, welche Ereignisse mit welchen Daten verbunden sind. Ich werde dies jedoch vorerst überspringen, da Sie sehen können, was Sie haben, wenn Sie die Trace-Daten tatsächlich abfragen bestimmte Ereignisse. 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 derselbe Satz von Ereignissen in 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 die Standardablaufverfolgung Rollover-Dateien verwendet und die Ihnen zur Verfügung stehenden Daten nur so weit zurückreichen. Der Datumsbereich der verfügbaren Daten hängt davon ab, wie viele der oben genannten Ereignisse erfasst werden und mit welcher Häufigkeit. Wenn Sie sicherstellen möchten, dass Sie einen längeren Verlauf behalten, 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. Hier sind Beispielabfragen zum Abrufen dieser spezifischen Informationen aus der Standardablaufverfolgung.

Frage: Wann wurde das letzte Mal automatisch in der AdventureWorks-Datenbank gewachsen und wie lange hat es gedauert?

Diese Abfrage ruft alle AutoGrow-Ereignisse in der AdventureWorks-Datenbank ab, sowohl für Protokoll- als auch für Datendateien, die sich noch in den Standardprotokolldateien für die Ablaufverfolgung 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?

Dies gibt alle DROP Ereignisse für ein Objekt mit dem Namen EmployeeAuditData zurück. Wenn Sie sicherstellen möchten, dass nur DROP Ereignisse für Tabellen erkannt werden, können Sie einen Filter hinzufügen: ObjectType = 8277 (Die vollständige Liste ist hier dokumentiert ). Wenn Sie den Suchbereich auf eine bestimmte 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;

Hier gibt es eine Komplikation, und es ist sehr Edge-Fall, aber es hielt es für ratsam, es trotzdem zu erwähnen. Wenn Sie mehrere Schemas verwenden und möglicherweise denselben Objektnamen in mehreren Schemas haben, können Sie nicht erkennen, um welches es sich handelt (es sei denn, die Gegenstücke sind noch vorhanden). Es gibt einen externen Fall, in dem BenutzerA möglicherweise SchemaB.Tabellenname gelöscht hat, während BenutzerB möglicherweise SchemaA.Tabellenname gelöscht hat. Der Standard-Trace verfolgt weder das Schema des Objekts (noch erfasst er TextData für dieses Ereignis), das im Trace enthaltene ObjectID nicht nützlich für eine direkte Übereinstimmung (da das Objekt gelöscht wurde und nicht mehr existiert). Das Einfügen dieser Spalte in die Ausgabe in diesem Fall kann nützlich sein, um Querverweise auf Kopien der Tabelle mit demselben Namen zu erstellen, die noch vorhanden sind, wenn sich das System jedoch in dieser Unordnung befindet (oder wenn alle diese Kopien dort gelöscht wurden) Möglicherweise ist dies immer noch keine verlässliche Methode, um zu erraten, welche Kopie der Tabelle von wem abgelegt wurde.

Erweiterte Ereignisse

Von nterstützung von SQL Server 2008: Die system_health-Sitzung (SQLCSS-Blog) ist die folgende Liste von Daten, die Sie aus der system_health - Sitzung in SQL Server 2008 und 2008 R2 auswählen können:

  • Der sql_text und die session_id für alle Sitzungen, bei denen ein Fehler mit dem Schweregrad> = 20 auftritt
  • Der sql_text und die session_id für alle Sitzungen, bei denen ein Fehler vom Typ "Speicher" 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 Msg 17883 gesehen)
  • Alle erkannten Deadlocks
  • Der Callstack, sql_text und session_id für alle Sitzungen, die länger als 15 Sekunden auf Latches (oder andere interessante Ressourcen) gewartet haben
  • Der Callstack, sql_text und session_id für alle Sitzungen, die länger als 30 Sekunden auf Sperren gewartet haben
  • Der Callstack, sql_text und session_id für jede Sitzung, die über einen längeren Zeitraum auf "externe" oder "vorbeugende Wartezeiten" gewartet hat.

Ab Verwenden Sie die 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 speicherbezogener Fehler auftritt. Die Fehler umfassen 17803, 701, 802, 8645, 8651, 8657 und 8902.
  • Eine Aufzeichnung aller nicht nachgebenden Scheduler-Probleme. (Diese werden im SQL Server-Fehlerprotokoll als Fehler 17883 angezeigt.)
  • Alle erkannten Deadlocks.
  • Der Callstack, sql_text und session_id für alle Sitzungen, die länger als 15 Sekunden auf Latches (oder andere interessante Ressourcen) gewartet haben.
  • Der Callstack, sql_text und session_id für alle Sitzungen, die länger als 30 Sekunden auf Sperren gewartet haben.
  • Der Callstack, sql_text und session_id für alle Sitzungen, die lange auf präventive Wartezeiten gewartet haben. Die Dauer variiert je nach Wartetyp. Bei einer vorbeugenden Wartezeit wartet SQL Server auf externe API-Aufrufe.
  • Der Callstack und die session_id für CLR-Zuweisungen und virtuelle Zuordnungsfehler.
  • Die ring_buffer-Ereignisse für den Speicherbroker, den Scheduler-Monitor, den Speicherknoten-OOM, die Sicherheit und die Konnektivität.
  • Die Systemkomponente ergibt sich aus sp_server_diagnostics.
  • Instanzzustand, der von scheduler_monitor_system_health_ring_buffer_recorded erfasst wurde.
  • CLR-Zuordnungsfehler.
  • Konnektivitätsfehler mit Connectivity_ring_buffer_recorded.
  • Sicherheitsfehler bei Verwendung von security_error_ring_buffer_recorded.

In SQL Server 2016 werden zwei weitere Ereignisse erfasst:

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

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

Um die kryptischere Konfiguration für Ihre spezifische Version zu erhalten, können Sie die folgende Abfrage immer direkt ausführen. Sie müssen jedoch die Namen interpretieren und die Prädikate analysieren, um sie mit den oben aufgeführten Listen natürlicher 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 auch zwei neue Sitzungen ausgeführt: AlwaysOn_failover Und AlwaysOn_health. Sie können die von ihnen 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;

Diese Ereignissitzungen verwenden Ringpufferziele zum Speichern der Daten, sodass ältere Ereignisse - wie der Pufferpool und der Plan-Cache - auslaufen, sodass Sie Ereignisse nicht unbedingt 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 keine sehr effiziente), die diese Informationen aus der Sitzung system_health Abrufen kann:

;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 stammt lose aus Amit Banerjees einleitendem Blog-Beitrag zur system_health - Sitzung .)

Weitere Informationen zu erweiterten Ereignissen (einschließlich vieler Beispiele, in denen Sie nach bestimmten Daten abfragen können) finden Sie in dieser 31-teiligen Blogserie 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 (aber Sie können dies ändern ). Dort werden zahlreiche Informationen gespeichert, einschließlich Startinformationen (wie viele Kerne verwendet werden, ob Sperrseiten im Speicher festgelegt sind, Authentifizierungsmodus usw.) sowie Fehler und andere Szenarien, die schwerwiegend genug sind, um dokumentiert zu werden (und nicht an anderer Stelle erfasst zu werden). Ein aktuelles Beispiel war jemand, der suchte, als eine Datenbank offline geschaltet wurde. Sie können dies feststellen, indem Sie jedes der letzten 7 Fehlerprotokolle nach dem Text Setting database option OFFLINE Durchsuchen:

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 einige andere Details behandelt in dieser jüngsten Antwort , und es gibt auch einige gute Hintergrundinformationen bei toadworld und auch in der offiziellen Dokumentation .

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

66
Aaron Bertrand