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

Forældede funktioner til at tage ud af din værktøjskasse – Del 1

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:

Denne SQL Server 2000-systemtabel er inkluderet som en visning for bagudkompatibilitet. Vi anbefaler, at du i stedet bruger de aktuelle SQL Server-systemvisninger. For at finde den eller de tilsvarende systemvisninger, se Tilknytning af systemtabeller til systemvisninger (Transact-SQL). Denne funktion vil blive fjernet i en fremtidig version af Microsoft SQL Server. Undgå at bruge denne funktion i nyt udviklingsarbejde, og planlæg at ændre applikationer, der i øjeblikket bruger denne funktion.

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:

Start med SQL Server 2014 (12.x) SP2, og brug sys.dm_exec_input_buffer til at returnere oplysninger om sætninger indsendt til en forekomst af SQL Server.

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.


  1. SQL Server-pivot vs. multiple join

  2. Tilfældig værdi for kolonnen DATETIME

  3. Hvordan opretter man et indeks for elementer i et array i PostgreSQL?

  4. Sammenligning af Entity Framework-kompatible udbydere til Oracle?