Microsoft har ikke for vane at forringe ting i disse dage, men når de gør det, er det af en grund – og det er bestemt ikke, fordi de ønsker at gøre dit liv sværere. Tværtimod er det næsten altid, fordi de har udviklet bedre og mere moderne måder at løse de samme problemer på.
Men vaner er svære at bryde; spørg mig, hvordan jeg ved det. Alt for ofte ser jeg folk klamre sig til en ældre måde at udføre en opgave på, selvom der findes en bedre måde.
Jeg vil gerne dele et par nylige eksempler, der hjælper med at illustrere, hvordan brugen af forældede SQL Server-funktioner fortsætter med at bide os. I denne første del vil jeg tale om...
sysprocesser
Systemtabellen sys.sysprocesses
blev erstattet helt tilbage i SQL Server 2005 af et sæt dynamiske administrationsvisninger (DMV'er), især sys.dm_exec_requests
, sys.dm_exec_sessions
, og sys.dm_exec_connections
. Den officielle dokumentation for sys.sysprocesses
advarer:
Et nyligt eksempel
For nylig undersøgte et af vores teams et problem med loglæserforsinkelse. Vi er meget opmærksomme på latens her, sammen med eventuelle langvarige transaktioner, på grund af nedstrøms indvirkning på teknologier, der bruger loglæseren – som tilgængelighedsgrupper og transaktionsreplikering. Vores første advarsler ses normalt på et dashboard, der plotter loglæserens latens mod transaktionsvarighed (jeg vil forklare de tidspunkter, jeg mærkede t0
og t1
snart):
De bestemte, lad os sige på tidspunktet t0
, at en bestemt session havde en åben transaktion, der blokerede loglæserprocessen. De kontrollerede først outputtet af DBCC INPUTBUFFER
, for at prøve at fastslå, hvad denne session varede, men resultaterne viste blot, at de også udstedte andre batcher under deres transaktion:
event_type parameters event_info -------------- ---------- --------------- Language Event 0 SET ROWCOUNT 0;
Bemærk at DBCC INPUTBUFFER
har også en mere dygtig erstatning i moderne versioner:sys.dm_exec_input_buffer
. Og selvom den ikke har en eksplicit advarsel om udfasning, er den officielle dokumentation for DBCC
kommandoen har dette blide skub:
Efter ikke at have fået noget fra inputbufferen, spurgte de sys.sysprocesses
:
SELECT spid, [status], open_tran, waittime, [cpu], physical_io, memusage, last_batch FROM sys.sysprocesses WHERE spid = 107;
Resultaterne var på samme måde ubrugelige, i det mindste med hensyn til at bestemme, hvad sessionen havde gjort for at holde deres transaktion åben og forstyrre loglæseren:
Jeg fremhæver physical_io
kolonne, fordi denne værdi udløste en diskussion om, hvorvidt de ønskede at risikere at dræbe den sovende session. Tanken var, at i tilfælde af at alle disse fysiske I/O'er er skrivninger, kunne dræbning af transaktionen resultere i en langvarig og forstyrrende tilbagerulning - potentielt gøre problemet endnu værre. Jeg vil ikke sætte faktiske tider på dette, men lad os bare sige, at dette blev til en langvarig samtale, og det efterlod systemet i denne tilstand fra tidspunktet t0
til tid t1
på grafen ovenfor.
Hvorfor er dette et problem
Problemet i denne specifikke sag er, at de brugte den tid på at overveje en beslutning baseret på ufuldstændige oplysninger. Er disse I/O'er læsninger eller skrivninger? Hvis brugeren har en åben transaktion og kun har læst en masse data, er der langt mindre indflydelse ved at rulle denne transaktion tilbage, end hvis de har ændret en masse data. Så i stedet for sys.sysprocesses
, lad os se, hvad den mere moderne DMV, sys.dm_exec_sessions
, kan vise os om denne session:
SELECT session_id, [status], open_transaction_count, cpu_time, [reads], writes, logical_reads, last_request_start_time, last_request_end_time FROM sys.dm_exec_sessions WHERE session_id = 107;
Resultater:
Her ser vi at sys.dm_exec_sessions
opdeler den fysiske I/O separat i læsninger og skrivninger. Dette giver os mulighed for at træffe en meget mere informeret beslutning, meget hurtigere end t1 - t0
, om en potentiel tilbagerulningspåvirkning. Hvis I/O'en er alle skrivere, og afhængigt af hvor højt tallet er, vil vi måske tøve lidt mere og måske bruge tiden på at finde brugeren (så vi kunne slå deres knoer eller spørge dem, hvorfor de har en åben transaktion ). Hvis vi ved, at det for det meste er læst, kan vi i stedet læne os mod at dræbe sessionen og tvinge transaktionen til at rulle tilbage.
Selvfølgelig, sys.sysprocesses
har dbid
og waittime
. Men dbid
er upålidelig og marginalt nyttig alligevel, især til krydsdatabaseforespørgsler; der er meget bedre information i sys.dm_tran_locks
. Venteoplysninger (tid og sidste ventetype) kan findes i sys.dm_exec_requests
, men meget mere detaljeret information findes i sys.dm_exec_session_wait_stats
(tilføjet i SQL Server 2016). En undskyldning, jeg plejede at høre meget, var, at sys.dm_exec_sessions
manglede open_tran
, men open_transaction_count
blev tilføjet tilbage i SQL Server 2012. Så der er meget lidt grund til overhovedet at tænke på at bruge sys.sysprocesses
i dag.
Hvis du vil finde ud af, hvor ofte sys.sysprocesses
er blevet refereret siden SQL Server genstartede sidst, kan du køre denne forespørgsel mod ydeevnetællerne DMV:
SELECT instance_name, cntr_value FROM sys.dm_os_performance_counters WHERE [object_name] LIKE N'%:Deprecated Features%' AND instance_name = N'sysprocesses' ORDER BY cntr_value DESC;
Hvis du virkelig vil undgå at sove i nat, eller du bare kan lide konstant at tilføje til vasketøjslisten over ting, du bekymrer dig om, skal du fjerne prædikatet mod instance_name
. Dette vil give dig en skræmmende idé på højt niveau om, hvor mange ting dine forekomster kører, som du i sidste ende bliver nødt til at ændre.
I mellemtiden kan du downloade sp_WhoIsActive
, Adam Machanics ultra nyttige lagrede procedure til overvågning og fejlfinding af SQL Server-processer i realtid. Vi har implementeret denne lagrede procedure til alle forekomster i vores miljø, og du bør også, uanset hvilke andre avancerede overvågningsværktøjer, du måske også bruger.
Næste gang
I del 2 vil jeg tale lidt om SQL Server Profiler, en applikation, som folk bruger mere på grund af deres kendskab end noget andet – uden at være klar over, hvor farligt det kan være.