sql >> Database teknologi >  >> RDS >> Database

Forstå hændelsestab med udvidede hændelser

Min kollega, Erin Stellato, stillede mig for nylig et spørgsmål om, hvor og hvorfor tab af begivenheder kunne ske med Extended Events. Spørgsmålet var resultatet af en kommentar, som nogen havde lavet på et af hendes blogindlæg, der hævdede, at showplan_xml begivenheder kan ikke indsamles af XE Profiler eller gennem en "live" stream af begivenhederne fra serveren. Jeg ved tilfældigvis, at dette ikke er korrekt, fordi jeg rutinemæssigt har demonstreret de negative præstationspåvirkninger af at bruge post_query_execution_showplan-begivenheden mod en produktionsbelastning ved at tilføje hændelsen i brugergrænsefladen og få den til at se live-dataene, så dette startede en mere dybdegående diskussion om hvordan og hvornår Extended Events vil kassere en hændelse, der er blevet genereret under dataindsamlingen.

Begivenhedens størrelse betyder noget

Extended Events konfigurerer intern hukommelsesbufferplads for en hændelsessession, når den startes på serveren, og konfigurationen af ​​hændelsessessionsindstillingerne bestemmer, hvor store hukommelsesbufferne er, og den maksimale størrelse hændelse, som hændelsessessionen kan indsamle. Mens de fleste hændelser genereret af udvidede hændelser er relativt lette og små i binært format, kan specifikke hændelser generere en meget større nyttelast af data, som skal bufferes. Standardhændelsessessionsindstillingerne resulterer i en sessionskonfiguration med tre interne hukommelsesbuffere til at holde hændelser, der er 1.441.587 bytes store. Størrelsen og antallet af hukommelsesbuffere for en begivenhedssession kan findes i sys.dm_xe_sessions DMV, mens sessionen STATE=START på serveren:

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

Bemærk, at der er nul store buffere for hver af de systemdefinerede hændelsessessioner, og den store bufferstørrelse er også sat til nul, hvilket er standardkonfigurationen. De store buffere for en begivenhedssession oprettes kun, når sessionsindstillingen MAX_EVENT_SIZE er konfigureret til begivenhedssessionen. Standardværdien for denne indstilling er 0, hvilket betyder, at den største hændelse, begivenhedssessionen faktisk kan forbruge, er størrelsen af ​​en almindelig hukommelsesbuffer, som er 1.441.587 bytes. For visse begivenheder, som dem, der producerer showplan_xml, er det faktisk relativt nemt at have en begivenhedsstørrelse, der er større end standard hukommelsesbufferstørrelsen for begivenhedssessionen. I disse tilfælde ville den store hændelse faktisk blive kasseret af hændelsessessionen, da den ikke kan placeres i en hukommelsesbuffer til afsendelse.

Kontrol af hændelsestab

Der er tre specifikke sessionsmuligheder, der bestemmer, hvor stor en begivenhed en begivenhedssession faktisk kan indsamle, og en, der styrer, hvordan begivenheder droppes, når bufferhukommelsen for begivenhedssessionen er fuld eller under pres. Alle disse fire har betydning, når vi taler om at indsamle begivenheder, der kunne generere en stor begivenhedsnyttelast, og vi ønsker at minimere chancen for, at vi potentielt kan droppe en begivenhed. Et eksempel på hændelsessession, der ville være tilbøjelig til hændelsestab på grund af hukommelsestryk i bufferpladsen for hændelsessessionen, er nedenfor:

OPRET EVENT SESSION [Låse] PÅ SERVER TILFØJ BEGIVENHED sqlserver.lock_acquired,ADD EVENT sqlserver.lock_releasedADD TARGET package0.event_file(SET filename=N'Locks',max_file_size=(5),max_rollover_MERY=(MAX_4)_MERY==4096 KB,MEMORY_PARTITION_MODE=INGEN,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_EVENT_SIZE=0 KB);

Bemærk:Dette er ikke en begivenhedssession, som jeg nogensinde vil anbefale at køre på en produktionsarbejdsbelastning – mængden af ​​data, den ville generere, ville være betydelig, da den sporer hver låseoptagelse og frigivelse.

Hvis vi starter denne session og derefter kører AdventureWorks Books Online Workload-generatoren, der er tilgængelig på min blog mod en forekomst af SQL Server, vil sessionen hurtigt begynde at droppe hændelser på grund af den hurtige hændelsesgenerering og forsinkelsen i buffer-flushing til event_file-målet der er konfigureret. Antallet af hændelser, der er blevet droppet af en hændelsessession, kan spores i sys.dm_xe_sessions DMV, hvis hændelsessessionsindstillingerne er blevet konfigureret med EVENT_RETENTION_MODE =ALLOW_SINGLE_EVENT_LOSS. Hvis hændelsessessionen er konfigureret med EVENT_RETENTION_MODE=ALLOW_MULTIPLE_EVENT_LOSS, kan hele hukommelsesbuffere af hændelser slettes, og den tæller kun, hvor mange buffere der blev slettet og ikke antallet af individuelle hændelser, hver buffer indeholdt.

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_event_dropped_size_size_s. 

Her kan vi se, at 100.521 hændelser blev droppet, og den største størrelse af en hændelse, der blev droppet, var 176 bytes, hvilket er mindre end størrelsen af ​​vores almindelige bufferplads, så vi rammer bare normalt bufferhukommelsespladstryk. Men hvis vi opretter en begivenhedssession, der samler de to af showplan-begivenhederne (se denne artikel for, hvorfor dette vil påvirke ydeevnen negativt og ikke bør udføres på produktionsservere), sammen med batchstart- og afsluttede begivenheder og generere nogle større planer, kan vi udløse begivenhedstab på grund af begivenhedens størrelse.

OPRET EVENT SESSION [DropsEvents] PÅ SERVER TILFØJ BEGIVENHED sqlserver.query_post_execution_showplan,ADD EVENT sqlserver.query_pre_execution_showplan,ADD EVENT sqlserver.sql_batch_completed,ADD_server EVENT; 

Her kan vi se, at den største_event_dropped_size er større end vores regular_buffer_size, så det betyder, at vi skal ændre konfigurationen af ​​vores sessionsbuffere. Hvis vi øger MAX_MEMORY for begivenhedssessionen, kan det øge størrelsen af ​​vores almindelige buffere. Standardværdien er kun 4MB, hvilket er hvor bufferstørrelsen på 1,4MB vist ovenfor kommer fra. Hvis vi ændrer dette til at være 64 MB for begivenhedssessionen, vil regular_buffer_size være 22,4 MB i størrelse, hvilket ville rumme vores 3,7 MB droppede begivenhed. Den anden mulighed er at indstille indstillingen MAX_EVENT_SIZE, som giver large_buffer_size til store begivenheder og divideres med to for sessionen.

 Opret begivenhedssession [CollectSEvents] på server Tilføj begivenhed SQLServer.Query_Post_Execution_Showplan, Tilføj begivenhed SQLServer.Query_pre_execution_showplan, Tilføj begivenhed SqlServer.sql_batch_completed, tilføj begivenhed sqlserver.sql_batch_startingwith (max_ (maxMory =

Så her kan vi se de to store buffere med en størrelse på 33,6 MB, og efter at have kørt den samme plan, der genererer arbejdsbelastning igen, har vi ingen droppede hændelser for vores nye CollectsEvents-session, men vi har fordoblet de droppede hændelser for vores DropsEvents-session ved at bruge standardindstillingerne.

Så der har du det; hvorfor visse hændelser muligvis ikke indsamles af en hændelsessession, hvordan man går til fejlfinding, når hændelser bliver droppet, og hvordan man afgør, om det er størrelsen af ​​hændelsen, der forårsager problemet. Mange af de sessioner, som jeg ser i faktisk brug på klientsystemer, har standardindstillingerne for begivenhedssessionsmuligheder, især når det kommer til hukommelse. Dette er et område, hvor du, når du først forstår buffermekanismen brugt af udvidede hændelser, og derefter overvejer størrelsen af ​​de hændelser, der potentielt kan genereres, vil du begynde at foretage ændringer i, hvordan sessionsmulighederne er defineret for at minimere potentialet for hændelser slettes på grund af begrænsninger i hukommelsesplads eller begrænsninger af hændelsesstørrelse.


  1. Typekonvertering. Hvad gør jeg med en PostgreSQL OID-værdi i libpq i C?

  2. JPA flush vs commit

  3. Sammenlign to MySQL-databaser

  4. Fjern dubletter fra Count()-resultater i SQLite