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

Západka DBCC_OBJECT_METADATA

Pokračujeme v mé sérii článků o latch, tentokrát budu diskutovat o latch DBCC_OBJECT_METADATA a ukážu, jak může být za určitých okolností hlavním úzkým hrdlem pro kontroly konzistence před SQL Server 2016. Problém se týká DBCC CHECKDB, DBCC CHECKTABLE a DBCC CHECKFILEGROUP, ale pro srozumitelnost budu ve zbytku tohoto příspěvku odkazovat pouze na DBCC CHECKDB.

Možná se divíte, proč píšu o problému, který se týká starších verzí, ale stále existuje velké množství SQL Server 2014 a starších instancí, takže je to platné téma pro mou sérii.

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.

Co je to DBCC_OBJECT_METADATA Latch?

Abych vysvětlil tuto západku, musím trochu vysvětlit, jak funguje DBCC CHECKDB.

Mezi obrovské množství kontrol konzistence, které DBCC CHECKDB provádí, je kontrola správnosti neklastrovaných indexů. Konkrétně DBCC CHECKDB zajišťuje:

  1. Pro každý neklastrovaný indexový záznam v každém neklastrovaném indexu existuje přesně jeden "odpovídající" datový záznam v základní tabulce (buď halda nebo seskupený index)
  2. Pro každý datový záznam v tabulce existuje přesně jeden "odpovídající" neklastrovaný indexový záznam v každém neklastrovaném indexu, který je pro tabulku definován, s přihlédnutím k filtrovaným indexům

Aniž bychom zacházeli do přílišné hloubky v podrobnostech toho, jak se to dělá, DBCC CHECKDB pro každý datový záznam v tabulce zkonstruuje každý neclusterovaný indexový záznam, který by měl existovat pro každý neclusterovaný index, a zajistí, že vytvořený neclusterovaný indexový záznam přesně odpovídá skutečnému neklastrovaný indexový záznam. Pokud má neclusterovaný index v sobě vypočítaný sloupec (buď jako součást neklastrovaného indexového klíče nebo jako INCLUDEd sloupec), musí DBCC CHECKDB zjistit vypočítanou hodnotu sloupce, která se použije při vytváření záznamů indexu.

Stejně jako kontroly správnosti neshlukovaného indexu, pokud přetrvává vypočítaný sloupec v definici tabulky, pak pro každý datový záznam v tabulce musí DBCC CHECKDB zkontrolovat, zda je trvalá hodnota správná, bez ohledu na to, zda je tento sloupec součástí neshlukovaného indexu nebo ne.

Jak tedy zjistí vypočítané hodnoty sloupců?

Procesor dotazů poskytuje mechanismus pro výpočet vypočtených hodnot sloupců, nazývaný „vyhodnocovač výrazů“. DBCC CHECKDB volá tuto funkci a poskytuje příslušné informace o metadatech a datovém záznamu a vyhodnocovač výrazů použije uloženou definici vypočítaného sloupce v metadatech a hodnoty z datového záznamu a vrátí hodnotu vypočítaného sloupce pro použití DBCC CHECKDB. . Interní fungování vyhodnocovače výrazu je mimo kontrolu kódu DBCC, ale aby bylo možné použít vyhodnocovač výrazu, je třeba nejprve získat západku; západka DBCC_OBJECT_METADATA.

Jak se západka stane úzkým hrdlem?

Zde je problém:existuje pouze jeden přijatelný režim, ve kterém lze před použitím vyhodnocování výrazů získat latch DBCC_OBJECT_METADATA, a to je režim EX (exkluzivní). A jak víte z přečtení úvodního příspěvku k sérii, v režimu EX může západku držet vždy pouze jedno vlákno.

Shrnutí všech těchto informací dohromady:když má databáze trvalé vypočítané sloupce nebo neshlukované indexy, které obsahují vypočítané sloupce, je třeba použít vyhodnocování výrazů. Pokud je SQL Server edice Enterprise, DBCC CHECKDB je schopen používat paralelismus, a tak má více vláken provádějících různé kontroly. A jakmile se několik vláken snaží získat závoru v režimu EX, stane se tato zádržka úzkým hrdlem. Jak velkým úzkým hrdlem se to stane, závisí na tom, jak moc je třeba použít vyhodnocovač výrazů, takže čím více trvalých vypočítaných sloupců nebo neshlukovaných indexů používajících vypočítané sloupce a čím větší je počet řádků tabulky v těchto tabulkách, tím větším úzkým hrdlem se stává západka DBCC _OBJECT_METADATA.

Pamatujte však, že k tomuto úzkému hrdlu dochází pouze u verzí SQL Server starších než SQL Server 2016. V SQL Server 2016 se Microsoft rozhodl „opravit“ úzké hrdlo tím, že ve výchozím nastavení vypnul kontroly neklastrovaných indexů pomocí vypočítaných sloupců a provedl je pouze v případě, že WITH Je použita možnost EXTENDED_LOGICAL_CHECKS.

Zobrazení úzkého místa

Úzké místo si můžete snadno reprodukovat sami spuštěním DBCC CHECKDB na databázi, která má buď trvalé vypočítané sloupce, nebo neshlukované indexy s vypočítanými sloupci, a skvělým příkladem je databáze AdventureWorks od společnosti Microsoft. Zde si můžete stáhnout zálohy AdventureWorks pro vaši verzi SQL Server. Provedl jsem několik testů pomocí databáze AdventureWorks2014 na instanci SQL Server 2014 (na 32jádrovém Dell R720) a pomocí Jonathanových skriptů jsem databázi zvětšil na několik set GB.

Když jsem spustil DBCC CHECKDB se serverem MAXDOP nastaveným na 0, spuštění trvalo více než 5 hodin. Typ čekání LATCH_EX představoval asi 30 % čekání, přičemž každé čekání bylo jen 1 milisekundu, a 99 % čekání LATCH_EX bylo na západku DBCC_OBJECT_METADATA.

Hledal jsem indexy bez klastrů obsahující vypočítané sloupce pomocí následujícího kódu:

SELECT [s].[jméno] AS [Schéma], [o].[jméno] AS [Objekt], [i].[jméno] AS [Index], [c].[jméno] AS [Sloupec ], [ic].* ZE sys.columns [c] PŘIPOJIT sys.index_columns [ic] ON [ic].[id_objektu] =[c].[id_objektu] AND [ic].[id_sloupce] =[c]. [id_sloupce] PŘIPOJIT SE k sys.indexes [i] ON [i].[id_objektu] =[ic].[id_objektu] A [i].[id_indexu] =[ic].[id_indexu] PŘIPOJIT SE k sys.objects [o] ZAPNUTO [i].[id_objektu] =[o].[id_objektu] PŘIPOJIT SE k sys.schemas [s] ZAPNUTO [o].[id_schématu] =[s].[id_schema] KDE [c].[je_vypočítáno] =1; 

Tento kód našel v databázi AdventureWorks2014 šest neklastrovaných indexů. Deaktivoval jsem všech šest indexů (pomocí ALTER INDEX … DISABLE) a znovu spustil DBCC CHECKDB a dokončil jsem to asi za 18 minut. Takže úzké hrdlo latch DBCC_OBJECT_METADATA bylo hlavním faktorem, který způsobil, že DBCC CHECKDB běžel více než 16krát pomaleji!

Shrnutí

Bohužel zakázání neklastrovaných indexů pomocí vypočítaných sloupců (a jejich pozdější opětovné povolení pomocí ALTER INDEX … REBUILD) je *jediný* způsob, jak odstranit úzké hrdlo latch DBCC_OBJECT_METADATA ve verzích před SQL Server 2016 při zachování všech ostatních funkcí DBCC. CHECKDB. Zakázání neklastrovaných indexů pravděpodobně není něco, co budete chtít dělat v produkčním prostředí, pokud nemáte okno údržby s nulovou aktivitou. To znamená, že pravděpodobně deaktivujete tyto neshlukované indexy, abyste odstranili úzké místo, pouze pokud jsou vaše kontroly konzistence přeneseny na jiný server pomocí metody backup-copy-restore-CHECKDB.

Dalším způsobem, jak to udělat, je použít možnost WITH PHYSICAL_ONLY při spuštění DBCC CHECKDB, ale pak přijdete o všechny hloubkové logické kontroly, takže nejsem velkým fanouškem doporučování jako řešení.


  1. SQL Query - zřetězení výsledků do jednoho řetězce

  2. Klonovat ORACLE_HOME

  3. Jak používat referenční kurzor Oracle z C# ODP.NET jako parametr ReturnValue bez použití uložené funkce nebo procedury?

  4. 12 Doporučené postupy zabezpečení MySQL/MariaDB pro Linux