sql >> Databáze >  >> RDS >> Database

Příznaky nad hlavou pozorovatele a typu čekání

Mnoho lidí používá statistiku čekání jako součást své celkové metodiky řešení problémů s výkonem, stejně jako já, takže otázka, kterou jsem chtěl v tomto příspěvku prozkoumat, se týká typů čekání spojených s režií pozorovatele. Režií pozorovatele mám na mysli dopad na propustnost zátěže SQL Server způsobený SQL Profilerem, trasováním na straně serveru nebo relacemi Extended Event. Více o tématu pozorovatele nad hlavou naleznete v následujících dvou příspěvcích od mého kolegy Jonathana Kehayiase :

  • Měření „režie pozorovatele“ trasování SQL vs. rozšířené události
  • Dopad události query_post_execution_showplan Extended v SQL Server 2012

Takže v tomto příspěvku bych rád prošel několika variacemi pozorovatele nad hlavou a zjistil, zda najdeme konzistentní typy čekání spojené s měřenou degradací. Existuje celá řada způsobů, jak uživatelé SQL Serveru implementují trasování ve svých produkčních prostředích, takže vaše výsledky se mohou lišit, ale chtěl jsem pokrýt několik širokých kategorií a podat zprávu o tom, co jsem našel:

  • Využití relace SQL Profiler
  • Využití trasování na straně serveru
  • Využití trasování na straně serveru, zápis do pomalé I/O cesty
  • Rozšířené použití událostí s cílem kruhové vyrovnávací paměti
  • Použití rozšířených událostí s cílem souboru
  • Využití rozšířených událostí s cílem souboru na pomalé cestě I/O
  • Rozšířené použití událostí s cílem souboru na pomalé cestě I/O bez ztráty události

Pravděpodobně si můžete vymyslet další variace na toto téma a vyzývám vás, abyste se podělili o jakékoli zajímavé poznatky týkající se statistiky pozorovatele a čekání jako komentář v tomto příspěvku.

Základní čára

K testu jsem použil virtuální stroj VMware se čtyřmi vCPU a 4GB RAM. Můj host virtuálního stroje byl na OCZ Vertex SSD. Operačním systémem byl Windows Server 2008 R2 Enterprise a verze SQL Server je 2012, SP1 CU4.

Pokud jde o „pracovní zátěž“, používám dotaz pouze pro čtení ve smyčce proti vzorové databázi kreditů z roku 2008, nastavenou na GO 10 000 000krát.

USE [Credit];
GO
 
SELECT TOP 1 
     [member].[member_no],
     [member].[lastname],
     [payment].[payment_no],
     [payment].[payment_dt],
     [payment].[payment_amt]
FROM [dbo].[payment]
INNER JOIN [dbo].[member]
ON [member].[member_no] = [payment].[member_no];
GO 10000000

Tento dotaz také provádím prostřednictvím 16 souběžných relací. Konečným výsledkem na mém testovacím systému je 100% využití CPU napříč všemi vCPU na virtuálním hostovi a průměrně 14 492 dávkových požadavků za sekundu během 2 minut.

Pokud jde o sledování událostí, v každém testu jsem použil Showplan XML Statistics Profile pro SQL Profiler a trasovací testy na straně serveru – a query_post_execution_showplan pro relace Extended Event. Události plánu provádění jsou velmi drahé, a to je přesně důvod, proč jsem si je vybral, abych viděl, jestli za extrémních okolností dokážu odvodit témata typu čekání.

Pro testování akumulace typu čekání během testovacího období jsem použil následující dotaz. Nic převratného – stačí vymazat statistiky, počkat 2 minuty a poté shromáždit 10 nejlepších nahromadění čekání pro instanci SQL Server během období testu degradace:

-- Clearing the wait stats
 
DBCC SQLPERF('waitstats', clear);
 
WAITFOR DELAY '00:02:00';
GO
 
SELECT TOP 10
     [wait_type],
     [waiting_tasks_count],
     [wait_time_ms]
FROM sys.[dm_os_wait_stats] AS [ws]
ORDER BY [wait_time_ms] DESC;

Všimněte si, že nejsem odfiltrování typů čekání na pozadí, které jsou obvykle odfiltrovány, a to proto, že jsem nechtěl eliminovat něco, co je normálně neškodné – ale za těchto okolností ve skutečnosti ukazuje na skutečnou oblast, kterou je třeba dále prozkoumat.

Relace SQL Profiler

Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení sledování trasování místního SQL Profiler Showplan XML Statistics Profile (běžící na stejném virtuálním počítači jako instance SQL Server):

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Hromadné požadavky relací SQL Profiler za sekundu
(průměr 2 minuty)
14 492 1 416

Můžete vidět, že trasování SQL Profiler způsobuje významný pokles propustnosti.

Pokud jde o kumulovanou dobu čekání za stejné období, nejčastější typy čekání byly následující (stejně jako u ostatních testů v tomto článku jsem provedl několik testovacích běhů a výstup byl obecně konzistentní):

wait_type waiting_tasks_count wait_time_ms
TRACEWRITE 67 142 1 149 824
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237 003
SLEEP_TASK 313 180 449
REQUEST_FOR_DEADLOCK_SEARCH 24 120 111
HADR_FILESTREAM_IOMGR_IOCOMPLETION 240 120 086
LAZYWRITER_SLEEP 120 120 059
DIRTY_PAGE_POLL 1 198 120 038
HADR_WORK_QUEUE 12 120 015
LOGMGR_QUEUE 937 120 011
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120 006

Typ čekání, který mi naskočí, je TRACEWRITE – který je definován Books Online jako typ čekání, který „nastane, když poskytovatel trasování sady řádků SQL čeká na volnou vyrovnávací paměť nebo vyrovnávací paměť s událostmi ke zpracování“. Zbývající typy čekání vypadají jako standardní typy čekání na pozadí, které by se obvykle odfiltrovaly z vaší sady výsledků. A co víc, o podobném problému s nadměrným sledováním jsem mluvil v roce 2011 v článku nazvaném Observer overhead – nebezpečí přílišného sledování – takže jsem tento typ čekání někdy znal. správně ukazovat na problémy nad hlavou pozorovatele. V tomto konkrétním případě, o kterém jsem blogoval, to nebyl SQL Profiler, ale jiná aplikace využívající poskytovatele trasování sady řádků (neefektivně).

Trasování na straně serveru

To bylo pro SQL Profiler, ale co režie trasování na straně serveru? Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení zápisu trasování do souboru na straně místního serveru:

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Dávkové požadavky SQL Profiler za sekundu
(průměr 2 minuty)
14 492 4 015

Nejčastější typy čekání byly následující (provedl jsem několik testovacích běhů a výstup byl konzistentní):

wait_type waiting_tasks_count wait_time_ms
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237 015
SLEEP_TASK 253 180 871
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120 046
HADR_WORK_QUEUE 12 120 042
REQUEST_FOR_DEADLOCK_SEARCH 24 120 021
XE_DISPATCHER_WAIT 3 120 006
ČEKEJTE NA 1 120 000
LOGMGR_QUEUE 931 119 993
DIRTY_PAGE_POLL 1 193 119 958
XE_TIMER_EVENT 55 119 954

Tentokrát nevidíme TRACEWRITE (nyní používáme poskytovatele souborů) a další typ čekání související se trasováním, nezdokumentovaný SQLTRACE_INCREMENTAL_FLUSH_SLEEP vyšplhal – ale ve srovnání s prvním testem má velmi podobnou kumulovanou dobu čekání (120 046 vs. 120 006) – a moje kolegyně Erin Stellato (@erinstellato) mluvila o tomto konkrétním typu čekání ve svém příspěvku Zjistit, kdy byly statistiky čekání naposledy vymazány . Když se tedy podíváme na ostatní typy čekání, žádný nevyskočí jako spolehlivý červený prapor.

Zápis trasování na straně serveru do pomalé I/O cesty

Co když umístíme trasovací soubor na straně serveru na pomalý disk? Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení trasování na straně místního serveru, které zapisuje do souboru na USB klíčenku:

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Dávkové požadavky SQL Profiler za sekundu
(průměr 2 minuty)
14 492 260

Jak vidíme – výkon je výrazně snížen – dokonce i ve srovnání s předchozím testem.

Nejčastější typy čekání byly následující:

wait_type waiting_tasks_count wait_time_ms
SQLTRACE_FILE_BUFFER 357 351 174
SP_SERVER_DIAGNOSTICS_SLEEP 2 273 299 995
SLEEP_TASK 240 194 264
FT_IFTS_SCHEDULER_IDLE_WAIT 2 181 458
REQUEST_FOR_DEADLOCK_SEARCH 25 125 007
LAZYWRITER_SLEEP 63 124 437
LOGMGR_QUEUE 941 120 559
HADR_FILESTREAM_IOMGR_IOCOMPLETION 67 120 516
ČEKEJTE NA 1 120 515
DIRTY_PAGE_POLL 1 204 120 513

Jeden typ čekání, který pro tento test vyskočí, je nezdokumentovaný SQLTRACE_FILE_BUFFER . Na tomto není příliš zdokumentováno, ale na základě názvu můžeme kvalifikovaně odhadnout (zejména s ohledem na konfiguraci tohoto konkrétního testu).

Rozšířené události do cíle kruhové vyrovnávací paměti

Dále si projdeme zjištění pro ekvivalenty relací Extended Event. Použil jsem následující definici relace:

CREATE EVENT SESSION [ApplicationXYZ] ON SERVER
  ADD EVENT sqlserver.query_post_execution_showplan,
  ADD TARGET package0.ring_buffer(SET max_events_limit=(1000))
  WITH (STARTUP_STATE=ON);
GO

Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení relace XE s cílem kruhové vyrovnávací paměti (zachycující query_post_execution_showplan událost):

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Dávkové požadavky SQL Profiler za sekundu
(průměr 2 minuty)
14 492 4 737

Nejčastější typy čekání byly následující:

wait_type waiting_tasks_count wait_time_ms
SP_SERVER_DIAGNOSTICS_SLEEP 612 299 992
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237 006
SLEEP_TASK 240 181 739
LAZYWRITER_SLEEP 120 120 219
HADR_WORK_QUEUE 12 120 038
DIRTY_PAGE_POLL 1 198 120 035
REQUEST_FOR_DEADLOCK_SEARCH 24 120 017
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120 011
LOGMGR_QUEUE 936 120 008
ČEKEJTE NA 1 120 001

Nic nevyskočilo jako související s XE, pouze „hluk“ úlohy na pozadí.

Rozšířené události na cílový soubor

Co takhle změnit relaci tak, aby používala cíl souboru místo cíle kruhové vyrovnávací paměti? Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení relace XE s cílem souboru namísto cíle kruhové vyrovnávací paměti:

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Dávkové požadavky SQL Profiler za sekundu
(průměr 2 minuty)
14 492 4 299

Nejčastější typy čekání byly následující:

wait_type waiting_tasks_count wait_time_ms
SP_SERVER_DIAGNOSTICS_SLEEP 2 103 299 996
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237 003
SLEEP_TASK 253 180 663
LAZYWRITER_SLEEP 120 120 187
HADR_WORK_QUEUE 12 120 029
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120 019
REQUEST_FOR_DEADLOCK_SEARCH 24 120 011
ČEKEJTE NA 1 120 001
XE_TIMER_EVENT 59 119 966
LOGMGR_QUEUE 935 119 957

Nic, s výjimkou XE_TIMER_EVENT , vyskočilo jako související s XE. Bob Ward’s Wait Type Repository to označuje za bezpečné ignorovat, pokud nebylo něco možného špatně – ale reálně byste si všimli tohoto obvykle neškodného typu čekání, pokud by byl na 9 místě ve vašem systému během snížení výkonu? A co když ho už odfiltrujete kvůli jeho normálně neškodné povaze?

Rozšířené události na cíl souboru s pomalou I/O cestou

Co když teď umístím soubor na pomalou I/O cestu? Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení relace XE s cílem souboru na USB flash disku:

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Dávkové požadavky SQL Profiler za sekundu
(průměr 2 minuty)
14 492 4 386

Nejčastější typy čekání byly následující:

wait_type waiting_tasks_count wait_time_ms
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237 046
SLEEP_TASK 253 180 719
HADR_FILESTREAM_IOMGR_IOCOMPLETION 240 120 427
LAZYWRITER_SLEEP 120 120 190
HADR_WORK_QUEUE 12 120 025
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120 013
REQUEST_FOR_DEADLOCK_SEARCH 24 120 011
ČEKEJTE NA 1 120 002
DIRTY_PAGE_POLL 1 197 119 977
XE_TIMER_EVENT 59 119 949

Opět zde není nic souvisejícího s XE, kromě XE_TIMER_EVENT .

Rozšířené události na cílový soubor s pomalou I/O cestou, bez ztráty události

Následující tabulka ukazuje dávkové požadavky před a po za sekundu při povolení relace XE s cílem souboru na USB klíčence, ale tentokrát bez povolení ztráty události (EVENT_RETENTION_MODE=NO_EVENT_LOSS) – což se nedoporučuje a uvidíte ve výsledcích, proč by to mohlo být:

Výchozí dávkové požadavky za sekundu
(průměr 2 minuty)
Dávkové požadavky SQL Profiler za sekundu
(průměr 2 minuty)
14 492 539

Nejčastější typy čekání byly následující:

wait_type waiting_tasks_count wait_time_ms
XE_BUFFERMGR_FREEBUF_EVENT 8 773 1 707 845
FT_IFTS_SCHEDULER_IDLE_WAIT 4 237 003
SLEEP_TASK 337 180 446
LAZYWRITER_SLEEP 120 120 032
DIRTY_PAGE_POLL 1 198 120 026
HADR_WORK_QUEUE 12 120 009
REQUEST_FOR_DEADLOCK_SEARCH 24 120 007
SQLTRACE_INCREMENTAL_FLUSH_SLEEP 30 120 006
ČEKEJTE NA 1 120 000
XE_TIMER_EVENT 59 119 944

S extrémním snížením propustnosti vidíme XE_BUFFERMGR_FREEBUF_EVENT skok na pozici číslo jedna v našich kumulovaných výsledcích čekací doby. Tento je dokumentováno v Books Online a Microsoft nám říká, že tato událost je spojena s relacemi XE nakonfigurovanými tak, aby nedocházelo ke ztrátě událostí a kde jsou všechny vyrovnávací paměti v relaci plné.

Vliv pozorovatele

Kromě typů čekání bylo zajímavé poznamenat, jaký dopad měla každá metoda pozorování na schopnost naší pracovní zátěže zpracovávat dávkové požadavky:


Vliv různých metod pozorování na dávkové požadavky za sekundu

U všech přístupů došlo k významnému – ale ne šokujícímu – zásahu ve srovnání s naší základní linií (žádné pozorování); nejvíce bolesti však bylo pociťováno při použití Profileru, při použití trasování na straně serveru k pomalé cestě I/O nebo rozšířených událostí k cíli souboru na pomalé cestě I/O – ale pouze při konfiguraci, aby nedošlo ke ztrátě události. Se ztrátou události se toto nastavení ve skutečnosti provádělo na stejné úrovni jako cíl souboru na rychlou cestu I/O, pravděpodobně proto, že dokázalo zahodit mnohem více událostí.

Shrnutí

Netestoval jsem všechny možné scénáře a určitě existují další zajímavé kombinace (nemluvě o různém chování na základě verze SQL Serveru), ale klíčový závěr, který si z tohoto průzkumu odnáším, je, že se nemůžete vždy spolehnout na zjevnou akumulaci typů čekání. ukazatel, když čelíte scénáři nad hlavou pozorovatele. Na základě testů v tomto příspěvku pouze tři ze sedmi scénářů vykazovaly konkrétní typ čekání, který by vám mohl pomoci nasměrovat správným směrem. Dokonce i tehdy – tyto testy probíhaly v řízeném systému – a často lidé filtrují výše uvedené typy čekání jako neškodné typy pozadí – takže je nemusíte vůbec vidět.

Vzhledem k tomu, co můžete dělat? Pro snížení výkonu bez jasných nebo zjevných příznaků doporučuji rozšířit rozsah, abyste se zeptali na trasování a relace XE (kromě toho doporučuji rozšířit rozsah, pokud je systém virtualizovaný nebo může mít nesprávné možnosti napájení). Například v rámci odstraňování problémů se systémem zkontrolujte sys.[traces] a sys.[dm_xe_sessions] abyste zjistili, zda v systému neběží něco neočekávaného. Je to další vrstva k tomu, o co se musíte starat, ale provedení několika rychlých ověření vám může ušetřit značné množství času.


  1. Připojte Javu k databázi MySQL

  2. Jak vytvořit omezení cizího klíče pomocí ON UPDATE CASCADE v SQL Server - SQL Server / Výukový program TSQL, část 79

  3. Velké objekty nelze použít v režimu automatického potvrzení

  4. Odpovídající všem hodnotám v klauzuli IN