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

Observer Overhead og Vent Type Symptomer

Mange mennesker bruger ventestatistikker som en del af deres overordnede præstationsfejlfindingsmetode, og det samme gør jeg, så spørgsmålet, jeg ønskede at udforske i dette indlæg, er omkring ventetyper forbundet med observatør-overhead. Med observatør-overhead mener jeg indvirkningen på SQL Server-arbejdsbelastningsgennemstrømning forårsaget af SQL Profiler, sporing på serversiden eller udvidede hændelsessessioner. For mere om emnet observatør overhead, se følgende to indlæg fra min kollega Jonathan Kehayias :

  • Måling af "Observer Overhead" af SQL Trace vs. udvidede hændelser
  • Konsekvensen af ​​query_post_execution_showplan Extended Event i SQL Server 2012

Så i dette indlæg vil jeg gerne gå gennem et par variationer af observatør overhead og se, om vi kan finde konsistente ventetyper forbundet med den målte nedbrydning. Der er en række måder, hvorpå SQL Server-brugere implementerer sporing i deres produktionsmiljøer, så dine resultater kan variere, men jeg ville gerne dække et par brede kategorier og rapportere tilbage om, hvad jeg fandt:

  • SQL Profiler session brug
  • Spor brug på serversiden
  • Spor brug på serversiden, skrivning til en langsom I/O-sti
  • Udvidet hændelsesbrug med et ringbuffermål
  • Udvidet hændelsesbrug med et filmål
  • Udvidet hændelsesbrug med et filmål på en langsom I/O-sti
  • Udvidet hændelsesbrug med et filmål på en langsom I/O-sti uden tab af hændelser

Du kan sandsynligvis finde på andre varianter af temaet, og jeg inviterer dig til at dele eventuelle interessante resultater vedrørende observatør-overhead og ventestatistikker som en kommentar i dette indlæg.

Basislinje

Til testen brugte jeg en virtuel VMware-maskine med fire vCPU'er og 4 GB RAM. Min virtuelle maskine-gæst var på OCZ Vertex SSD'er. Operativsystemet var Windows Server 2008 R2 Enterprise, og versionen af ​​SQL Server er 2012, SP1 CU4.

Med hensyn til "arbejdsbyrden" bruger jeg en skrivebeskyttet forespørgsel i en løkke mod 2008-kreditprøvedatabasen, indstillet til GO 10.000.000 gange.

USE [Credit];
GO
 
SELECT TOP 1 
     [member].[member_no],
     [member].[lastname],
     [payment].[payment_no],
     [payment].[payment_dt],
     [payment].[payment_amt]
FROM [dbo].[payment]
INNER JOIN [dbo].[member]
ON [member].[member_no] = [payment].[member_no];
GO 10000000

Jeg udfører også denne forespørgsel via 16 samtidige sessioner. Slutresultatet på mit testsystem er 100 % CPU-udnyttelse på tværs af alle vCPU'er på den virtuelle gæst og et gennemsnit på 14.492 batch-anmodninger pr. sekund over en periode på 2 minutter.

Med hensyn til hændelsessporingen brugte jeg i hver test Showplan XML Statistics Profile til SQL Profiler og Server-side sporingstests – og query_post_execution_showplan til udvidede begivenhedssessioner. Udførelsesplanhændelser er meget dyre, og det er netop derfor, jeg valgte dem, så jeg kunne se, om jeg under ekstreme omstændigheder kunne udlede ventetype-temaer eller ej.

Til at teste ventetypeakkumulering over en testperiode brugte jeg følgende forespørgsel. Ikke noget fancy – bare at rydde statistikken, vente 2 minutter og derefter indsamle de 10 bedste venteakkumuleringer for SQL Server-forekomsten i løbet af nedbrydningstestperioden:

-- Clearing the wait stats
 
DBCC SQLPERF('waitstats', clear);
 
WAITFOR DELAY '00:02:00';
GO
 
SELECT TOP 10
     [wait_type],
     [waiting_tasks_count],
     [wait_time_ms]
FROM sys.[dm_os_wait_stats] AS [ws]
ORDER BY [wait_time_ms] DESC;

Bemærk, at jeg er ikke frafiltrering af baggrundsventetyper, der typisk er filtreret fra, og det skyldes, at jeg ikke ønskede at fjerne noget, der normalt er godartet – men i denne omstændighed faktisk peger på et reelt område at undersøge nærmere.

SQL Profiler Session

Følgende tabel viser før-og-efter batch-anmodninger pr. sekund, når du aktiverer en lokal SQL Profiler-sporingssporing Showplan XML Statistics Profile (kører på samme VM som SQL Server-instansen):

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Session Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 1.416

Du kan se, at SQL Profiler-sporingen forårsager et betydeligt fald i gennemløbet.

Hvad angår akkumuleret ventetid i samme periode, var de øverste ventetyper som følger (som med resten af ​​testene i denne artikel, lavede jeg et par testkørsler, og outputtet var generelt konsistent):

wait_type waiting_tasks_count ventetid_ms
TRACEWRITE 67.142 1.149.824
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237.003
SLEEP_TASK 313 180.449
REQUEST_FOR_DEADLOCK_SEARCH 24 120.111
HADR_FILESTREAM_IOMGR_IOCOMPLETION 240 120.086
LAZYWRITER_SLEEP 120 120.059
DIRTY_PAGE_POLL 1.198 120.038
HADR_WORK_QUEUE 12 120.015
LOGMGR_QUEUE 937 120.011
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120.006

Ventetypen, der springer ud for mig, er TRACEWRITE – som er defineret af Books Online som en ventetype, der "opstår, når SQL Trace-rækkesæt-sporingsudbyderen venter på enten en ledig buffer eller en buffer med hændelser, der skal behandles". Resten af ​​ventetyperne ligner standardbaggrundsventetyper, som man typisk ville filtrere fra dit resultatsæt. Desuden talte jeg om et lignende problem med oversporing i en artikel tilbage i 2011 kaldet Observer overhead - farerne ved for meget sporing - så jeg var bekendt med denne ventetype nogle gange korrekt peger på observatør overhead problemer. Nu i det særlige tilfælde, jeg bloggede om, var det ikke SQL Profiler, men et andet program, der bruger rækkesættets sporingsudbyder (ineffektivt).

Sporing på serversiden

Det var til SQL Profiler, men hvad med sporingsoverhead på serversiden? Følgende tabel viser før-og-efter batch-anmodninger pr. sekund, når du aktiverer en lokal server-side-sporingsskrivning til en fil:

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 4.015

De øverste ventetyper var som følger (jeg lavede et par testkørsler, og outputtet var konsistent):

wait_type waiting_tasks_count ventetid_ms
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237.015
SLEEP_TASK 253 180.871
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120.046
HADR_WORK_QUEUE 12 120.042
REQUEST_FOR_DEADLOCK_SEARCH 24 120.021
XE_DISPATCHER_WAIT 3 120.006
VENT 1 120.000
LOGMGR_QUEUE 931 119.993
DIRTY_PAGE_POLL 1.193 119.958
XE_TIMER_EVENT 55 119.954

Denne gang ser vi ikke TRACEWRITE (vi bruger en filudbyder nu) og den anden sporingsrelaterede ventetype, den udokumenterede SQLTRACE_INCREMENTAL_FLUSH_SLEEP klatrede op – men har i sammenligning med den første test meget lignende akkumuleret ventetid (120.046 vs. 120.006) – og min kollega Erin Stellato (@erinstellato) talte om denne særlige ventetype i sit indlæg Finding Out When Wait Statistics Were Last Cleared . Så ser man på de andre ventetyper, er der ingen, der springer ud som et pålideligt rødt flag.

Server-Side Trace-skrivning til en langsom I/O-sti

Hvad hvis vi lægger sporingsfilen på serversiden på langsom disk? Følgende tabel viser før-og-efter batch-anmodninger pr. sekund, når du aktiverer en lokal server-side-sporing, der skriver til en fil på en USB-stick:

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 260

Som vi kan se – er ydeevnen væsentligt forringet – selv sammenlignet med den tidligere test.

De bedste ventetyper var som følger:

wait_type waiting_tasks_count ventetid_ms
SQLTRACE_FILE_BUFFER 357 351.174
SP_SERVER_DIAGNOSTICS_SLEEP 2.273 299.995
SLEEP_TASK 240 194.264
FT_IFTS_SCHEDULER_IDLE_WAIT 2 181.458
REQUEST_FOR_DEADLOCK_SEARCH 25 125.007
LAZYWRITER_SLEEP 63 124.437
LOGMGR_QUEUE 941 120.559
HADR_FILESTREAM_IOMGR_IOCOMPLETION 67 120.516
VENT 1 120.515
DIRTY_PAGE_POLL 1.204 120.513

En ventetype, der springer ud for denne test, er den udokumenterede SQLTRACE_FILE_BUFFER . Ikke meget dokumenteret på denne, men baseret på navnet kan vi lave et kvalificeret gæt (især i betragtning af denne særlige tests konfiguration).

Udvidede hændelser til ringbuffermålet

Lad os derefter gennemgå resultaterne for ækvivalenter til udvidede begivenhedssessioner. Jeg brugte følgende sessionsdefinition:

CREATE EVENT SESSION [ApplicationXYZ] ON SERVER
  ADD EVENT sqlserver.query_post_execution_showplan,
  ADD TARGET package0.ring_buffer(SET max_events_limit=(1000))
  WITH (STARTUP_STATE=ON);
GO

Følgende tabel viser før-og-efter batch-anmodninger pr. sekund, når en XE-session aktiveres med et ringbuffermål (fanger query_post_execution_showplan begivenhed):

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 4.737

De bedste ventetyper var som følger:

wait_type waiting_tasks_count ventetid_ms
SP_SERVER_DIAGNOSTICS_SLEEP 612 299.992
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237.006
SLEEP_TASK 240 181.739
LAZYWRITER_SLEEP 120 120.219
HADR_WORK_QUEUE 12 120.038
DIRTY_PAGE_POLL 1.198 120.035
REQUEST_FOR_DEADLOCK_SEARCH 24 120.017
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120.011
LOGMGR_QUEUE 936 120.008
VENT 1 120.001

Intet sprang ud som XE-relateret, kun baggrundsopgave "støj".

Udvidede hændelser til et filmål

Hvad med at ændre sessionen til at bruge et filmål i stedet for et ringbuffermål? Følgende tabel viser før-og-efter batch-anmodninger pr. sekund, når en XE-session aktiveres med et filmål i stedet for et ringbuffermål:

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 4.299

De bedste ventetyper var som følger:

wait_type waiting_tasks_count ventetid_ms
SP_SERVER_DIAGNOSTICS_SLEEP 2.103 299.996
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237.003
SLEEP_TASK 253 180.663
LAZYWRITER_SLEEP 120 120.187
HADR_WORK_QUEUE 12 120.029
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120.019
REQUEST_FOR_DEADLOCK_SEARCH 24 120.011
VENT 1 120.001
XE_TIMER_EVENT 59 119.966
LOGMGR_QUEUE 935 119.957

Intet, med undtagelse af XE_TIMER_EVENT , sprang ud som XE-relateret. Bob Wards Wait Type Repository omtaler dette som sikkert at ignorere, medmindre der var noget muligt galt - men realistisk set ville du bemærke denne normalt godartede ventetype, hvis den var på 9-pladsen på dit system under en ydeevneforringelse? Og hvad hvis du allerede filtrerer det fra på grund af dets normalt godartede natur?

Udvidede hændelser til et langsom I/O-stifilmål

Hvad nu hvis jeg lægger filen på en langsom I/O-sti? Følgende tabel viser før- og efter batch-anmodninger pr. sekund, når en XE-session aktiveres med et filmål på en USB-stick:

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 4.386

De bedste ventetyper var som følger:

wait_type waiting_tasks_count ventetid_ms
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237.046
SLEEP_TASK 253 180.719
HADR_FILESTREAM_IOMGR_IOCOMPLETION 240 120.427
LAZYWRITER_SLEEP 120 120.190
HADR_WORK_QUEUE 12 120.025
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120.013
REQUEST_FOR_DEADLOCK_SEARCH 24 120.011
VENT 1 120.002
DIRTY_PAGE_POLL 1.197 119.977
XE_TIMER_EVENT 59 119.949

Igen, intet XE-relateret springer ud bortset fra XE_TIMER_EVENT .

Udvidede hændelser til et langsom I/O-stifilmål, ingen hændelsestab

Følgende tabel viser før-og-efter batch-anmodninger pr. sekund, når du aktiverer en XE-session med et filmål på en USB-stick, men denne gang uden at tillade tab af hændelse (EVENT_RETENTION_MODE=NO_EVENT_LOSS) – hvilket ikke anbefales, og du vil se i resultaterne, hvorfor det kunne være:

Baseline Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
SQL Profiler Batch-anmodninger pr. sekund
(2 minutters gennemsnit)
14.492 539

De bedste ventetyper var som følger:

wait_type waiting_tasks_count ventetid_ms
XE_BUFFERMGR_FREEBUF_EVENT 8.773 1.707.845
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237.003
SLEEP_TASK 337 180.446
LAZYWRITER_SLEEP 120 120.032
DIRTY_PAGE_POLL 1.198 120.026
HADR_WORK_QUEUE 12 120.009
REQUEST_FOR_DEADLOCK_SEARCH 24 120.007
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120.006
VENT 1 120.000
XE_TIMER_EVENT 59 119.944

Med den ekstreme gennemløbsreduktion ser vi XE_BUFFERMGR_FREEBUF_EVENT spring til nummer et på vores akkumulerede ventetidsresultater. Denne er dokumenteret i Books Online, og Microsoft fortæller os, at denne hændelse er forbundet med XE-sessioner, der er konfigureret til ingen tab af hændelser, og hvor alle buffere i sessionen er fulde.

Observatørpåvirkning

Bortset fra ventetyper var det interessant at bemærke, hvilken indflydelse hver observationsmetode havde på vores arbejdsbyrdes evne til at behandle batch-anmodninger:


Indvirkning af forskellige observationsmetoder på batch-anmodninger pr. sekund

For alle tilgange var der et signifikant – men ikke chokerende – hit sammenlignet med vores baseline (ingen observation); den største smerte føltes dog ved brug af Profiler, når man brugte Server-Side Trace til en langsom I/O-sti eller udvidede hændelser til et filmål på en langsom I/O-sti – men kun når den var konfigureret til ingen hændelsestab. Med tab af hændelser fungerede denne opsætning faktisk på niveau med et filmål til en hurtig I/O-sti, formentlig fordi den var i stand til at droppe mange flere hændelser.

Oversigt

Jeg testede ikke alle mulige scenarier, og der er helt sikkert andre interessante kombinationer (for ikke at nævne forskellig adfærd baseret på SQL Server-versionen), men den vigtigste konklusion, jeg tager med fra denne udforskning, er, at du ikke altid kan stole på en åbenlys ventetype-akkumulering pointer, når du står over for et observatør overhead-scenarie. Baseret på testene i dette indlæg manifesterede kun tre ud af syv scenarier en specifik ventetype, der potentielt kunne hjælpe med at pege dig i den rigtige retning. Selv dengang – disse tests var på et kontrolleret system – og ofte filtrerer folk de førnævnte ventetyper fra som godartede baggrundstyper – så du måske slet ikke ser dem.

I betragtning af dette, hvad kan du gøre? For ydeevneforringelse uden klare eller tydelige symptomer anbefaler jeg at udvide omfanget for at spørge om spor og XE-sessioner (som en side – jeg anbefaler også at udvide dit omfang, hvis systemet er virtualiseret eller kan have forkerte strømindstillinger). For eksempel, som en del af fejlfinding af et system, skal du kontrollere sys.[traces] og sys.[dm_xe_sessions] for at se, om der kører noget på systemet, som er uventet. Det er et ekstra lag til det, du skal bekymre dig om, men at udføre et par hurtige valideringer kan spare dig en betydelig mængde tid.


  1. Hvordan opdateres JPA-enheder, når backend-databasen ændres asynkront?

  2. Hvordan finder jeg ud af, om en oracle-database er indstillet til autocommit?

  3. Opret en midlertidig tabel i SQLite

  4. Forbindelseshåndtering og drosling med ProxySQL