SEÇME / EKLE Kilitlenme


10

Bu örnek, SharePoint 2007 veritabanlarını (SP) barındırır. SP içerik veritabanında yoğun olarak kullanılan bir tabloya karşı çok sayıda SELECT / INSERT kilitlenme yaşıyoruz. İlgili kaynakları daralttım, her iki işlem de kümelenmemiş dizin üzerinde kilit gerektiriyor.
INSERT, SELECT kaynağında bir IX kilidine ve SELECT, INSERT kaynağında bir S kilidine ihtiyaç duyar. Kilitlenme grafiği, 1.) SELECT'ten (üretici / tüketici paralel dişleri) ve 2.) INSERT'ten üç kaynak gösterir.
İncelemeniz için kilitlenme grafiğini ekledim. Bu Microsoft kodu ve tablo yapıları olduğundan herhangi bir değişiklik yapamayız.
Ancak, MSFT SP sitesinde MAXDOP Örnek düzeyi yapılandırma seçeneğini 1 olarak ayarlamanızı önermelerini okudum. Bu örnek diğer birçok veritabanı / uygulama arasında paylaşıldığı için bu ayar devre dışı bırakılamaz.


Bu nedenle, bu SELECT ifadelerinin paralel gitmesini engellemeye çalıştım. Bunun bir çözüm değil, sorun gidermeye yardımcı olacak daha fazla geçici bir değişiklik olduğunu biliyorum. Bu nedenle, iş yükü değişmemiş olsa bile (sık sık meydana gelen SELECT / INSERT) çıkmazlar ortadan kalkmış olsa da, “Paralellik için Maliyet Eşiği” ni standart 25'ten 40'a çıkardım. Sorum neden?

SPID 356 INSERT, kümelenmemiş dizine ait bir sayfada IX kilidine sahiptir
SPID 690 SELECT Yürütme Kimliği 0, aynı kümelenmemiş dizine ait bir sayfada S kilidine sahiptir

şimdi

SPID 356, SPID 690 kaynağında bir IX kilidi istiyor, ancak SPID 356 SPID 690 Yürütme Kimliği 0 tarafından kilitlendiğinden
SPX 690 Yürütme Kimliği 1, SPID 356 kaynağında bir S kilidi istiyor ancak SPID 690 Yürütme Kimliği nedeniyle bunu alamıyor. 1, SPID 356 tarafından engellendi ve şimdi kilitlenmemiz var.

Yürütme Planı SkyDrive'ımda bulunabilir

Tam Kilitlenme Ayrıntılarını burada bulabilirsiniz

Biri bana neden gerçekten minnettar olduğumu anlamama yardımcı olabilirse.

EventReceivers Tablosu.
Hiçbir 16 Uniqueidentifier Kimliği
hiçbir 512 nvarchar Adı
no 16 Uniqueidentifier siteid
WebId Uniqueidentifier hiçbir 16
HostID Uniqueidentifier hiçbir 16
HOSTTYPE int no 4
ItemId int no 4
Dirname nvarchar hayır 512
hayır 256 nvarchar LeafName
Tip int no 4
SequenceNumber int no 4
Montaj nvarchar hiçbir 512
Sınıf nvarchar no 512
Veri nvarchar no 512
Filtre nvarchar no 512
SourceId tContentTypeId no 512
SourceType int no 4
Kimlik bilgisi int no 4
ContextType varbinary no 16

ContextEventType varbinary no 16 ContextId varbinary no 16
ContextObjectId varbinary no 16
ContextCollectionId varbinary hayır 16

index_name index_description index_keys
EventReceivers_ByContextCollectionId kümelenmemiş İLKÖĞRETİM siteid üzerinde bulunan ContextCollectionId
EventReceivers_ByContextObjectId İLKÖĞRETİM siteid üzerinde, ContextObjectId bulunduğu kümelenmemiş
EventReceivers_ById, İLKÖĞRETİM siteid üzerinde bulunan kimliği benzersiz kümelenmemiş
İLKÖĞRETİM siteid, WebId, HostID, HOSTTYPE, Tür, ContextCollectionId, ContextObjectId üzerinde bulunan eşsiz, EventReceivers_ByTarget kümelenmiş, ContextId, ContextType, ContextEventType, SequenceNumber, Assembly, Class
EventReceivers_IdUnique PRIMARY Id'de bulunan kümelenmemiş, benzersiz, benzersiz anahtar


2
XDL'de göremediğimiz ne yapıyor proc_InsertEventReceiverve proc_InsertContextEventReceiveryapıyor? Ayrıca paralelliği azaltmak için neden sunucu genelindeki ayarlarla birleştirmek yerine bu ifadeyi (MAXDOP 1 kullanarak) doğrudan etkilemiyoruz?
Aaron Bertrand

1
Şiddetli MAXDOP ayarınızın ne olduğunu ve kaç işlemcinizin (mantıksal) olduğunu merak ediyorum. SharePoint gerçekten daha iyi çalışır ve MAXDOP sunucusu 1 genişliğinde bir sunucuda olmayı tercih eder. Sevmiyorum, ama bu şekilde geliştirdiler. Gerçek yürütme planlarını gönderebilir misiniz? Bu bağlantıda gördüğüm tek şey .xdl (kilitlenme grafiği)
Mike Walsh

Merhaba Beyler Yanıtlamak için yoğun programınızdan zaman ayırdığınız için teşekkür ederim. SkyDrive sitesinde incelemeniz için hem prosedürleri hem de yürütme planlarını yayınlayacağım. Ben MAXDOP (1) sorgu seçeneği dahil kod değiştirmeyi düşündüm, ancak bunu yapmak Microsoft ile desteğimizi geçersiz kılar. Fiziksel sunucu ProLiant DL580 G4 MAXDOP ayarı 4'tür ve toplam 8 fiziksel işlemci vardır ve H / T devre dışıdır.
SQLJarHead

Merhaba Beyler, SkyDrive'daki tüm detayları içeren bir zip paketi oluşturdum. Orijinal gönderinin gövdesini paketin URL'sini içerecek şekilde değiştirdim. Lütfen, sorunun ne olduğunu söyleme, sadece yol göster ve bana bunun için çalış. NOT: Temel şemada herhangi bir kod değişikliği veya DDL değişikliği yapamıyorum.
SQLJarHead

1
Yani, kodu değiştiremezsiniz ve şemayı değiştiremezsiniz, başka hangi çözümleri bulmamızı beklersiniz? Microsoft desteğini geçersiz kılmaktan endişe ediyorsanız, bu , Microsoft desteğiniz olduğunu gösterir; bu durumda - bize yapamayacağınızı söylediğiniz tüm kısıtlamalar göz önüne alındığında - Microsoft ile bir destek bileti açmayı düşündünüz mü?
Aaron Bertrand

Yanıtlar:


14

Yüzünde, bu klasik bir arama kilitlenmesine benziyor . Bu kilitlenme paterni için temel bileşenler şunlardır:

  • SELECTAnahtar Arama ile örtmeyen kümelenmemiş bir dizin kullanan bir sorgu
  • INSERTkümelenmiş dizini ve ardından kümelenmemiş dizini değiştiren bir sorgu

SELECTİlk kümelenmemiş endeksi, sonra kümelenmiş bir dizin erişir. INSERTErişim kümelenmiş dizin, sonra kümelenmemiş dizin. Uyumsuz kilitler elde ederek aynı kaynaklara farklı bir sırayla erişmek, elbette bir kilitlenme elde etmenin harika bir yoludur.

Bu durumda, SELECTsorgu:

Sorgu SEÇ

... ve INSERTsorgu:

INSERT sorgusu

Yeşil vurgulanan kümelenmemiş dizinlerin bakımına dikkat edin.

SELECTParalel versiyondan çok farklı olması durumunda planın seri versiyonunu görmemiz gerekecek , ancak Jonathan Kehayias , Deadlocks'u Kullanma kılavuzunda belirttiği gibi , bu özel kilitlenme deseni zamanlama ve dahili sorgu yürütme uygulama detaylarına çok duyarlıdır. Bu tür çıkmazlar genellikle belirgin bir dış sebep olmadan gelir ve gider.

İlgili sisteme erişim ve uygun izinler göz önüne alındığında, sonunda kilitlenmenin neden paralel planla oluştuğunu ancak seriyle değil (aynı genel şekli varsayarak) tam olarak çözebileceğimizden eminim. Soruşturma Potansiyel çizgileri optimize iç içe döngüler kontrol ve / veya ön yükleme içerir - her ikisi de dahili olarak yapabilirsiniz izolasyon seviyesini yükselmek için REPEATABLE READdeyimi süresince. Paralel dizin arama aralığı atamasının bazı özelliklerinin de soruna katkıda bulunması da mümkündür. Seri plan kullanılabilir hale gelirse, potansiyel olarak ilginç olduğu için ayrıntılara bakmak için biraz zaman harcayabilirim.

Bu tür bir kilitlenme için olağan çözüm, dizin kaplamasını yapmaktır, ancak bu durumda sütunların sayısı bunu pratik olmayabilir (ve ayrıca, SharePoint'te bu tür şeylerle uğraşmamamız gerekiyor). Nihayetinde, SharePoint kullanırken yalnızca seri planlar için öneri bir nedenden ötürü vardır (her ne kadar iyi olsa da, iyi bir plan değildir). Paralellik için maliyet eşiğindeki değişiklik , sorunu şimdilik çözüyorsa, bu iyidir. Daha uzun vadede, SharePoint iç sorgularının istenen MAXDOP 1davranışı almasını ve diğer uygulamanın paralelliği kullanabilmesi için belki de Kaynak Yöneticisi'ni kullanarak iş yüklerini ayırmak isterim .

Kilitlenme izinde ortaya çıkan borsalar sorunu benim için kırmızı bir ringa balığı gibi görünüyor; basitçe, teknik olarak ağaçta görünmesi gereken kaynaklara sahip olan bağımsız ipliklerin bir sonucu. Borsaların kendilerinin kilitlenme sorununa doğrudan katkıda bulunduğunu öne sürecek hiçbir şey göremiyorum.


6

Bu klasik bir arama çıkmazıysa , kaynak listesinde hem Kümelenmiş Dizin hem de Kümelenmemiş Dizin bulunur. Tipik olarak SELECT, NC dizininde PAYLAŞILAN bir kilit tutacak ve CI'da PAYLAŞILAN bir kilit bekleyecek, bu arada INSERT CI üzerinde ÖZEL bir kilit alacak ve NC'de ÖZEL bir kilit bekleyecektir. Deadlock xml içindeki kaynak listesi, bu durumda her iki nesneyi de listeler.

Kilitlenme grafiği yalnızca NC Dizini içerdiğinden, bu seçeneği göz ardı edebiliriz.

Ayrıca, UNORDERED PREFETCH ile İç İçe Döngü Birleştirme nedeniyle ölü bir kilitse , yürütme planı bize, burada yine geçerli olmayan UNORDERED PREFETCH algoritmasının kullanılıp kullanılmadığını söyleyecektir (aşağıdaki güncellemeye bakın).

Bu , Paralel Plan nedeniyle bunun bir kilitlenme olduğunu varsaymamızı sağlar .

Kilitlenme grafiği düzgün oluşturulmuyor, ancak Kilitlenme XML'sine bakarsanız, SELECT deyiminden (SPID 690) iki iş parçacığının kilitlenmeye karıştığını görebilirsiniz. Tüketici iş parçacığı PAGE 1219645 üzerinde bir SHARED kilidi tutuyor ve port801f8ed0 (e_waitPipeGetRow) üzerinde üreticiyi bekliyor. Üretici iş parçacığı, PAGE 1155940 üzerinde paylaşılan bir kilit bekliyor.

INSERT deyimi, PAGE 1155940 üzerinde bir IX kilidi tutuyor ve PAGE 1219645'te bir IX kilidini bekleyerek bir kilitlenmeye neden oluyor.

SELECT deyimi için bir seri plan kullanırken bir kilitlenmenin önleneceğine inanıyorum çünkü hiçbir noktada birden fazla sayfada PAYLAŞILAN kilit gerektirecektir. Seri planın paralel planla hemen hemen aynı olacağını düşünüyorum (paralellik operatörü sans).

[Paul'ün yorumuna göre GÜNCELLENDİ]

Görünüşe göre plan bir OPTIMIZED Nested Loop algoritması kullanıyor

Bu ifadenin sonuna kadar PAYLAŞILAN kilitlerin neden tutulduğunu açıklar. TEKRARLANABİLİR READ, paralel plan ile birleştirildiğinde, kilitli plan bir seri plandan daha savunmasızdır, çünkü paralel plan bir dizinin farklı aralıklarından kilitler alıp tutabilirken, seri plan kilitleri daha ardışık bir şekilde elde edebilir.


Kabul. Bu kilitlenme gerçek bir LOOKUP ile ilgiliyse, SELECT için bekleme kaynağı kümelenmiş dizine başvururdu. DBCC PAGE üzerinden sayfa üstbilgisini (SPID 690 Bekleme Kaynağı = SAYFA: 1155940 | SPID 356 Bekleme Kaynağı = SAYFA 1219645) sayfa üstbilgisini görüntüleyerek bunu ekleyebildim ve her ikisi de dizin kimliği 5 (IndexID 5 = EventReceivers_ByContextObjectId) üzerinde Belirtilen tablodaki NC dizinini gösterir (EventReceivers).
SQLJarHead

Beyler, Bu ilginç sorunun analiz edilmesine yardımcı olmak için zaman ayırdığınız için tekrar teşekkür ederiz. Birkaç soru: 1.) Roji, paralel SPID'nin birden fazla sayfa istediğine dikkat çekiyor. Bunu hiçbir infaz planında görmüyorum. Satır sayısına bakıldığında, INDEX SEEK operatörü için, iki üreticiden sadece bir iş parçacığı herhangi bir satırı işliyor. Birden fazla sayfa istediğini nasıl belirlediniz? (1/2)
SQLJarHead

2.) OPTIMIZED Nested Loop algoritması, izolasyon seviyesini her zaman REAPTABLE READ olarak ayarlayacak mı? Yürütme planları XML çıktısını kontrol ettim ve yalnızca SPID bağlantısı için okundu bilgisi görüyorum. Bunun yalnızca plan operatörü düzeyinde çağrıldığını varsayıyorum. (2/2)
SQLJarHead

OPTIMIZED Nested Loops'un kilitleme davranışı REPEATABLE READ ile karşılaştırılabilir ( ifadenin sonuna kadar kilitleri tutar ), ancak işlemin yalıtım düzeyini REPEATABLE READ olarak ayarlar. Sanırım bu senin soruna bir cevap veriyor. Paralel iş parçacıkları aynı anda birden fazla sayfa istiyor değil, ancak bir paralel iş parçacığı bir sayfada kilit tutuyor ve başka bir iş parçacığı başka bir sayfada kilit bekliyor
Roji P Thomas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.