
Microsoft v dnešní době nemá ve zvyku věci odsuzovat, ale když se tak stane, má to svůj důvod – a rozhodně to není proto, že by vám chtěli ztížit život. Naopak, je to téměř vždy proto, že vyvinuli lepší a modernější způsoby řešení stejných problémů.
Ale zvyky je těžké prolomit; zeptej se mě, jak to vím. Až příliš často vidím lidi, jak lpí na starším způsobu splnění nějakého úkolu, i když existuje lepší způsob.
Rád bych se podělil o několik nedávných příkladů, které nám pomohou ilustrovat, jak nás používání zastaralých funkcí SQL Serveru stále trápí. V této první části chci mluvit o…
systémové procesy
Systémová tabulka sys.sysprocesses byl v SQL Server 2005 nahrazen sadou pohledů dynamické správy (DMV), zejména sys.dm_exec_requests , sys.dm_exec_sessions a sys.dm_exec_connections . Oficiální dokumentace pro sys.sysprocesses varuje:
Nedávný příklad
Nedávno jeden z našich týmů zkoumal problém s latencí čtečky protokolů. Zde věnujeme velkou pozornost latenci spolu s jakýmikoli dlouhotrvajícími transakcemi, a to kvůli následným dopadům na technologie, které používají čtečku protokolů – jako jsou skupiny dostupnosti a transakční replikace. Naše první varování jsou obvykle spatřena na řídicím panelu, který vykresluje latenci čtečky protokolů oproti délce transakce (vysvětlím časové body, které jsem označil t0 a t1 zakrátko):

Určili, řekněme v čase t0 , že určitá relace měla otevřenou transakci blokující proces čtení protokolu. Nejprve zkontrolovali výstup DBCC INPUTBUFFER , aby se pokusili zjistit, co tato relace trvala, ale výsledky jednoduše ukázaly, že během transakce vydali také další dávky:
event_type parameters event_info -------------- ---------- --------------- Language Event 0 SET ROWCOUNT 0;
Všimněte si, že DBCC INPUTBUFFER má také schopnější náhradu v moderních verzích:sys.dm_exec_input_buffer . A přestože neobsahuje výslovné upozornění na ukončení podpory, oficiální dokumentace pro DBCC příkaz má toto jemné šťouchnutí:
Poté, co nezískali nic ze vstupní vyrovnávací paměti, zeptali se sys.sysprocesses :
SELECT spid, [status], open_tran, waittime, [cpu], physical_io, memusage, last_batch FROM sys.sysprocesses WHERE spid = 107;
Výsledky byly podobně k ničemu, alespoň pokud jde o určení toho, co relace dělala, aby jejich transakce zůstala otevřená a narušila čtení protokolu:

Zvýrazňuji physical_io protože tato hodnota rozpoutala diskusi o tom, zda chtějí nebo nechtějí riskovat zabití spící relace. Myšlenka byla taková, že v případě, že dojde k zápisu všech těchto fyzických I/O, ukončení transakce by mohlo vést ke zdlouhavému a rušivému návratu – potenciálně problém ještě zhoršit. Nebudu to uvádět skutečné časy, ale řekněme, že se to změnilo v prodlouženou konverzaci a systém to nechal v tomto stavu od času t0 na čas t1 na grafu výše.
Proč je to problém
Problémem v tomto konkrétním případě je, že strávili tento čas úvahami o rozhodnutí na základě neúplných informací. Jsou tyto I/O čtení nebo zápis? Pokud má uživatel otevřenou transakci a pouze přečetl velké množství dat, má vrácení transakce zpět mnohem menší dopad, než kdyby se změnil hodně dat. Takže místo sys.sysprocesses , podívejme se, co modernější DMV, sys.dm_exec_sessions , může nám ukázat o této relaci:
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;
Výsledky:

Zde vidíme, že sys.dm_exec_sessions rozdělí fyzické I/O odděleně na čtení a zápis. To nám umožňuje učinit mnohem informovanější rozhodnutí, mnohem rychleji než t1 - t0 , o možném dopadu vrácení. Pokud I/O vše zapisuje a v závislosti na tom, jak je číslo vysoké, můžeme ještě trochu váhat a možná strávit čas hledáním uživatele (takže bychom jim mohli namlátit klouby nebo se jich zeptat, proč mají otevřenou transakci ). Pokud víme, že jde většinou o čtení, můžeme se místo toho přiklonit k zastavení relace a vynucení vrácení transakce.
Jistě, sys.sysprocesses má dbid a waittime . Ale dbid je stejně nespolehlivá a okrajově užitečná, zejména pro dotazy napříč databázemi; mnohem lepší informace jsou v sys.dm_tran_locks . Informace o čekání (čas a typ posledního čekání) lze nalézt v sys.dm_exec_requests , ale mnohem podrobnější informace nabízí sys.dm_exec_session_wait_stats (přidáno v SQL Server 2016). Omluva, kterou jsem často slýchal, byla, že sys.dm_exec_sessions chyběl open_tran , ale open_transaction_count byl přidán zpět do SQL Server 2012. Je tedy velmi málo důvodů vůbec přemýšlet o použití sys.sysprocesses dnes.
Pokud chcete zjistit, jak často sys.sysprocesses byl odkazován od posledního restartování serveru SQL Server, můžete tento dotaz spustit proti čítačům výkonu 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;
Pokud se dnes v noci opravdu chcete vyhnout spánku nebo jen rádi neustále přidáváte do seznamu věcí, které vás trápí, odeberte predikát u instance_name . To vám dá děsivou představu na vysoké úrovni o tom, kolik věcí ve vašich instancích běží a které budete nakonec muset změnit.
Mezitím si stáhněte sp_WhoIsActive , mimořádně užitečná uložená procedura Adama Machanice pro monitorování a odstraňování problémů s procesy SQL Server v reálném čase. Tuto uloženou proceduru jsme nasadili do každé instance v našem prostředí a vy byste měli také, bez ohledu na to, jaké další špičkové monitorovací nástroje také používáte.
Příště
V části 2 budu hovořit trochu o SQL Server Profiler, aplikaci, kterou lidé používají spíše kvůli známosti než cokoli jiného – aniž by si uvědomovali, jak nebezpečná může být.