V minulých článcích jsme se převážně zabývali zámky. Na příkladech jste si mohli povšimnout situací, kdy dotazy čekají na uvolnění řádků v tabulce zamknutými jinými dotazy. Pokud bych to měl zobecnit, pak lze říci, že v architektuře celého počítače úlohy čekají na přidělení zdrojů, které potřebují pro dokončení své činnosti. Různé úlohy potřebují pro svůj běh různé zdroje. Systém eviduje čekající úlohy a poskytuje informaci, na co úloha čeká pomocí tzv. Waits. Pojďme se podívat, jak to celé funguje v SQL Serveru. Při dalším popisu se dopustím jistých zjednodušení, které snad nebudou na úkor pochopení celého principu.
Threads (Vlákna)
V dnešní době vícejádrových procesorů může být proces vykonáván několika jádry současně. K tomu aby proces mohl být rozdělen, je potřeba jej rozdělit na menší jednotky. Těmto jednotkám se říká vlákna. V žargonu SQL Serveru se jedná o Worker Threads. Některá vlákna jsou přímo určená pro zajištění systémových funkcí SQL Serveru jako např. vykonávání checkpointů, monitorování deadlocků atp. Jiná vlákna jsou určena pro zpracování požadavků klientů připojených k SQL Serveru.
Paralelismus
Označuje souběžné zpracování úlohy (resp. vláken) více jádry procesoru současně. Dochází tak k efektivnějšímu a rychlejšímu odbavení úloh. Arbitrem, který rozhoduje, zda daný SQL dotaz může být zpracováván paralelně, je Query Processor a následně Query Optimizer připraví paralelizovaný SQL plan.
Thread Scheduling (Plánování)
Plánovač se stará o řádné přidělování procesoru jednotlivým vláknům a kontroluje jeho přidělený čas. Řídí tedy čekající nebo běžící vlákna pro jedno procesorové jádro. Každé jádro procesoru má vlastní plánovač. Nyní se podíváme z čeho se plánovač skládá.
Processor
Provádí výpočty pouze pro jedno vlákno. Každému vláknu je přiděleno určité pevně dané množství procesorového času, které nelze měnit a můžeme jej nazvat časovým kvantem. Kvantum je dlouhé 4 milisekundy. Vlákna aktuálně běžící mají status RUNNING.
Waiter List
Seznam vláken, které čekají na uvolnění a přidělení nějakého zdroje, potřebného pro vlastní běh (disk pro ukládání/čtení dat, paměť pro ukládání mezivýsledků, atp.), se nazývá Waiter List. Vlákna nalézající se na tomto seznamu mají status SUSPENDED. Seznam není žádným způsobem setříděn a neexistuje zde žádná priorita. Nejsou zde ani žádné limity, jak dlouho zde vlákno může maximálně čekat. Seznam čekajících úloh si můžete zobrazit pomocí dotazu
SELECT * FROM sys.dm_os_waiting_tasks
Runnable Queue
Fronta vláken, jež mají alokovány všechny zdroje a pouze čekají, až dostanou přidělen procesorový čas pro svůj běh. Vlákna ve frontě mají status RUNNABLE. Vlastní fronta je typu FIFO (First-In-First-Out). Typickou ukázkou ze života je jakákoliv fronta v bance, na lístky u pokladní přepážky atp. Stejně jako i v běžném životě kde se můžete setkat s předbíháním ve frontě, tak i SQL Server má implementovanou prioritu (viz. Resource Governor).
Typický běh úlohy může být následující
Úloha „Zpracuj data“ potřebuje ke svému běhu dostupný soubor na disku, ze kterého bude číst data. Soubor je momentálně uzamčen jinou úlohou „Ulož data„, která do něj ukládá výsledky své práce. „Zpracuj data“ je přidán na Waiter List a zároveň je její status nastaven na Suspended.
Po ukončení „Ulož data“ je soubor uvolněn a úloha je přesunuta do fronty Runnable Queue a její status je změněn na Runnable.
Zatímco „Zpracuj data“ čeká, vystřídají se na procesoru všechny čekající úlohy, které byly do fronty zařazeny před „Zpracuj data„.
Jakmile je procesor uvolněn, může být úloha „Zpracuj data“ přesunuta na Processor a její status změněn na Running. Po vypršení časového kvanta 4ms je zpět přesunuta do fronty čekajících úloh na procesor. Takto se celý cyklus opakuje dokud není celá úloha zpracována.
V okamžiku, kdy úloha opět potřebuje číst data z disku a z nějakého důvodu je zdroj dat nedostupný, může být z Processoru přesunuta zpátky na Waiter List, kde bude opět čekat na uvolnění požadovaného zdroje.
Nyní se tedy dostáváme k tomu, proč se Waits stávají zajímavým ukazatelem výkonu SQL serveru. Jednotlivé typy nám mohou pomoci zjistit, proč SQL server zpracovává požadavky pomalu. Např. pokud se v systému objevuje často čekání na diskový subsystém, může to znamenat pomalé nebo přetížené disky. Nápravným opatřením může být zakoupení rychlejšího disku nebo oddělení a přesunutí datových souborů a transakčních logů na samostatné disky.
Přehled jednotlivých typů naleznete v dokumentaci pro dm_os_wait_stats