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.