Fejlfinding af ydeevne er en kunst og en videnskab. Kunsten kommer fra erfaring (og at lære af andres erfaringer), og videnskaben kommer fra velkendte retningslinjer om, hvad man skal gøre i hvilke scenarier.
Eller det er i hvert fald det, jeg godt kan lide at tænke og undervise i.
I virkeligheden praktiserer mange DBA'er og udviklere derude, hvad jeg kalder 'knee-jerk performance-fejlfinding'. Dette sker almindeligvis, når et ydeevneproblem har nået det kritiske stadie med f.eks. forespørgsler, der udløber, processer, der kører langsomt eller fejler, brugere er utilfredse, og ledelsen ønsker svar og hurtig handling!
'Knæet' kommer fra at lave en overfladisk analyse af problemet og hoppe til den konklusion (det er virkelig at gribe efter et strå), at det mest udbredte symptom må være grundårsagen og forsøge at løse det, til ingen eller ringe nytte, bruger ofte forkerte eller direkte forkerte råd fundet online. Dette fører til en masse frustration og spildtid, og fører ofte til spildte penge, når organisationen beslutter sig for at forsøge at kaste hardware på problemet ved at opgradere serveren og/eller I/O-undersystemet, kun for at finde ud af, at problemet stadig er der , eller dukker ret hurtigt op igen.
Ventestatistikanalyse er et af de områder, hvor det er nemmest at knæfalde, og i dette indlæg vil jeg fortælle om et par af de almindelige ventetyper og de fejl, som folk begår omkring dem. Der er ikke mulighed for i en artikel som denne at gå i dybden med, hvad du skal gøre i hvert enkelt tilfælde, men jeg vil give dig nok information til at pege dig i den rigtige retning.
LCK_M_XX
De fleste mennesker antager, at hvis låseventer er de mest udbredte, så må det være en form for blokeringsproblem, der er problemet. Ofte er det, såsom mangel på et passende ikke-klyngeindeks, der forårsager en tabelscanning i REPEATABLE_READ eller SERIALIZABLE isolationsniveauer, der eskalerer til en S-tabellås. (Og som et hurtigt tip, hvis du ikke tror, du nogensinde bruger SERIALIZABLE, gør du det, hvis du bruger distribuerede transaktioner – alt konverteres til SERIALIZABLE under dækslerne, hvilket kan føre til uventet blokering og dødvande.)
Det er dog ofte tilfældet, at blokeringen er forårsaget af noget andet. Under standard READ_COMMITTED isolationsniveau holdes låse, der dækker ændringer, indtil transaktionen forpligtes, og vil blokere læsninger og andre opdateringer til samme række(r). Hvis noget forhindrer en transaktion i at begå, kan det medføre, at blokering dukker op.
For eksempel, hvis databasen spejles synkront, kan transaktionen ikke forpligte og frigive sine låse, før logposterne er blevet sendt over til spejlet og skrevet til spejlets logdrev. Hvis netværket er alvorligt overbelastet, eller der er massiv I/O-strid på spejlet, kan dette forsinke spejlingsoperationen alvorligt, og dermed få transaktionen til at tage meget længere tid at gennemføre. Dette ville ligne blokering, men hovedårsagen er ressourcestrid om spejling.
For låsende ventetider, medmindre årsagen er indlysende ved at se på forespørgselsplanen, lås ressource (f.eks. tabelniveau, der angiver låseskalering eller isolationsniveau, følg blokeringskæden (ved hjælp af et script, der går i kolonnen blocking_session_id i sys.dm_exec_requests og derefter se, hvad tråden i spidsen af blokeringskæden venter på. Det vil pege på hovedårsagen.
ASYNC_NETWORK_IO
Navnet på denne skaber en masse forvirring. Hvilket ord fokuserer du på? NETVÆRK. Årsagen til denne ventetype har normalt intet at gøre med netværket. Det burde virkelig hedde WAITING_FOR_APP_ACK (nowledgment) eller noget lignende, da det er præcis, hvad der sker:SQL Server har sendt nogle data til en klient og venter på, at klienten anerkender, at den har forbrugt dataene.
En af mine yndlingsdemoer at lave, når jeg underviser om ventestatistik, er at køre en forespørgsel, der returnerer et stort resultatsæt i Management Studio og se serveren samle ASYNC_NETWORK_IO-venter. Der er tydeligvis ikke noget netværk involveret - det er bare SSMS, der tager lang tid at svare på SQL Server. Det gør det, der er kendt som RBAR (Row-By-Agonizing-Row), hvor kun én række ad gangen trækkes fra resultaterne og behandles, i stedet for at cache alle resultaterne og derefter straks svare til SQL Server og fortsætte med at behandle cachelagrede rækker.
Dette er hovedårsagen til ASYNC_NETWORK_IO-venter – dårligt programdesign. Jeg ville så se på, om serveren, der kører applikationskoden, har et ydeevneproblem, selvom selve applikationskoden er godt designet. Nogle gange er det netværket, men det er sjældent efter min erfaring.
OLEDB
Den almindelige knæfaldsreaktion her er at sidestille denne ventetype med linkede servere. Denne ventetid blev dog mere almindelig at se, hvornår SQL Server 2005 blev sendt, fordi 2005 indeholdt en række nye DMV'er, og DMV'er bruger for det meste OLE DB under coveret. Inden jeg ledte efter forbundne serverproblemer, ville jeg tjekke, om et overvågningsværktøj kører DMV'er konstant på serveren.
Hvis du har linkede servere, skal du fortsætte fejlfindingen ved at gå til den linkede server og se på ventestatistikken der for at se, hvad det mest udbredte problem er, og derefter fortsætte den samme analyse.
En anden ting, der kan forårsage OLEDB-venter, er DBCC CHECKDB (og relaterede kommandoer). Den bruger et OLE DB-rækkesæt til at kommunikere information mellem dets Query Processor og Storage Engine-undersystemer.
Andre ventetider
Nogle af de andre ventetider, der forårsager knæfaldsreaktioner, er CXPACKET, PAGEIOLATCH_XX, SOS_SCHEDULER_YIELD og WRITELOG, og dem vil jeg dække i mit indlæg næste måned.
Oversigt
Når du har et ydeevneproblem, skal du tage dig tid til at forstå de data, du ser på, og udføre yderligere undersøgelser for at hjælpe med at indsnævre årsagen til problemet. Tag ikke bare fat i det, der synes at være den bedste ventestatistik, og følg det første råd, du støder på online (medmindre det er fra en velkendt og velrenommeret kilde), ellers vil du sandsynligvis ikke løse dit problem, og måske endda gøre det værre.
Hvad angår generel ventestatistik, kan du finde mere information om brugen af dem til fejlfinding af ydeevne i:
- Min blogindlægsserie, der starter med Vent-statistikker, eller fortæl mig venligst, hvor det gør ondt
- Mine ventetyper og låseklasser bibliotek her
- Mit Pluralsight online-kursus SQL Server:Fejlfinding af ydeevne ved hjælp af ventestatistik
- SQL Sentry Performance Advisor
Dette var det første i en række af indlæg, jeg vil lave i løbet af dette år, der fortæller om knæfaldende (re)aktioner omkring SQL Server, og hvorfor de er den forkerte ting at gøre. Indtil næste gang, god fejlfinding!