sql >> Database >  >> RDS >> Database

Observer Overhead en wachttype Symptomen

Veel mensen gebruiken wachtstatistieken als onderdeel van hun algemene methodologie voor het oplossen van prestaties, net als ik, dus de vraag die ik in dit bericht wilde onderzoeken, gaat over wachttypen die verband houden met de overhead van de waarnemer. Met waarnemersoverhead bedoel ik de impact op de werkbelasting van SQL Server die wordt veroorzaakt door SQL Profiler, server-side traces of Extended Event-sessies. Zie de volgende twee berichten van mijn collega Jonathan Kehayias voor meer informatie over de overhead van waarnemers :

  • Meten "Observer Overhead" van SQL Trace versus uitgebreide gebeurtenissen
  • Impact van de query_post_execution_showplan Extended Event in SQL Server 2012

Dus in dit bericht zou ik graag een paar variaties van waarnemersoverhead willen doorlopen en kijken of we consistente wachttypen kunnen vinden die verband houden met de gemeten degradatie. Er zijn verschillende manieren waarop SQL Server-gebruikers tracering in hun productieomgevingen implementeren, dus uw resultaten kunnen variëren, maar ik wilde een paar brede categorieën behandelen en verslag uitbrengen over wat ik heb gevonden:

  • SQL Profiler-sessiegebruik
  • Gebruik tracering aan serverzijde
  • Traceergebruik aan serverzijde, schrijven naar een langzaam I/O-pad
  • Uitgebreid gebruik van gebeurtenissen met een ringbufferdoel
  • Uitgebreid gebruik van gebeurtenissen met een bestandsdoel
  • Uitgebreid gebruik van gebeurtenissen met een bestandsdoel op een langzaam I/O-pad
  • Uitgebreid gebruik van gebeurtenissen met een bestandsdoel op een langzaam I/O-pad zonder verlies van gebeurtenissen

Je kunt waarschijnlijk andere variaties op het thema bedenken en ik nodig je uit om eventuele interessante bevindingen met betrekking tot de overhead van waarnemers en wachtstatistieken als commentaar in dit bericht te delen.

Basislijn

Voor de test gebruikte ik een virtuele VMware-machine met vier vCPU's en 4 GB RAM. Mijn gast op de virtuele machine was op OCZ Vertex SSD's. Het besturingssysteem was Windows Server 2008 R2 Enterprise en de versie van SQL Server is 2012, SP1 CU4.

Wat betreft de "werklast" gebruik ik een alleen-lezen-query in een lus tegen de 2008 Credit-voorbeelddatabase, ingesteld op GO 10.000.000 keer.

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

Ik voer deze query ook uit via 16 gelijktijdige sessies. Het eindresultaat op mijn testsysteem is 100% CPU-gebruik over alle vCPU's op de virtuele gast en een gemiddelde van 14.492 batchverzoeken per seconde gedurende een periode van 2 minuten.

Wat betreft het traceren van gebeurtenissen, gebruikte ik in elke test Showplan XML Statistics Profile voor de SQL Profiler en Server-side traceringstests – en query_post_execution_showplan voor Extended Event-sessies. Uitvoeringsplangebeurtenissen zijn erg duur, en dat is precies waarom ik ze heb gekozen, zodat ik kon zien of ik onder extreme omstandigheden wel of niet wait-type-thema's kon afleiden.

Voor het testen van de accumulatie van het wachttype gedurende een testperiode heb ik de volgende query gebruikt. Niets bijzonders - gewoon de statistieken wissen, 2 minuten wachten en vervolgens de top 10 wachtende accumulaties verzamelen voor de SQL Server-instantie tijdens de degradatietestperiode:

-- 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;

Merk op dat ik niet . ben het uitfilteren van typen wachten op de achtergrond die doorgaans worden weggefilterd, en dit is omdat ik iets dat normaal gesproken goedaardig is niet wilde elimineren, maar in dit geval wijst het in feite op een echt gebied om verder te onderzoeken.

SQL Profiler-sessie

De volgende tabel toont de batchverzoeken voor en na per seconde bij het inschakelen van een lokale SQL Profiler-tracering Showplan XML Statistics Profile (draaiend op dezelfde VM als de SQL Server-instantie):

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-sessiebatchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 1.416

U kunt zien dat de SQL Profiler-tracering een aanzienlijke daling van de doorvoer veroorzaakt.

Wat betreft de geaccumuleerde wachttijden in diezelfde periode, waren de meest voorkomende soorten wachttijden als volgt (net als bij de rest van de tests in dit artikel heb ik een paar testruns uitgevoerd en de uitvoer was over het algemeen consistent):

wait_type waiting_tasks_count wait_time_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

Het type wacht dat me opvalt is TRACEWRITE - die door Books Online is gedefinieerd als een wachttype dat "optreedt wanneer de SQL Trace-rijenset-traceerprovider wacht op een vrije buffer of een buffer met te verwerken gebeurtenissen". De rest van de wachttypen zien eruit als standaard wachttypen op de achtergrond die je normaal gesproken uit je resultatenset zou filteren. Bovendien sprak ik over een soortgelijk probleem met over-tracing in een artikel in 2011 genaamd Observer overhead - de gevaren van te veel tracing - dus ik was bekend met dit type wacht soms correct wijzen op problemen met de overhead van de waarnemer. In dat specifieke geval waarover ik blogde, was het niet SQL Profiler, maar een andere toepassing die de rowset-traceerprovider (inefficiënt) gebruikte.

Server-Side Trace

Dat was voor SQL Profiler, maar hoe zit het met de traceeroverhead aan de serverzijde? De volgende tabel toont de voor-en-na batchverzoeken per seconde bij het inschakelen van een lokale server-side tracering naar een bestand:

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-batchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 4015

De beste soorten wachten waren als volgt (ik heb een paar testruns gedaan en de uitvoer was consistent):

wait_type waiting_tasks_count wait_time_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
WAITFOR 1 120.000
LOGMGR_QUEUE 931 119.993
DIRTY_PAGE_POLL 1.193 119.958
XE_TIMER_EVENT 55 119.954

Deze keer zien we geen TRACEWRITE (we gebruiken nu een bestandsprovider) en het andere traceergerelateerde wachttype, het ongedocumenteerde SQLTRACE_INCREMENTAL_FLUSH_SLEEP klom naar boven - maar heeft in vergelijking met de eerste test een zeer vergelijkbare geaccumuleerde wachttijd (120.046 vs. 120.006) - en mijn collega Erin Stellato (@erinstellato) sprak over dit specifieke type wachten in haar bericht Uitzoeken wanneer wachtstatistieken voor het laatst zijn gewist . Dus kijkend naar de andere soorten wachten, springt er geen eruit als een betrouwbare rode vlag.

Server-Side Trace schrijven naar een langzaam I/O-pad

Wat als we het traceerbestand aan de serverzijde op een langzame schijf zetten? De volgende tabel toont de batchverzoeken voor en na per seconde bij het inschakelen van een lokale server-side trace die naar een bestand op een USB-stick schrijft:

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-batchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 260

Zoals we kunnen zien, zijn de prestaties aanzienlijk verslechterd, zelfs in vergelijking met de vorige test.

De beste wachttypes waren als volgt:

wait_type waiting_tasks_count wait_time_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
WAITFOR 1 120.515
DIRTY_PAGE_POLL 1204 120.513

Een type wacht dat eruit springt voor deze test is de ongedocumenteerde SQLTRACE_FILE_BUFFER . Hierover is niet veel gedocumenteerd, maar op basis van de naam kunnen we een weloverwogen gok doen (vooral gezien de configuratie van deze specifieke test).

Uitgebreide gebeurtenissen naar het ringbufferdoel

Laten we vervolgens de bevindingen bekijken voor equivalenten van Extended Event-sessies. Ik heb de volgende sessiedefinitie gebruikt:

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

De volgende tabel toont de voor-en-na batchverzoeken per seconde bij het inschakelen van een XE-sessie met een ringbufferdoel (waarbij het query_post_execution_showplan wordt vastgelegd evenement):

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-batchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 4.737

De beste wachttypes waren als volgt:

wait_type waiting_tasks_count wait_time_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
WAITFOR 1 120.001

Niets sprong eruit als XE-gerelateerd, alleen achtergrondtaak "ruis".

Uitgebreide gebeurtenissen naar een bestandsdoel

Hoe zit het met het wijzigen van de sessie om een ​​bestandsdoel te gebruiken in plaats van een ringbufferdoel? De volgende tabel toont de batchverzoeken voor en na per seconde bij het inschakelen van een XE-sessie met een bestandsdoel in plaats van een ringbufferdoel:

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-batchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 4.299

De beste wachttypes waren als volgt:

wait_type waiting_tasks_count wait_time_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
WAITFOR 1 120.001
XE_TIMER_EVENT 59 119.966
LOGMGR_QUEUE 935 119.957

Niets, met uitzondering van XE_TIMER_EVENT , sprong eruit als XE-gerelateerd. De Wait Type Repository van Bob Ward verwijst naar deze als veilig om te negeren, tenzij er mogelijk iets mis is - maar realistisch gezien zou u dit gewoonlijk goedaardige wachttype opmerken als het op de 9e plaats op uw systeem stond tijdens een prestatievermindering? En wat als je het er al uit filtert vanwege zijn normaal goedaardige aard?

Uitgebreide gebeurtenissen naar een langzaam I/O-padbestandsdoel

Wat nu als ik het bestand op een langzaam I/O-pad zet? De volgende tabel toont de voor-en-na batchverzoeken per seconde bij het inschakelen van een XE-sessie met een bestandsdoel op een USB-stick:

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-batchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 4.386

De beste wachttypes waren als volgt:

wait_type waiting_tasks_count wait_time_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
WAITFOR 1 120.002
DIRTY_PAGE_POLL 1.197 119.977
XE_TIMER_EVENT 59 119.949

Nogmaals, er springt niets XE-gerelateerd uit behalve de XE_TIMER_EVENT .

Uitgebreide gebeurtenissen naar een langzaam I/O-padbestandsdoel, geen gebeurtenisverlies

De volgende tabel toont de batchverzoeken voor en na per seconde bij het inschakelen van een XE-sessie met een bestandsdoel op een USB-stick, maar deze keer zonder gebeurtenisverlies toe te staan ​​(EVENT_RETENTION_MODE=NO_EVENT_LOSS) - wat niet wordt aanbevolen en u zult zien in de resultaten waarom dat zou kunnen zijn:

Basislijn batchverzoeken per seconde
(gemiddelde van 2 minuten)
SQL Profiler-batchverzoeken per seconde
(gemiddelde van 2 minuten)
14.492 539

De beste wachttypes waren als volgt:

wait_type waiting_tasks_count wait_time_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
WAITFOR 1 120.000
XE_TIMER_EVENT 59 119.944

Met de extreme doorvoerreductie zien we XE_BUFFERMGR_FREEBUF_EVENT spring naar de nummer één positie op onze verzamelde wachttijdresultaten. Deze is gedocumenteerd in Books Online, en Microsoft vertelt ons dat deze gebeurtenis is gekoppeld aan XE-sessies die zijn geconfigureerd voor geen verlies van gebeurtenissen en waarbij alle buffers in de sessie vol zijn.

Invloed van waarnemer

Afgezien van de typen wacht, was het interessant om te zien welke impact elke observatiemethode had op het vermogen van onze werklast om batchverzoeken te verwerken:


Impact van verschillende observatiemethoden op batchverzoeken per seconde

Voor alle benaderingen was er een significante – maar niet schokkende – hit in vergelijking met onze baseline (geen observatie); de meeste pijn werd echter gevoeld bij het gebruik van Profiler, bij het gebruik van Server-Side Trace naar een langzaam I/O-pad, of Extended Events naar een bestandsdoel op een langzaam I/O-pad - maar alleen wanneer geconfigureerd voor geen gebeurtenisverlies. Met verlies van gebeurtenissen presteerde deze opstelling eigenlijk op hetzelfde niveau als een bestandsdoel naar een snel I/O-pad, vermoedelijk omdat het in staat was om veel meer gebeurtenissen te laten vallen.

Samenvatting

Ik heb niet elk mogelijk scenario getest en er zijn zeker andere interessante combinaties (om nog maar te zwijgen van verschillende gedragingen op basis van de SQL Server-versie), maar de belangrijkste conclusie die ik uit deze verkenning trek, is dat je niet altijd kunt vertrouwen op een voor de hand liggende accumulatie van het wachttype aanwijzer wanneer geconfronteerd met een waarnemer overhead scenario. Op basis van de tests in dit bericht vertoonden slechts drie van de zeven scenario's een specifiek wachttype dat u mogelijk in de goede richting zou kunnen wijzen. Zelfs toen - deze tests waren op een gecontroleerd systeem - en vaak filteren mensen de bovengenoemde wachttypes uit als goedaardige achtergrondtypes - zodat je ze misschien helemaal niet ziet.

Gezien dit, wat kunt u doen? Voor prestatievermindering zonder duidelijke of voor de hand liggende symptomen, raad ik aan om de reikwijdte uit te breiden om te vragen naar sporen en XE-sessies (terzijde - ik raad ook aan om je reikwijdte uit te breiden als het systeem gevirtualiseerd is of mogelijk onjuiste stroomopties heeft). Als onderdeel van het oplossen van problemen met een systeem, controleert u bijvoorbeeld sys.[traces] en sys.[dm_xe_sessions] om te zien of er iets onverwachts op het systeem draait. Het is een extra laag waar u zich zorgen over moet maken, maar een paar snelle validaties kunnen u een aanzienlijke hoeveelheid tijd besparen.


  1. Orbeon Forms Postgres DB-verbinding

  2. Waarom ongeldige conversie aangevraagd FOUTCODE:17132?

  3. De lat hoger leggen voor beheer van MySQL, MariaDB, PostgreSQL en MongoDB

  4. SQL Server 2017-back-up -3