Database
 sql >> Datenbank >  >> RDS >> Database

Ereignisverlust bei erweiterten Ereignissen verstehen

Meine Kollegin Erin Stellato hat mir kürzlich eine Frage gestellt, wo und warum Ereignisverluste bei erweiterten Ereignissen auftreten können. Die Frage war das Ergebnis eines Kommentars, den jemand in einem ihrer Blogposts gemacht hatte und in dem behauptet wurde, dass showplan_xml Ereignisse können nicht vom XE Profiler oder über einen „Live“-Stream der Ereignisse vom Server erfasst werden. Ich weiß zufällig, dass dies nicht korrekt ist, da ich routinemäßig die negativen Auswirkungen auf die Leistung der Verwendung des post_query_execution_showplan-Ereignisses für eine Produktionsworkload demonstriert habe, indem ich das Ereignis in der Benutzeroberfläche hinzugefügt und die Live-Daten überwacht habe, sodass dies eine eingehendere Diskussion auslöste darüber, wie und wann erweiterte Ereignisse ein Ereignis verwerfen, das während der Datenerfassung generiert wurde.

Event-Größe ist wichtig

Erweiterte Ereignisse konfiguriert den internen Pufferspeicherplatz für eine Ereignissitzung, wenn sie zum ersten Mal auf dem Server gestartet wird, und die Konfiguration der Ereignissitzungsoptionen bestimmt, wie groß die Speicherpuffer sind und wie groß das Ereignis, das die Ereignissitzung erfassen kann, maximal ist. Während die meisten von Extended Events generierten Ereignisse im Binärformat relativ leichtgewichtig und klein sind, können bestimmte Ereignisse eine viel größere Nutzlast von Daten erzeugen, die gepuffert werden müssen. Die Standardoptionen für Ereignissitzungen führen zu einer Sitzungskonfiguration mit drei internen Speicherpuffern zum Speichern von Ereignissen mit einer Größe von 1.441.587 Byte. Die Größe und Anzahl der Speicherpuffer für eine Ereignissitzung kann in der DMV sys.dm_xe_sessions gefunden werden, während die Sitzung STATE=START auf dem Server ist:

SELECT
    s.name, 
    s.total_regular_buffers,
    s.regular_buffer_size,
    s.total_large_buffers,
    s.large_buffer_size,
    s.total_buffer_size
FROM sys.dm_xe_sessions AS s;

Beachten Sie, dass es für jede vom System definierte Ereignissitzung null große Puffer gibt und dass die Größe des großen Puffers ebenfalls auf null gesetzt ist, was die Standardkonfiguration ist. Die großen Puffer für eine Ereignissitzung werden nur erstellt, wenn die Sitzungsoption MAX_EVENT_SIZE für die Ereignissitzung konfiguriert ist. Der Standardwert für diese Option ist 0, was bedeutet, dass das größte Ereignis, das die Ereignissitzung tatsächlich verbrauchen kann, die Größe eines regulären Speicherpuffers ist, der 1.441.587 Byte beträgt. Bei bestimmten Ereignissen, wie denen, die showplan_xml erzeugen, ist es eigentlich relativ einfach, eine Ereignisgröße zu haben, die größer ist als die Standardspeicherpuffergröße für die Ereignissitzung. In diesen Fällen würde das große Ereignis tatsächlich von der Ereignissitzung verworfen, da es nicht in einen Speicherpuffer zum Versenden gestellt werden kann.

Kontrolle des Ereignisverlusts

Es gibt drei spezifische Sitzungsoptionen, die bestimmen, wie groß ein Ereignis in einer Ereignissitzung tatsächlich erfasst werden kann, und eine, die steuert, wie Ereignisse gelöscht werden, wenn der Pufferspeicher für die Ereignissitzung voll oder unter Druck ist. Alle vier sind wichtig, wenn wir über das Sammeln von Ereignissen sprechen, die eine große Ereignisnutzlast generieren könnten, und wir die Wahrscheinlichkeit minimieren möchten, dass wir möglicherweise ein Ereignis löschen. Nachfolgend finden Sie ein Beispiel für eine Ereignissitzung, die aufgrund von Speichermangel im Pufferspeicher für die Ereignissitzung anfällig für Ereignisverluste wäre:

CREATE EVENT SESSION [Locks] ON SERVER 
ADD EVENT sqlserver.lock_acquired,
ADD EVENT sqlserver.lock_released
ADD TARGET package0.event_file(SET filename=N'Locks',max_file_size=(5),max_rollover_files=(4))
WITH (MAX_MEMORY=4096 KB,
MEMORY_PARTITION_MODE=NONE,
EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
MAX_EVENT_SIZE=0 KB);

Hinweis:Dies ist keine Ereignissitzung, die ich jemals empfehlen würde, auf einer Produktions-Workload ausgeführt zu werden – die Menge an Daten, die sie generieren würde, wäre erheblich, da sie jeden Lock-Erwerb und -Freigabe verfolgt.

Wenn wir diese Sitzung starten und dann den AdventureWorks Books Online Workload-Generator, der in meinem Blog verfügbar ist, für eine Instanz von SQL Server ausführen, beginnt die Sitzung aufgrund der schnellen Ereignisgenerierung und der Verzögerung beim Leeren des Puffers in das Ziel „event_file“ schnell mit dem Löschen von Ereignissen das ist konfiguriert. Die Anzahl der Ereignisse, die von einer Ereignissitzung gelöscht wurden, kann in der DMV sys.dm_xe_sessions nachverfolgt werden, wenn die Ereignissitzungsoptionen mit EVENT_RETENTION_MODE =ALLOW_SINGLE_EVENT_LOSS konfiguriert wurden. Wenn die Ereignissitzung mit EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS konfiguriert ist, können ganze Speicherpuffer von Ereignissen gelöscht werden und es wird nur gezählt, wie viele Puffer gelöscht wurden und nicht die Anzahl der einzelnen Ereignisse, die jeder Puffer enthielt.

SELECT
   s.name, 
   s.total_regular_buffers,
   s.regular_buffer_size,
   s.total_large_buffers,
   s.large_buffer_size,
   s.dropped_event_count,
   s.dropped_buffer_count,
   s.largest_event_dropped_size
FROM sys.dm_xe_sessions AS s;

Hier können wir sehen, dass 100.521 Ereignisse verworfen wurden und die größte Größe eines verworfenen Ereignisses 176 Byte betrug, was kleiner ist als die Größe unseres regulären Pufferspeicherplatzes, sodass wir nur den normalen Pufferspeicherplatzdruck erreichen. Wenn wir jedoch eine Ereignissitzung erstellen, die die beiden showplan-Ereignisse sammelt (lesen Sie diesen Artikel, warum dies die Leistung stark beeinträchtigen wird und nicht auf Produktionsservern durchgeführt werden sollte), zusammen mit den Batch-Start- und -Abgeschlossen-Ereignissen, und generieren Sie einige größere Pläne, können wir aufgrund der Ereignisgröße einen Ereignisverlust auslösen.

CREATE EVENT SESSION [DropsEvents] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan,
ADD EVENT sqlserver.query_pre_execution_showplan,
ADD EVENT sqlserver.sql_batch_completed,
ADD EVENT sqlserver.sql_batch_starting;

Hier können wir sehen, dass „largest_event_dropped_size“ größer ist als unsere „regular_buffer_size“, was bedeutet, dass wir die Konfiguration unserer Sitzungspuffer ändern müssen. Wenn wir MAX_MEMORY für die Ereignissitzung erhöhen, kann dies die Größe unserer regulären Puffer erhöhen. Der Standardwert beträgt nur 4 MB, daher kommt die oben gezeigte Puffergröße von 1,4 MB. Wenn wir dies für die Ereignissitzung auf 64 MB ändern, wird die regular_buffer_size 22,4 MB groß sein, was unserem gelöschten Ereignis von 3,7 MB Platz bieten würde. Die andere Option besteht darin, die Option MAX_EVENT_SIZE festzulegen, die die large_buffer_size für große Ereignisse bereitstellt und für die Sitzung durch zwei geteilt wird.

CREATE EVENT SESSION [CollectsEvents] ON SERVER 
ADD EVENT sqlserver.query_post_execution_showplan,
ADD EVENT sqlserver.query_pre_execution_showplan,
ADD EVENT sqlserver.sql_batch_completed,
ADD EVENT sqlserver.sql_batch_starting
WITH (MAX_MEMORY=65536 KB,MAX_EVENT_SIZE=65536 KB,MEMORY_PARTITION_MODE=NONE);

Hier können wir also die beiden großen Puffer mit einer Größe von 33,6 MB sehen, und nachdem wir denselben Plan erneut ausgeführt haben, der Workload generiert, haben wir keine gelöschten Ereignisse für unsere neue CollectsEvents-Sitzung, aber wir haben die gelöschten Ereignisse für unsere DropsEvents-Sitzung unter Verwendung der Standardeinstellungen verdoppelt.

Da haben Sie es also; Warum bestimmte Ereignisse möglicherweise nicht von einer Ereignissitzung erfasst werden, wie Sie bei der Fehlerbehebung vorgehen, wenn Ereignisse gelöscht werden, und wie Sie feststellen können, ob die Größe des Ereignisses das Problem verursacht. Viele der Sitzungen, die ich in der tatsächlichen Verwendung auf Client-Systemen sehe, haben die Standardeinstellungen für Ereignissitzungsoptionen, insbesondere wenn es um Speicher geht. Dies ist ein Bereich, in dem Sie, sobald Sie den von Extended Events verwendeten Puffermechanismus verstehen und dann die Größe der möglicherweise generierten Ereignisse berücksichtigen, Änderungen an der Definition der Sitzungsoptionen vornehmen werden, um das Potenzial für Ereignisse zu minimieren aufgrund von Speicherplatzbeschränkungen oder Beschränkungen der Ereignisgröße gelöscht werden.