За да завърша кратката си поредица от статии за ключалки, този път ще обсъдя няколко други ключалки в SQL Server, които може да видите от време на време, но не заслужават пълна статия сами по себе си. Както обикновено, силно ви препоръчвам да прочетете първоначалната публикация от поредицата преди тази, за да имате всички основни основни познания за ключалките.
Резето на LOG_MANAGER
Ключалката LOG_MANAGER се използва за синхронизация по време на някои операции, включващи регистрационния файл на транзакциите, и има едно LOG_MANAGER ключалка за база данни (тъй като всяка база данни има свой собствен мениджър на регистрационни файлове). Той може да бъде придобит само в изключителен режим и може да бъде пречка по време на растежа на регистрационния файл на транзакциите. Сценарият, при който ще стане очевиден като проблем, е:
- Регистрационният файл има малък набор за автоматично нарастване
- Има много едновременни връзки, генериращи записи в регистъра на транзакциите
- Регистрационният файл продължава да се увеличава
Когато регистрационният файл свърши без място, той ще трябва да нарасне. Първата нишка, която реализира повече пространство в регистрационния файл, придобива фиксатора LOG_MANAGER в режим EX и продължава да увеличава регистрационния файл. Много други нишки продължават да се опитват да генерират регистрационни записи и да влязат в опашката за ключалката LOG_MANAGER, за да могат да разрастват регистрационния файл. Когато първата нишка освободи ключалката, следващата я получава и разбира, че трупът вече е нараснал, така че го пуска и продължава. И така нататък и така нататък. Между другото, този модел на тесни места се нарича конвой с фиксатор .
Можете да го мислите като точно същото тесно място, както с ключалката FGCB_ADD_REMOVE, която обсъдих по-рано в поредицата, но с нарастване на регистрационния файл вместо нарастване на файл с данни. Въпреки това, с ключалката FGCB_ADD_REMOVE, обикновено екземплярът има активирана мигновена инициализация на файла, така че растежът на файла е много бърз, но с ключалката LOG_MANAGER дневникът *трябва* да бъде инициализиран с нула и времето, загубено в опашката за заключване е по-дълго .
Решението за това затруднение се състои от три части:
- Настройте правилно автоматичното нарастване на регистрационния файл, така че регистрационният файл да не нараства често
- Оразмерете регистрационния файл правилно за работното натоварване, така че дневникът изобщо не трябва да нараства
- Уверете се, че регистрационният файл се изчиства правилно, така че не е необходимо да се увеличава
Ако всички те са на място, не би трябвало да виждате, че ключалката на LOG_MANAGER е редовно тесно място и аз говоря повече за това в публикацията си тук.
Резето ACCESS_METHODS_DATASET_PARENT
Когато се осъществява достъп до хийп или индекс, вътрешно има обект, наречен съответно HeapDataSetSession или IndexDataSetSession. Когато се извършва паралелно сканиране, всяка нишка, извършваща действителната работа на сканирането, има „детски“ набор от данни (друг екземпляр от двата обекта, които току-що описах), а основният набор от данни, който наистина контролира сканирането, се нарича „родителя“.
Когато една от работните нишки за сканиране е изчерпала набора от редове, които трябва да сканира, тя трябва да получи нов диапазон чрез достъп до родителския набор от данни, което означава придобиване на ключалката ACCESS_METHODS_DATASET_PARENT в изключителен режим. Въпреки че това може да изглежда като пречка, всъщност не е и не можете да направите нищо, за да спрете нишките, извършващи паралелно сканиране, от време на време да показват LATCH_EX изчакване за това ключалка.
Въпросът, който трябва да си зададете, е:трябва ли тази заявка да извършва паралелно сканиране на първо място? Напълно възможно е нещо да се е случило, за да принуди плана на заявката да включва паралелно сканиране, когато това може да не е най-ефективният начин за изпълнение на заявката. Примери за неща, които могат да доведат до промяна на плана към паралелно сканиране, включват:
- Неактуални статистически данни
- Липсващ или отпаднал неклъстериран индекс
- Нов код, който принуждава сканиране поради имплицитно преобразуване – несъответствие на типа данни между колона и променлива/параметър, което изключва използването на неклъстериран индекс
- Нов код принудително сканиране, тъй като аритметика се извършва върху колона на таблица вместо променлива/параметър, което отново изключва използването на неклъстериран индекс
- Нарастването на данните и сканирането наистина е най-ефективният план
Или може да се окаже, че тази заявка изисква сканиране, в който случай LATCH_EX чака ACCESS_METHODS_DATASET_PARENT са само част от вашата среда.
Резето ACCESS_METHODS_HOBT_VIRTUAL_ROOT
Всеки екземпляр на това ключалка защитава запис в метаданните на Storage Engine за b-дърво, по-специално идентификатора на страницата на основната страница на b-дървото (страницата в горната част на триъгълника, която обикновено смятаме за индекс) . Специално казвам b-tree а не индекс , тъй като индексът може да има множество дялове, всеки от които има b-дърво (по същество част от общия индекс, но с ключови ограничения с ниска и висока стойност).
Всеки път, когато дадена нишка трябва да премине през b-дърво, тя трябва да започне от основната страница и да стигне до нивото на листа. За да прочете метаданните, съдържащи идентификатора на страницата на основната страница, нишката трябва да придобие ключалката ACCESS_METHODS_HOBT_VIRTUAL_ROOT в режим SH, за да се увери, че идентификационният номер на страницата не е в процес на промяна. Когато дадена нишка трябва да промени идентификатора на страницата на основната страница, тя трябва да придобие ключалката в режим EX.
Защо основната страница на b-дървото някога би се променила? Тъй като броят на индексните записи в основната страница нараства, в крайна сметка тя ще се запълни и ще настъпи разделяне на страницата. Когато това се случи, текущата основна страница и страницата, на която тя се разделя, стават ново ниво в b-дървото и се създава чисто нова основна страница с два индексни записа, сочещи към старата основна страница и страницата, която тя разделени на. Новият идентификатор на основна страница трябва да бъде въведен в метаданните, така че ключалката се придобива в режим EX. Това ще се случи няколко пъти бързо, тъй като индексът на празна таблица започне да се попълва от вмъквания, но не е нещо, което ще видите като текущ проблем с производителността.
Резюме
Както съм сигурен, че сте разбрали от тази поредица, разбирането на ключалки и тесни места на ключалки включва да знаете малко повече за това какво се случва вътре в Storage Engine, отколкото за общ анализ на статистиката за чакане.
Обикновено съветвам хората *не* да започват отстраняване на неизправности с производителността, като гледат статистически данни за ключалката (чрез sys.dm_os_latch_stats ), но вместо това винаги да започвате със статистически данни за изчакване (вижте публикацията ми тук) и да задълбавате само в ключалки, ако LATCH_EX или LATCH_SH са едни от най-големите шепа изчаквания в екземпляра на SQL Server.
Ако имате въпроси относно ключалките, не се колебайте да ми пишете.