sql >> Databáze >  >> RDS >> Sqlserver

Zámky SQL Server – další závory, o kterých byste měli vědět

Abych dokončil svou krátkou sérii článků o latch, tentokrát budu diskutovat o několika dalších latch na SQL Server, které můžete občas vidět, ale nezasloužíte si úplný článek. Jako obvykle důrazně doporučuji, abyste si přečetli první příspěvek v sérii před tímto, abyste měli všechny obecné základní znalosti o západkách.

Zámek LOG_MANAGER

Zámek LOG_MANAGER se používá pro synchronizaci během některých operací zahrnujících protokol transakcí a na databázi je jeden zámek LOG_MANAGER (protože každá databáze má svého vlastního správce protokolů). Lze jej získat pouze ve výhradním režimu a může být překážkou při růstu souboru protokolu transakcí. Scénář, kde se to projeví jako problém, je:

  • Soubor protokolu má malou sadu automatického růstu
  • Existuje mnoho souběžných připojení generujících záznamy protokolu transakcí
  • Soubor protokolu se musí neustále zvětšovat

Když v souboru protokolu dojde místo, bude se muset zvětšit. První vlákno, které si uvědomí, že je potřeba více místa pro protokol, získá západku LOG_MANAGER v režimu EX a pokračuje v rozšiřování souboru protokolu. Mnoho dalších vláken se nadále pokouší generovat záznamy protokolu a dostat se do fronty pro západku LOG_MANAGER, aby mohly rozšířit soubor protokolu. Když první vlákno uvolní západku, další ji dostane a uvědomí si, že log již narostl, tak jej zahodí a pokračuje. A tak dále a tak dále. Mimochodem, tento vzor úzkého hrdla se nazývá západkový konvoj .

Můžete si to představit jako přesně stejné úzké hrdlo jako u západky FGCB_ADD_REMOVE, o které jsem hovořil dříve v sérii, ale s růstem souboru protokolu namísto růstu datového souboru. Se západkou FGCB_ADD_REMOVE má však instance obvykle povolenou okamžitou inicializaci souboru, takže růst souboru je velmi rychlý, ale při západce LOG_MANAGER musí být protokol *musí* být inicializován nulou a čas ztracený ve frontě západek je delší. .

Řešení tohoto úzkého hrdla má tři části:

  1. Správně nastavte automatický růst souboru protokolu, aby se protokol často nezvětšoval
  2. Nastavte správnou velikost protokolu pro pracovní vytížení, takže by protokol neměl vůbec růst
  3. Ujistěte se, že se protokol správně čistí, takže protokol nemusí růst

Pokud jsou všechny na svém místě, neměli byste vidět, že západka LOG_MANAGER je běžným úzkým hrdlem, a více o tom mluvím ve svém příspěvku zde.

Zámek ACCESS_METHODS_DATASET_PARENT

Když se přistupuje k haldě nebo indexu, interně existuje objekt nazývaný HeapDataSetSession nebo IndexDataSetSession. Když se provádí paralelní skenování, každé vlákno provádějící skutečnou práci skenování má „podřízený“ datový soubor (další instance dvou objektů, které jsem právě popsal) a hlavní datový soubor, který skenování skutečně řídí, se nazývá „rodič.“

Když jedno z pracovních vláken skenování vyčerpalo sadu řádků, které má skenovat, potřebuje získat nový rozsah přístupem k nadřazené datové sadě, což znamená získat latch ACCESS_METHODS_DATASET_PARENT ve výhradním režimu. I když se to může zdát jako překážka, ve skutečnosti tomu tak není a nemůžete udělat nic, abyste zabránili tomu, aby vlákna provádějící paralelní skenování občas ukazovala LATCH_EX čekání na tuto západku.

Otázka, kterou byste si měli položit, zní:měl by tento dotaz především provádět paralelní skenování? Je zcela možné, že se stalo něco, co přinutilo plán dotazů zahrnout paralelní skenování, když to nemusí být nejefektivnější způsob, jak dotaz spustit. Příklady věcí, které by mohly způsobit změnu plánu na paralelní skenování, zahrnují:

  • Neaktuální statistiky
  • Chybějící nebo vynechaný neseskupený index
  • Nový kód vynucující skenování z důvodu implicitní konverze – nesouladu datového typu mezi sloupcem a proměnnou/parametrem, což vylučuje použití neshlukovaného indexu
  • Nový kód vynucující skenování, protože aritmetika se provádí na sloupci tabulky namísto proměnné/parametru, což opět vylučuje použití neshlukovaného indexu.
  • Dochází k nárůstu dat a skenování je skutečně tím nejefektivnějším plánem

Nebo je možné, že tento dotaz vyžaduje skenování, v takovém případě LATCH_EX čeká na ACCESS_METHODS_DATASET_PARENT jsou jen součástí vašeho prostředí.

Zámek ACCESS_METHODS_HOBT_VIRTUAL_ROOT

Každá instance této západky chrání záznam v metadatech Storage Engine pro b-strom, konkrétně ID stránky kořenové stránky b-stromu (stránky v horní části trojúhelníku, kterou obecně považujeme za index) . Konkrétně říkám b-strom a ne index , protože index může mít více oddílů, z nichž každý má b-strom (v podstatě část celkového indexu, ale s omezeními klíčů s nízkou hodnotou a vysokou hodnotou).

Pokaždé, když vlákno potřebuje procházet b-strom, musí začít na kořenové stránce a postupovat dolů na úroveň listu. Aby bylo možné číst metadata obsahující ID stránky kořenové stránky, musí vlákno získat západku ACCESS_METHODS_HOBT_VIRTUAL_ROOT v režimu SH, aby se zajistilo, že se ID stránky nemění. Když vlákno potřebuje změnit ID stránky kořenové stránky, musí získat západku v režimu EX.

Proč by se kořenová stránka b-stromu někdy měnila? Jak počet záznamů indexu na kořenové stránce roste, nakonec se zaplní a dojde k rozdělení stránky. Když k tomu dojde, aktuální kořenová stránka a stránka, na kterou se rozděluje, se stanou novou úrovní v b-stromu a vytvoří se zcela nová kořenová stránka se dvěma indexovými záznamy, které ukazují na starou kořenovou stránku a stránku, kterou rozdělit na. Nové ID kořenové stránky musí být zadáno do metadat, takže závora se získá v režimu EX. K tomu dojde několikrát rychle, jakmile se index na prázdné tabulce začne zaplňovat vložkami, ale není to něco, co byste považovali za problém trvalého omezení výkonu.

Shrnutí

Jak jsem si jist z této série, pochopení latch a latch úzkých hrdel vyžaduje vědět trochu více o tom, co se děje uvnitř Storage Engine, než pro obecnou analýzu statistik čekání.

Obvykle lidem radím, aby *ne* zahajovali odstraňování problémů s výkonem sledováním statistiky latch (přes sys.dm_os_latch_stats ), ale místo toho vždy začínat statistikou čekání (viz můj příspěvek zde) a ponořit se do latch pouze v případě, že LATCH_EX nebo LATCH_SH jsou jednou z horní hrstky čekání na instanci SQL Server.

Pokud máte nějaké dotazy ohledně západek, neváhejte mi napsat.


  1. Chyba při pokusu o načtení textu chyby ORA-01804

  2. Multi-Cloud Full Database Cluster Možnosti převzetí služeb při selhání pro MariaDB Cluster

  3. TNS-12505:TNS:listener aktuálně nezná SID uvedené v deskriptoru připojení

  4. Oracle 12c IDENTIFIKOVANÝ PODLE HODNOT