To wystąpienie obsługuje bazy danych SharePoint 2007 (SP). Występuje wiele zakleszczeń SELECT / INSERT wobec jednej mocno wykorzystywanej tabeli w bazie danych zawartości SP. Zawęziłem zasoby, oba procesy wymagają blokady indeksu nieklastrowanego.
INSERT potrzebuje blokady IX w zasobie SELECT, a SELECT potrzebuje blokady S w zasobie INSERT. Wykres impasu przedstawia trzy zasoby: 1.) dwa z SELECT (równoległe wątki producent / konsument) i 2.) WSTAW.
Dołączyłem wykres impasu do twojej recenzji. Ponieważ jest to kod Microsoft i struktury tabel, nie możemy dokonywać żadnych zmian.
Jednak przeczytałem na stronie MSFT SP, że zalecają ustawienie opcji konfiguracji poziomu wystąpienia MAXDOP na 1. Ponieważ to wystąpienie jest współużytkowane przez wiele innych baz danych / aplikacji, ustawienia tego nie można wyłączyć.
Dlatego postanowiłem spróbować nie dopuścić do równoległości tych instrukcji SELECT. Wiem, że to nie jest rozwiązanie, ale bardziej tymczasowa modyfikacja, która pomaga w rozwiązywaniu problemów. Dlatego zwiększyłem „próg kosztu dla równoległości” z naszego standardowego 25 do 40, robiąc to, mimo że obciążenie się nie zmieniło (często pojawia się WYBIERZ / WSTAW) impasy zniknęły. Moje pytanie brzmi: dlaczego?
SPID 356 INSERT ma blokadę IX na stronie należącej do indeksu nieklastrowego
SPID 690 SELECT ID wykonania 0 blokuje S na stronie należącej do tego samego indeksu nieklastrowanego
Teraz
SPID 356 chce IX blokady na zasobie SPID 690, ale nie może go utrzymać, ponieważ SPID 356 jest blokowany przez SPID 690 ID wykonania 0 Blokada S
SPID 690 ID wykonania 1 chce blokady S na zasobu SPID 356, ale nie może go uzyskać, ponieważ identyfikator wykonania SPID 690 1 jest blokowany przez SPID 356, a teraz mamy impas.
Plan wykonania można znaleźć na mojej SkyDrive
Pełne szczegóły impasu można znaleźć tutaj
Jeśli ktoś może mi pomóc zrozumieć, dlaczego naprawdę to doceniam.
Tabela EventReceivers.
Identyfikator unikalny nr 16
Nazwa nvarchar nr 512
SiteId unikalny identyfikator nr 16
WebId unikalny identyfikator nr 16
HostId unikalny identyfikator nr 16
HostType int nr 4
ItemId int nr 4
DirName nvarchar nie 512
LiśćName nvarchar nr 256
Typ int nr 4
Sekwencja Numer int 4
Montaż nvarchar nr 512
Klasa nvarchar nie 512
Dane nvarchar nie 512
Filtr nvarchar nie 512
SourceId tContentTypeId nie 512
SourceType int nie 4
Referencje int nie 4
ContextType varbinary nr 16
ContextEventType varbinary no 16
ContextId varbinary no 16
ContextObjectId varbinary no 16
ContextCollectionId varbinary no 16
index_name index_description index_keys
EventReceivers_ByContextCollectionId nieklastrowany się na pierwotnych siteid, ContextCollectionId
EventReceivers_ByContextObjectId nieklastrowany się na pierwotnych siteid, ContextObjectId
EventReceivers_ById nieklastrowany, niepowtarzalny się na pierwotnych siteid, Id
EventReceivers_ByTarget skupione, niepowtarzalny się na pierwotnych siteid, WebId, hostid, HostType, typ, ContextCollectionId, ContextObjectId, ContextId, ContextType, ContextEventType, SequenceNumber, Assembly, Class
EventReceivers_IdUnique nieklastrowany, unikalny, unikalny klucz umieszczony na PODSTAWOWYM Id
źródło
proc_InsertEventReceiver
iproc_InsertContextEventReceiver
czego nie możemy zobaczyć w XDL? Również, aby zmniejszyć paralelizm, dlaczego po prostu nie wpłynąć bezpośrednio na tę instrukcję (za pomocą MAXDOP 1) zamiast na próżno z ustawieniami całego serwera?Odpowiedzi:
Na pierwszy rzut oka wygląda to jak klasyczny impas wyszukiwania . Podstawowymi składnikami tego impasu są:
SELECT
kwerenda, która używa zakaz obejmujący nieklastrowany indeks z kluczem LookupINSERT
zapytania, który modyfikuje klastra indeks i indeks nieklastrowanySELECT
Dostęp pierwszy indeks nieklastrowany, a następnie indeksu klastrowego.INSERT
Dostęp indeks klastra, potem indeks nieklastrowany. Dostęp do tych samych zasobów w innej kolejności i uzyskiwanie niekompatybilnych zamków jest oczywiście świetnym sposobem na osiągnięcie impasu.W takim przypadku
SELECT
zapytanie to:... a
INSERT
zapytanie brzmi:Zwróć uwagę na podświetloną na zielono obsługę indeksów nieklastrowych.
SELECT
Musielibyśmy zobaczyć wersję seryjną planu na wypadek, gdyby różniła się bardzo od wersji równoległej, ale jak zauważa Jonathan Kehayias w swoim przewodniku dotyczącym obsługi zakleszczeń, ten szczególny wzorzec zakleszczenia jest bardzo wrażliwy na szczegóły dotyczące czasu i wykonania wewnętrznego zapytania. Ten rodzaj impasu często przychodzi i odchodzi bez oczywistej przyczyny zewnętrznej.Biorąc pod uwagę dostęp do danego systemu i odpowiednie uprawnienia, jestem pewien, że w końcu moglibyśmy dokładnie ustalić, dlaczego impas występuje z planem równoległym, ale nie szeregowym (przyjmując ten sam ogólny kształt). Potencjalne kierunki śledztwa obejmują sprawdzanie zoptymalizowanych zagnieżdżonych pętli i / lub preselekcji - z których oba mogą wewnętrznie eskalacji poziom izolacji , aby
REPEATABLE READ
w czasie trwania zestawienia. Możliwe jest również, że pewna funkcja równoległego przypisywania zakresu wyszukiwania indeksu przyczynia się do tego problemu. Jeśli plan seryjny stanie się dostępny, mógłbym poświęcić trochę czasu na dalsze analizowanie szczegółów, ponieważ jest to potencjalnie interesujące.Zwykłym rozwiązaniem tego typu zakleszczenia jest sprawienie, by indeks był zakryty, chociaż liczba kolumn w tym przypadku może sprawić, że będzie to niepraktyczne (a poza tym nie powinniśmy zadzierać z takimi rzeczami w SharePoint, jak mi powiedziano). Ostatecznie zalecenie dotyczące planów tylko szeregowych przy korzystaniu z SharePoint istnieje z jakiegoś powodu (choć niekoniecznie dobrego, jeśli chodzi o to). Jeśli zmiana progu kosztu dla równoległości rozwiązuje problem w tej chwili, to dobrze. W dłuższej perspektywie prawdopodobnie chciałbym rozdzielić obciążenia, być może używając Resource Governor, aby wewnętrzne zapytania SharePoint uzyskały pożądane
MAXDOP 1
zachowanie, a druga aplikacja mogła korzystać z równoległości.Pytanie o wymiany pojawiające się w impasie wydaje mi się czerwonym śledziem; po prostu konsekwencja posiadania przez niezależne wątki zasobów, które technicznie muszą pojawić się w drzewie. Nie widzę nic, co sugerowałoby, że same wymiany przyczyniają się bezpośrednio do problemu impasu.
źródło
Jeśli byłby to klasyczny impas wyszukiwania , lista zasobów zawiera zarówno Indeks klastrowany, jak i Indeks nieklastrowany. Zazwyczaj WYBIERZ będzie trzymał blokadę SHARED na indeksie NC i czekał na blokadę SHARED na CI, tymczasem INSERT uzyska blokadę EXCLUSIVE na CI i czeka na blokadę EXCLUSIVE na NC. Lista zasobów w zakleszczonym pliku XML wyświetli oba te obiekty w tym przypadku.
Ponieważ wykres impasu obejmuje tylko Indeks NC, możemy wykluczyć tę opcję.
Ponadto, jeśli był to martwy zamek z powodu łączenia zagnieżdżonej pętli z NIEZGODNYM PREFETKIEM , plan wykonania powie nam, czy używany jest algorytm NIEPRZERWANY PREFETCH, co znowu nie ma miejsca (patrz aktualizacja poniżej).
To pozwala nam założyć, że jest to impas z powodu planu równoległego.
Wykres zakleszczenia nie jest poprawnie renderowany, ale jeśli spojrzysz na kod zakleszczenia XML, możesz zauważyć, że w impasie są zaangażowane dwa wątki z instrukcji SELECT (SPID 690). Wątek konsumenta trzyma blokadę SHARED na STRONIE 1219645 i czeka na producenta na porcie 801f8ed0 (e_waitPipeGetRow). Wątek producenta czeka na udostępnioną blokadę na STRONIE 1155940.
Instrukcja INSERT trzyma blokadę IX na STRONIE 1155940 i czeka na blokadę IX na STRONIE 1219645, co powoduje zakleszczenie.
Uważam, że impas zostanie uniknięty podczas korzystania z planu szeregowego instrukcji SELECT, ponieważ w żadnym momencie nie będzie wymagał blokady SHARED na więcej niż jednej stronie. Myślę też, że plan szeregowy będzie prawie taki sam jak plan równoległy (bez operatora równoległości).
[AKTUALIZACJA na podstawie komentarza Paula]
Najwyraźniej plan wykorzystuje OPTYMALIZOWANY algorytm zagnieżdżonej pętli
To wyjaśnia, dlaczego blokady SHARED są utrzymywane do końca instrukcji. POWTARZALNE CZYTANIE w połączeniu z planem równoległym jest bardziej narażone na zakleszczenie niż plan szeregowy, ponieważ plan równoległy może uzyskiwać i utrzymywać blokady z różnych zakresów indeksu, podczas gdy plan szeregowy uzyskuje blokady w bardziej sekwencyjny sposób.
źródło