Microsoft har inte för vana att förringa saker nuförtiden, men när de gör det, är det av en anledning – och det är verkligen inte för att de vill göra ditt liv svårare. Tvärtom beror det nästan alltid på att de har utvecklat bättre och modernare sätt att lösa samma problem.
Men vanor är svåra att bryta; fråga mig hur jag vet. Allt för ofta ser jag människor klamra sig fast vid ett äldre sätt att utföra en uppgift, även om det finns ett bättre sätt.
Jag skulle vilja dela med mig av ett par senaste exempel som hjälper till att illustrera hur användningen av föråldrade SQL Server-funktioner fortsätter att bita på oss. I den här första delen vill jag prata om...
sysprocesser
Systemtabellen sys.sysprocesses
ersattes långt tillbaka i SQL Server 2005 av en uppsättning dynamiska hanteringsvyer (DMV), särskilt sys.dm_exec_requests
, sys.dm_exec_sessions
och sys.dm_exec_connections
. Den officiella dokumentationen för sys.sysprocesses
varnar:
Ett färskt exempel
Nyligen undersökte ett av våra team ett problem med loggläsarens latens. Vi lägger stor vikt vid latens här, tillsammans med eventuella långvariga transaktioner, på grund av nedströms påverkan på tekniker som använder loggläsaren – som tillgänglighetsgrupper och transaktionsreplikering. Våra första varningar syns vanligtvis på en instrumentpanel som plottar loggläsarens latens mot transaktionens varaktighet (jag ska förklara tidpunkterna jag märkte t0
och t1
snart):
De bestämde, låt oss säga vid tidpunkten t0
, att en viss session hade en öppen transaktion som blockerade loggläsarprocessen. De kontrollerade först utdata från DBCC INPUTBUFFER
, för att försöka avgöra vad den här sessionen senast gjorde, men resultaten visade helt enkelt att de också utfärdade andra batcher under sin transaktion:
event_type parameters event_info -------------- ---------- --------------- Language Event 0 SET ROWCOUNT 0;
Observera att DBCC INPUTBUFFER
har också en mer kapabel ersättning i moderna versioner:sys.dm_exec_input_buffer
. Och även om den inte har en explicit utfasningsvarning, är den officiella dokumentationen för DBCC
kommandot har denna mjuka knuff:
Efter att ha fått något från indatabufferten frågade de sys.sysprocesses
:
SELECT spid, [status], open_tran, waittime, [cpu], physical_io, memusage, last_batch FROM sys.sysprocesses WHERE spid = 107;
Resultaten var likaledes värdelösa, åtminstone när det gällde att avgöra vad sessionen hade gjort för att hålla sin transaktion öppen och störa loggläsaren:
Jag markerar physical_io
kolumnen eftersom detta värde väckte en diskussion om huruvida de ville riskera att döda sovsessionen eller inte. Tanken var att i händelse av att alla dessa fysiska I/O är skrivningar, kan dödande av transaktionen resultera i en långvarig och störande återställning – potentiellt göra problemet ännu värre. Jag tänker inte sätta faktiska tider på detta, men låt oss bara säga att detta blev en långvarig konversation och det lämnade systemet i detta tillstånd från tidpunkten t0
till tid t1
på grafen ovan.
Varför detta är ett problem
Problemet i det här specifika fallet är att de ägnade den tiden åt att överväga ett beslut baserat på ofullständig information. Är dessa I/O läser eller skriver? Om användaren har en öppen transaktion och bara har läst mycket data, blir det mycket mindre inverkan på att återställa den transaktionen än om de har ändrats mycket data. Så istället för sys.sysprocesses
, låt oss se vad den mer moderna DMV, sys.dm_exec_sessions
, kan visa oss om den här sessionen:
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;
Resultat:
Här ser vi att sys.dm_exec_sessions
bryter ut den fysiska I/O separat i läsningar och skrivningar. Detta gör att vi kan fatta ett mycket mer välgrundat beslut, mycket snabbare än t1 - t0
, om en potentiell återställningseffekt. Om I/O är helt skrivna, och beroende på hur högt siffran är, kan vi tveka lite mer och kanske ägna tiden åt att försöka hitta användaren (så att vi kan slå deras knogar eller fråga dem varför de har en öppen transaktion ). Om vi vet att det mestadels är läsningar kan vi istället luta oss mot att döda sessionen och tvinga transaktionen att rulla tillbaka.
Visst, sys.sysprocesses
har dbid
och waittime
. Men dbid
är opålitlig och marginellt användbar ändå, särskilt för korsdatabasförfrågningar; det finns mycket bättre information i sys.dm_tran_locks
. Vänteinformation (tid och senaste väntetyp) finns i sys.dm_exec_requests
, men mycket mer detaljerad information finns i sys.dm_exec_session_wait_stats
(tillagt i SQL Server 2016). En ursäkt som jag brukade höra mycket var att sys.dm_exec_sessions
saknade open_tran
, men open_transaction_count
lades till tillbaka i SQL Server 2012. Så det finns väldigt liten anledning att ens tänka på att använda sys.sysprocesses
idag.
Om du vill upptäcka hur ofta sys.sysprocesses
har refererats sedan SQL Server startade om senast kan du köra den här frågan mot prestandaräknare 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;
Om du verkligen vill undvika sömn i natt, eller om du bara gillar att ständigt lägga till i tvättlistan över saker du oroar dig för, ta bort predikatet mot instance_name
. Detta kommer att ge dig en skrämmande uppfattning på hög nivå om hur många saker dina instanser kör som du så småningom kommer att behöva ändra.
Under tiden kan du ladda ner sp_WhoIsActive
, Adam Machanics extremt användbara lagrade procedur för övervakning och felsökning av SQL Server-processer i realtid. Vi har distribuerat denna lagrade procedur till varje instans i vår miljö, och du bör också, oavsett vilka andra avancerade övervakningsverktyg du kanske också använder.
Nästa gång
I del 2 ska jag prata lite om SQL Server Profiler, en applikation som folk använder mer på grund av förtrogenhet än något annat – utan att inse hur farligt det kan vara.