Azure SQL Veritabanı'de kilitlenmeleri analiz etme ve önleme

Şunlar için geçerlidir:Azure SQL Veritabanı

Bu makalede Azure SQL Veritabanı’ndaki kilitlenmeleri tanımlama, kilitlenme grafiklerini ve Sorgu Deposu'nu kullanarak kilitlenmedeki sorguları tanımlama ve kilitlenmelerin yeniden oluşmasını önlemek için gerekli değişiklikleri planlama ve test etme adımları öğretilir.

Bu makale kilit çekişmesi nedeniyle kilitlenmeleri tanımlamaya ve analiz etmeye odaklanmaktadır. Kaynaklarda kilitlenmeye neden olabilecek diğer kilitlenme türleri hakkında daha fazla bilgi edinin.

Azure SQL Veritabanı'de kilitlenmeler nasıl oluşur?

Azure SQL Veritabanı'daki her yeni veritabanında varsayılan olarak etkin okuma işlemi yapılan anlık görüntü (RCSI) veritabanı ayarı vardır. Eşzamanlılığı artırmak için satır sürümü oluşturma kullanan RCSI altında, verileri okuyan oturumlar ve veri yazan oturumlar arasında engelleme en aza indirilir. Ancak, engelleme ve kilitlenmeler Azure SQL Veritabanı veritabanlarında yine oluşabilir çünkü:

  • Verileri değiştiren sorgular birbirlerini engelleyebilir.
  • Sorgular, engellemeyi artıran yalıtım düzeyleri altında çalıştırılabilir. Yalıtım düzeyleri Transact-SQL'de istemci kitaplığı yöntemleri, sorgu ipuçları veya SET deyimleri aracılığıyla belirtilebilir.
  • RCSI devre dışı bırakılabilir, bu da veritabanının okuma işlemi yapılan yalıtım düzeyi altında çalışan SELECT deyimlerini korumak için paylaşılan (S) kilitleri kullanmasına neden olabilir. Bu, engelleme ve kilitlenmeleri artırabilir.

Örnek kilitlenme

İki veya daha fazla görev birbirini kalıcı olarak engellediğinde kilitlenme oluşur çünkü her görevin diğer görevin kilitlemeye çalıştığı bir kaynak üzerinde kilidi vardır. Kilitlenme, döngüsel bağımlılık olarak da adlandırılır: İki görevli kilitlenme durumunda A işleminin B işlemine bağımlılığı vardır ve B işlemi A işlemine bağımlı olarak daireyi kapatır.

Örnek:

  1. Oturum A , açık bir işlem başlatır ve tablodaki SalesLT.Productbir satırda özel (X) kilidine dönüştürülen bir güncelleştirme (U) kilidi alan bir güncelleştirme deyimi çalıştırır.
  2. Oturum B , tabloyu değiştiren SalesLT.ProductDescription bir güncelleştirme deyimi çalıştırır. Update deyimi, güncelleştirilecek SalesLT.Product doğru satırları bulmak için tabloya katılır.
    • Oturum B , tablodaki 72 satırda SalesLT.ProductDescription bir güncelleştirme (U) kilidi alır.
    • Oturum B'de, A Oturumu tarafından kilitlenen satır da dahil olmak üzere tablodaki SalesLT.Productsatırlarda paylaşılan bir kilit gerekir. Oturum B üzerinde SalesLT.Productengellendi.
  3. A oturumu işlemine devam eder ve şimdi tabloda bir güncelleştirme SalesLT.ProductDescription çalıştırır. Oturum A , üzerindeki SalesLT.ProductDescriptionOturum B tarafından engellendi.

A diagram showing two sessions in a deadlock. Each session owns a resource that the other process needs in order to continue.

Bir kilitlenmedeki tüm işlemler, oturumun sonlandırılması gibi sebeplerle katılan işlemlerden biri geri alınmadığı sürece süresiz olarak bekler.

Veritabanı altyapısı kilitlenme izleyicisi, kilitlenme içindeki görevleri düzenli aralıklarla denetler. Kilitlenme izleyicisi döngüsel bağımlılık algılarsa, görevlerden birini kurban olarak seçer ve "İşlem (İşlem Kimliği N) başka bir işlemle kilit kaynaklarına kilitlendi ve kilitlenme kurbanı olarak seçildi" hatasını 1205 ile sonlandırır. İşlemi yeniden çalıştırın." Kilitlenmeyi bu şekilde bozmak, kilitlenmedeki diğer görev veya görevlerin işlemlerini tamamlayabilmesini sağlar.

Dekont

Bu makalenin Kilitlenme işlemi listesi bölümünde kilitlenme kurbanı seçme ölçütleri hakkında daha fazla bilgi edinin.

Overview of a deadlock between two sessions. One session has been chosen as the deadlock victim.

Kilitlenme kurbanı olarak seçilen işlemi içeren uygulamanın işlemi yeniden denemesi gerekir. Bu işlem genellikle kilitlenmeye dahil olan diğer işlem veya işlemler tamamlandıktan sonra tamamlanmalıdır.

Aynı kilitlenmeyle tekrar karşılaşmamak için yeniden denemeden önce kısa, rastgele bir gecikme uygulamak en iyi yöntemdir. Geçici hatalar için yeniden deneme mantığı tasarlama hakkında daha fazla bilgi edinin.

Azure SQL Veritabanı'de varsayılan yalıtım düzeyi

Azure SQL Veritabanı'deki yeni veritabanları varsayılan olarak okuma işlemi yapılan anlık görüntüyü (RCSI) etkinleştirir. RCSI, SELECT deyimleri için paylaşılan (S) kilitleri kullanılmadan deyim düzeyinde tutarlılık sağlamak üzere satır sürümü oluşturma kullanmak üzere okuma işlemi yapılan yalıtım düzeyinin davranışını değiştirir.

RCSI etkinken:

  • Verileri okuyan deyimler, verileri değiştiren deyimleri engellemez.
  • Verileri değiştiren deyimler, verileri okuyan deyimleri engellemez.

Anlık görüntü yalıtım düzeyi, Azure SQL Veritabanı'daki yeni veritabanları için de varsayılan olarak etkinleştirilir. Anlık görüntü yalıtımı, veriler için işlem düzeyi tutarlılığı sağlayan ve güncelleştirilecek satırları seçmek için satır sürümlerini kullanan ek bir satır tabanlı yalıtım düzeyidir. Anlık görüntü yalıtımını kullanmak için sorguların veya bağlantıların işlem yalıtım düzeyini açıkça olarak olarak SNAPSHOTayarlaması gerekir. Bu yalnızca veritabanı için anlık görüntü yalıtımı etkinleştirildiğinde yapılabilir.

RCSI ve/veya anlık görüntü yalıtımının Transact-SQL ile etkinleştirilip etkinleştirilmediğini belirleyebilirsiniz. Azure SQL Veritabanı'da veritabanınıza Bağlan ve aşağıdaki sorguyu çalıştırın:

SELECT name, is_read_committed_snapshot_on, snapshot_isolation_state_desc
FROM sys.databases
WHERE name = DB_NAME();
GO

RCSI etkinleştirilirse, is_read_committed_snapshot_on sütun 1 değerini döndürür. Anlık görüntü yalıtımı etkinleştirilirse, snapshot_isolation_state_desc sütun ON değerini döndürür.

rcsi Azure SQL Veritabanı bir veritabanı için devre dışı bırakıldıysa, yeniden etkinleştirmeden önce RCSI'nin neden devre dışı bırakıldığını araştırın. Veri yazan sorgular tarafından veri okuyan sorguların engellenmesi ve RCSI etkinleştirildiğinde yarış koşullarından yanlış sonuçlar alınması beklenirken uygulama kodu yazılmış olabilir.

Kilitlenme olaylarını yorumlama

Azure SQL Veritabanı'da kilitlenme yöneticisi bir kilitlenme algıladıktan ve kurban olarak bir işlem seçtikten sonra bir kilitlenme olayı yayılır. Başka bir deyişle, kilitlenmeler için uyarılar ayarlarsanız, tek bir kilitlenme çözüldükten sonra bildirim tetiklenir. Bu kilitlenme için yapılması gereken bir kullanıcı eylemi yoktur. Uygulamalar, 1205 hatasını aldıktan sonra otomatik olarak devam edebilmeleri için yeniden deneme mantığını içerecek şekilde yazılmalıdır: "İşlem (İşlem Kimliği N), kilit kaynaklarında başka bir işlemle kilitlendi ve kilitlenme kurbanı olarak seçildi. İşlemi yeniden çalıştırın."

Ancak kilitlenmeler yeniden oluşa kadar uyarıları ayarlamak yararlı olur. Kilitlenme uyarıları, veritabanınızda yinelenen bir kilitlenme düzeni olup olmadığını araştırmanıza olanak tanır. Bu durumda, kilitlenmelerin yeniden oluşmasını önlemek için eylem gerçekleştirmeyi seçebilirsiniz. Uyarı oluşturma hakkında daha fazla bilgi edinmek için bu makalenin İzleme ve kilitlenmeler hakkında uyarı oluşturma bölümüne bakın.

Kilitlenmeleri önlemeye yönelik en iyi yöntemler

Kilitlenmelerin yeniden oluşmasını önlemeye yönelik en düşük risk yaklaşımı genellikle kilitlenmeye dahil olan sorguları iyileştirmek için kümelenmemiş dizinleri ayarlamaktır.

  • Bu yaklaşımda risk düşüktür çünkü kümelenmemiş dizinlerin ayarlanması sorgu kodunun kendisinde değişiklik yapılmasını gerektirmez ve Transact-SQL yeniden yazılırken kullanıcıya yanlış veri döndürülmesine neden olan kullanıcı hatası riskini azaltır.
  • Etkin bir şekilde kümelenmemiş dizin ayarlama, sorguların okunacak verileri bulmasına ve daha verimli bir şekilde değiştirilmesine yardımcı olur. Sorgunun erişmesi gereken veri miktarını azaltarak engelleme olasılığı azalır ve kilitlenmeler genellikle önlenebilir.

Bazı durumlarda, kümelenmiş dizin oluşturmak veya ayarlamak engelleme ve kilitlenmeleri azaltabilir. Kümelenmiş dizin tüm kümelenmemiş dizin tanımlarına dahil edildiğinden, kümelenmiş dizin oluşturma veya değiştirme işlemi, mevcut kümelenmemiş dizinlere sahip daha büyük tablolarda yoğun GÇ ve zaman alan bir işlem olabilir. Kümelenmiş dizin tasarımı yönergeleri hakkında daha fazla bilgi edinin.

Dizin ayarlaması kilitlenmeleri önlemede başarılı olmadığında, diğer yöntemler kullanılabilir:

  • Kilitlenme yalnızca kilitlenmeye dahil olan sorgulardan biri için belirli bir plan seçildiğinde oluşursa, sorgu planını Sorgu Deposu ile zorlamak kilitlenmelerin yeniden oluşmasını engelleyebilir.
  • Kilitlenmeye dahil olan bir veya daha fazla işlem için Transact-SQL'in yeniden yazılması da kilitlenmeleri önlemeye yardımcı olabilir. Açık işlemleri daha küçük işlemlere ayırmak, eşzamanlı değişiklikler gerçekleştiğinde veri geçerliliğini sağlamak için dikkatli bir kodlama ve test gerektirir.

Bu makalenin Kilitlenmenin yeniden oluşmasını önleme bölümünde bu yaklaşımların her biri hakkında daha fazla bilgi edinin.

Kilitlenmeleri izleme ve uyarı

Bu makalede, kilitlenmeler için uyarılar ayarlamak, örnek bir kilitlenmeye neden olmak, örnek kilitlenme için kilitlenme grafiğini analiz etmek ve kilitlenmenin yeniden oluşmasını önlemek için değişiklikleri test etmek için örnek veritabanını kullanacağız AdventureWorksLT .

Kilitlenme graflarını etkileşimli bir görsel modda görüntüleme işlevselliği içerdiğinden bu makalede SQL Server Management Studio (SSMS) istemcisini kullanacağız. Örnekleri takip etmek için Azure Data Studio gibi diğer istemcileri kullanabilirsiniz, ancak kilitlenme grafiklerini yalnızca XML olarak görüntüleyebilirsiniz.

AdventureWorksLT veritabanını oluşturma

Örnekleri takip etmek için Azure SQL Veritabanı'da yeni bir veritabanı oluşturun ve Veri kaynağı olarak Örnek veriler'i seçin.

Azure portalı, Azure CLI veya PowerShell ile oluşturma AdventureWorksLT hakkında ayrıntılı yönergeler için Hızlı Başlangıç: Azure SQL Veritabanı tek veritabanı oluşturma başlığı altında tercih edilen yaklaşımı seçin.

Azure portalında kilitlenme uyarılarını ayarlama

Kilitlenme olaylarına yönelik uyarılar ayarlamak için Azure portalını kullanarak Azure SQL Veritabanı ve Azure Synapse Analytics için uyarılar oluşturma makalesindeki adımları izleyin.

Uyarının sinyal adı olarak Kilitlenmeler'i seçin. Eylem grubunu, e-posta/SMS/Gönderme/Ses eylem türü gibi tercih ettiğiniz yöntemi kullanarak sizi bilgilendirecek şekilde yapılandırın.

Genişletilmiş Olaylar ile Azure SQL Veritabanı kilitlenme grafiklerini toplama

Kilitlenme grafikleri, kilitlenmeye dahil olan süreçler ve kilitlerle ilgili zengin bir bilgi kaynağıdır. Azure SQL Veritabanı Genişletilmiş Olaylar (XEvents) ile kilitlenme grafikleri toplamak için olayı yakalayınsqlserver.database_xml_deadlock_report.

Kademe arabelleği hedefini veya olay dosyası hedefini kullanarak XEvents ile kilitlenme grafikleri toplayabilirsiniz. Uygun hedef türünü seçmeyle ilgili dikkat edilmesi gerekenler aşağıdaki tabloda özetlenir:

Yaklaşım Sosyal haklar Dikkat edilmesi gerekenler Kullanım senaryoları
Kademe arabelleği hedefi
  • Yalnızca Transact-SQL ile basit kurulum.
  • XEvents oturumu veritabanını çevrimdışına alma veya veritabanı yük devretmesi gibi herhangi bir nedenle durdurulduğunda olay verileri temizlenir.
  • Veritabanı kaynakları, halka arabelleğindeki verileri korumak ve oturum verilerini sorgulamak için kullanılır.
  • Test ve öğrenme için örnek izleme verileri toplayın.
  • Hemen bir olay dosyası hedefi kullanarak oturum ayarlayamıyorsanız kısa vadeli gereksinimler için oluşturun.
  • İzleme verilerini bir tabloda kalıcı hale getirmek için otomatik bir işlem ayarladığınızda izleme verileri için "giriş bölmesi" olarak kullanın.
Olay dosyası hedefi
  • Azure Depolama'da olay verilerini bir blobda kalıcı hale getirmek için oturum durdurulduktan sonra bile kullanılabilir.
  • Olay dosyaları Azure portalından veya Azure Depolama Gezgini indirilebilir ve yerel olarak analiz edilebilir; bu, oturum verilerini sorgulamak için veritabanı kaynaklarının kullanılmasını gerektirmez.
  • Kurulum daha karmaşıktır ve Azure Depolama kapsayıcısının ve veritabanı kapsamlı kimlik bilgilerinin yapılandırılması gerekir.
  • Olay oturumu durdurulduğunda bile olay verilerinin kalıcı olmasını istediğinizde genel kullanım.
  • Bellekte kalıcı olmasını istediğinizden daha fazla miktarda olay verisi oluşturan bir izleme çalıştırmak istiyorsunuz.

Kullanmak istediğiniz hedef türü seçin:

Halka arabelleği hedefi kolay ve kurulumu kolaydır, ancak sınırlı kapasiteye sahiptir ve bu da eski olayların kaybolmasına neden olabilir. Kademe arabelleği olayları depolamada kalıcı yapmaz ve XEvents oturumu durdurulduğunda halka arabelleği hedefi temizlenir. Bu, veritabanı altyapısı yük devretme gibi herhangi bir nedenle yeniden başlatıldığında toplanan XEvent'lerin kullanılamayacağı anlamına gelir. Bir olay dosyası hedefine hemen XEvents oturumu ayarlama olanağınız yoksa kademe arabelleği hedefi öğrenme ve kısa vadeli gereksinimler için en uygun yöntemdir.

Bu örnek kod, halka arabellek hedefini kullanarak bellekteki kilitlenme grafiklerini yakalayan bir XEvents oturumu oluşturur. Kademe arabelleği hedefi için izin verilen bellek üst sınırı 4 MB'tır ve veritabanı çevrimiçi olduğunda (örneğin, yük devretme sonrasında) oturum otomatik olarak çalışır.

Kademe arabelleği hedefine yazan olay için bir XEvents oturumu oluşturmak ve başlatmak için sqlserver.database_xml_deadlock_report veritabanınıza bağlanın ve aşağıdaki Transact-SQL'i çalıştırın:

CREATE EVENT SESSION [deadlocks] ON DATABASE 
ADD EVENT sqlserver.database_xml_deadlock_report
ADD TARGET package0.ring_buffer 
WITH (STARTUP_STATE=ON, MAX_MEMORY=4 MB)
GO

ALTER EVENT SESSION [deadlocks] ON DATABASE
    STATE = START;
GO

AdventureWorksLT'de kilitlenmeye neden olur

Dekont

Bu örnek, RCSI etkinleştirildiğinde veritabanında varsayılan şema ve verilerle çalışır AdventureWorksLT . Veritabanını oluşturma yönergeleri için bkz . AdventureWorksLT veritabanı oluşturma.

Kilitlenmeye neden olmak için veritabanına iki oturum AdventureWorksLT bağlamanız gerekir. Bu oturumlara Oturum A ve Oturum B olarak başvuracağız.

A Oturumu'nda aşağıdaki Transact-SQL'i çalıştırın. Bu kod açık bir işlem başlatır ve tabloyu güncelleştiren SalesLT.Product tek bir deyim çalıştırır. Bunu yapmak için işlem, tablodaki SalesLT.Product bir satırda özel (X) kilidine dönüştürülen bir güncelleştirme (U) kilidi alır. İşlemi açık bırakıyoruz.

BEGIN TRAN

    UPDATE SalesLT.Product SET SellEndDate = SellEndDate + 1
        WHERE Color = 'Red';

Şimdi, Oturum B'de aşağıdaki Transact-SQL'i çalıştırın. Bu kod açıkça işlem başlatmaz. Bunun yerine, otomatik komut işlem modunda çalışır. Bu deyim tabloyu güncelleştirir SalesLT.ProductDescription . Güncelleştirme, tablodaki 72 satırda SalesLT.ProductDescription bir güncelleştirme (U) kilidi çıkarır. Sorgu, tablo da dahil olmak üzere diğer tablolara SalesLT.Product katılır.

UPDATE SalesLT.ProductDescription SET Description = Description
    FROM SalesLT.ProductDescription as pd
    JOIN SalesLT.ProductModelProductDescription as pmpd on
        pd.ProductDescriptionID = pmpd.ProductDescriptionID
    JOIN SalesLT.ProductModel as pm on
        pmpd.ProductModelID = pm.ProductModelID
    JOIN SalesLT.Product as p on
        pm.ProductModelID=p.ProductModelID
    WHERE p.Color = 'Silver';

Bu güncelleştirmeyi tamamlamak için, Oturum B'nin, A Oturumu tarafından kilitlenen satır da dahil olmak üzere tablodaki SalesLT.Productsatırlarda paylaşılan (S) kilidine ihtiyacı vardır. Oturum B üzerinde SalesLT.Productengellenir.

Oturum A'ya dönün. Aşağıdaki Transact-SQL deyimini çalıştırın. Bu, açık işlemin bir parçası olarak ikinci bir UPDATE deyimi çalıştırır.

    UPDATE SalesLT.ProductDescription SET Description = Description
        FROM SalesLT.ProductDescription as pd
        JOIN SalesLT.ProductModelProductDescription as pmpd on
            pd.ProductDescriptionID = pmpd.ProductDescriptionID
        JOIN SalesLT.ProductModel as pm on
            pmpd.ProductModelID = pm.ProductModelID
        JOIN SalesLT.Product as p on
            pm.ProductModelID=p.ProductModelID
        WHERE p.Color = 'Red';

A Oturumu'ndaki ikinci güncelleştirme deyimi, üzerindeki SalesLT.ProductDescriptionOturum B tarafından engellenir.

Oturum A ve Oturum B artık birbirini engelliyor. Her biri diğeri tarafından kilitlenmiş bir kaynağa ihtiyaç duyduğundan hiçbir işlem devam edebilir.

Birkaç saniye sonra kilitlenme izleyicisi, A Oturumu ve B Oturumu'ndaki işlemlerin birbirini karşılıklı olarak engellediğini ve bunların hiçbirinin ilerleme kaydedemdiğini belirler. Kilitlenme kurbanı olarak Oturum A'nın seçili olduğu bir kilitlenme olduğunu görmeniz gerekir. A Oturumunda aşağıdakine benzer bir metin içeren bir hata iletisi görüntülenir:

Msg 1205, Düzey 13, Durum 51, Satır 7 İşlem (İşlem Kimliği 91) başka bir işlemle kilit kaynaklarına kilitlendi ve kilitlenme kurbanı olarak seçildi. İşlemi yeniden çalıştırın.

Oturum B başarıyla tamamlanır.

Azure portalında kilitlenme uyarıları ayarlarsanız kilitlenme gerçekleştikten kısa süre sonra bir bildirim almanız gerekir.

XEvents oturumundaki kilitlenme grafiklerini görüntüleme

Kilitlenmeleri toplamak için bir XEvents oturumu ayarladıysanız ve oturum başlatıldıktan sonra bir kilitlenme oluştuysa, kilitlenme grafiğinin etkileşimli grafik görüntüsünü ve kilitlenme grafiğinin XML'sini görüntüleyebilirsiniz.

Kademe arabelleği hedefi ve olay dosyası hedefleri için kilitlenme bilgilerini almak için farklı yöntemler kullanılabilir. XEvents oturumunuz için kullandığınız hedefi seçin:

Kademe arabelleğine yazan bir XEvents oturumu ayarlarsanız, aşağıdaki Transact-SQL ile kilitlenme bilgilerini sorgulayabilirsiniz. Sorguyu çalıştırmadan önce değerini @tracename xEvents oturumunuzun adıyla değiştirin.

DECLARE @tracename sysname = N'deadlocks';

WITH ring_buffer AS (
    SELECT CAST(target_data AS XML) as rb
    FROM sys.dm_xe_database_sessions AS s 
    JOIN sys.dm_xe_database_session_targets AS t 
        ON CAST(t.event_session_address AS BINARY(8)) = CAST(s.address AS BINARY(8))
    WHERE s.name = @tracename and
    t.target_name = N'ring_buffer'
), dx AS (
    SELECT 
        dxdr.evtdata.query('.') as deadlock_xml_deadlock_report
    FROM ring_buffer
    CROSS APPLY rb.nodes('/RingBufferTarget/event[@name=''database_xml_deadlock_report'']') AS dxdr(evtdata)
) 
SELECT 
    d.query('/event/data[@name=''deadlock_cycle_id'']/value').value('(/value)[1]', 'int') AS [deadlock_cycle_id],
    d.value('(/event/@timestamp)[1]', 'DateTime2') AS [deadlock_timestamp],
    d.query('/event/data[@name=''database_name'']/value').value('(/value)[1]', 'nvarchar(256)') AS [database_name],
    d.query('/event/data[@name=''xml_report'']/value/deadlock') AS deadlock_xml,
    LTRIM(RTRIM(REPLACE(REPLACE(d.value('.', 'nvarchar(2000)'),CHAR(10),' '),CHAR(13),' '))) as query_text
FROM dx
CROSS APPLY deadlock_xml_deadlock_report.nodes('(/event/data/value/deadlock/process-list/process/inputbuf)') AS ib(d)
ORDER BY [deadlock_timestamp] DESC;
GO

KILITLENME grafiğini XML'de görüntüleme ve kaydetme

Kilitlenme grafiğini XML biçiminde görüntülemek, kilitlenmeye inputbuffer dahil olan Transact-SQL deyimlerini kopyalamanıza olanak tanır. Kilitlenmeleri metin tabanlı bir biçimde çözümlemeyi de tercih edebilirsiniz.

Kilitlenme grafiği bilgilerini döndürmek için Transact-SQL sorgusu kullandıysanız, kilitlenme grafiği XML'sini görüntülemek için herhangi bir satırdaki sütundaki deadlock_xml değeri seçerek kilitlenme grafiğinin XML'sini SSMS'de yeni bir pencerede açın.

Bu örnek kilitlenme grafı için XML şöyledir:

<deadlock>
  <victim-list>
    <victimProcess id="process24756e75088" />
  </victim-list>
  <process-list>
    <process id="process24756e75088" taskpriority="0" logused="6528" waitresource="KEY: 8:72057594045202432 (98ec012aa510)" waittime="192" ownerId="1011123" transactionname="user_transaction" lasttranstarted="2022-03-08T15:44:43.490" XDES="0x2475c980428" lockMode="U" schedulerid="3" kpid="30192" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-03-08T15:44:49.250" lastbatchcompleted="2022-03-08T15:44:49.210" lastattention="1900-01-01T00:00:00.210" clientapp="Microsoft SQL Server Management Studio - Query" hostname="LAPTOP-CHRISQ" hostpid="16716" loginname="chrisqpublic" isolationlevel="read committed (2)" xactid="1011123" currentdb="8" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671096864" clientoption2="128056">
      <executionStack>
        <frame procname="unknown" queryhash="0xef52b103e8b9b8ca" queryplanhash="0x02b0f58d7730f798" line="1" stmtstart="2" stmtend="792" sqlhandle="0x02000000c58b8f1e24e8f104a930776e21254b1771f92a520000000000000000000000000000000000000000">
unknown    </frame>
      </executionStack>
      <inputbuf>
    UPDATE SalesLT.ProductDescription SET Description = Description
        FROM SalesLT.ProductDescription as pd
        JOIN SalesLT.ProductModelProductDescription as pmpd on
            pd.ProductDescriptionID = pmpd.ProductDescriptionID
        JOIN SalesLT.ProductModel as pm on
            pmpd.ProductModelID = pm.ProductModelID
        JOIN SalesLT.Product as p on
            pm.ProductModelID=p.ProductModelID
        WHERE p.Color = 'Red'   </inputbuf>
    </process>
    <process id="process2476d07d088" taskpriority="0" logused="11360" waitresource="KEY: 8:72057594045267968 (39e18040972e)" waittime="2641" ownerId="1013536" transactionname="UPDATE" lasttranstarted="2022-03-08T15:44:46.807" XDES="0x2475ca80428" lockMode="S" schedulerid="2" kpid="94040" status="suspended" spid="95" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2022-03-08T15:44:46.807" lastbatchcompleted="2022-03-08T15:44:46.760" lastattention="1900-01-01T00:00:00.760" clientapp="Microsoft SQL Server Management Studio - Query" hostname="LAPTOP-CHRISQ" hostpid="16716" loginname="chrisqpublic" isolationlevel="read committed (2)" xactid="1013536" currentdb="8" currentdbname="AdventureWorksLT" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056">
      <executionStack>
        <frame procname="unknown" queryhash="0xef52b103e8b9b8ca" queryplanhash="0x02b0f58d7730f798" line="1" stmtstart="2" stmtend="798" sqlhandle="0x020000002c85bb06327c0852c0be840fc1e30efce2b7c8090000000000000000000000000000000000000000">
unknown    </frame>
      </executionStack>
      <inputbuf>
    UPDATE SalesLT.ProductDescription SET Description = Description
        FROM SalesLT.ProductDescription as pd
        JOIN SalesLT.ProductModelProductDescription as pmpd on
            pd.ProductDescriptionID = pmpd.ProductDescriptionID
        JOIN SalesLT.ProductModel as pm on
            pmpd.ProductModelID = pm.ProductModelID
        JOIN SalesLT.Product as p on
            pm.ProductModelID=p.ProductModelID
        WHERE p.Color = 'Silver';   </inputbuf>
    </process>
  </process-list>
  <resource-list>
    <keylock hobtid="72057594045202432" dbid="8" objectname="9e011567-2446-4213-9617-bad2624ccc30.SalesLT.ProductDescription" indexname="PK_ProductDescription_ProductDescriptionID" id="lock2474df12080" mode="U" associatedObjectId="72057594045202432">
      <owner-list>
        <owner id="process2476d07d088" mode="U" />
      </owner-list>
      <waiter-list>
        <waiter id="process24756e75088" mode="U" requestType="wait" />
      </waiter-list>
    </keylock>
    <keylock hobtid="72057594045267968" dbid="8" objectname="9e011567-2446-4213-9617-bad2624ccc30.SalesLT.Product" indexname="PK_Product_ProductID" id="lock2474b588580" mode="X" associatedObjectId="72057594045267968">
      <owner-list>
        <owner id="process24756e75088" mode="X" />
      </owner-list>
      <waiter-list>
        <waiter id="process2476d07d088" mode="S" requestType="wait" />
      </waiter-list>
    </keylock>
  </resource-list>
</deadlock>

Kilitlenme grafiğini XML dosyası olarak kaydetmek için:

  1. Dosya'yı seçin ve Farklı Kaydet....
  2. Kayıt türü değerini varsayılan XML Dosyaları (*.xml) olarak bırakın
  3. Dosya adı'nı istediğiniz ada ayarlayın.
  4. Kaydet'i seçin.

Kilitlenme grafiğini SSMS'de etkileşimli olarak görüntülenebilen bir XDL dosyası olarak kaydetme

Kilitlenme grafiğinin etkileşimli bir gösterimini görüntülemek, kilitlenmeye neden olan işlemlere ve kaynaklara hızlı bir genel bakış elde etmek ve kilitlenme kurbanını hızlı bir şekilde tanımlamak için yararlı olabilir.

Kilitlenme grafiğini SSMS tarafından grafik olarak görüntülenebilen bir dosya olarak kaydetmek için:

  1. Kilitlenme grafiğinin deadlock_xml XML'sini SSMS'de yeni bir pencerede açmak için herhangi bir satırdaki sütundaki değeri seçin.

  2. Dosya'yı seçin ve Farklı Kaydet....

  3. Kayıt türü'nü Tüm Dosyalar olarak ayarlayın.

  4. Dosya adı'nı istediğiniz ada ayarlayın ve uzantıyı .xdl olarak ayarlayın.

  5. Kaydet'i seçin.

    A screenshot in SSMS of saving a deadlock graph XML file to a file with the xsd extension.

  6. Pencerenin üst kısmındaki sekmedeki X işaretini seçerek veya Dosya'yı ve ardından Kapat'ı seçerek dosyayı kapatın.

  7. Dosya'yı ve ardından Aç'ı ve ardından Dosya'yı seçerek dosyayı SSMS'de yeniden açın. Uzantıyla .xdl kaydettiğiniz dosyayı seçin.

    Kilitlenme grafı artık SSMS'de, kilitlenmeye dahil olan işlemlerin ve kaynakların görsel bir gösterimiyle görüntülenir.

    Screenshot of an xdl file opened in SSMS. The deadlock graph is displayed graphically, with processes indicated by ovals and lock resources as rectangles.

Azure SQL Veritabanı için kilitlenme analizi

Kilitlenme grafı genellikle üç düğüme sahiptir:

  • Kurban listesi. Kilitlenme kurbanı işlem tanımlayıcısı.
  • İşlem listesi. Kilitlenmeye dahil olan tüm süreçlerle ilgili bilgiler. Kilitlenme grafikleri, işlem çalıştıran bir oturumu temsil etmek için 'process' terimini kullanır.
  • Kaynak listesi. Kilitlenmeye dahil olan kaynaklar hakkında bilgi.

Kilitlenmeyi analiz ederken, bu düğümlerde adım adım gezinmek yararlı olur.

Kilitlenme kurbanı listesi

Kilitlenme kurbanı listesi, kilitlenme kurbanı olarak seçilen işlemi gösterir. Kilitlenme grafiğinin görsel gösteriminde işlemler ovallerle temsil edilir. Kilitlenme kurbanı işlemi ovalin üzerine bir "X" çizilmiş.

Screenshot of the visual display of a deadlock. The oval representing the process selected as victim has an X drawn across it.

Bir kilitlenme grafiğinin XML görünümünde düğüm, victim-list kilitlenmenin kurbanı olan işlem için bir kimlik verir.

Örnek kilitlenmemizde, kurban işlem kimliği process24756e75088 şeklindedir. Bu kimliği, kurban işlemi ve kilitlendiği veya kilitlenmesini istediği kaynaklar hakkında daha fazla bilgi edinmek için işlem listesi ve kaynak listesi düğümlerini incelerken kullanabiliriz.

Kilitlenme işlemi listesi

Kilitlenme işlemi listesi, kilitlenmeye dahil olan işlemler hakkında zengin bir bilgi kaynağıdır.

Kilitlenme grafiğinin grafik gösterimi, kilitlenme grafiği XML'sinde yer alan bilgilerin yalnızca bir alt kümesini gösterir. Kilitlenme grafiğindeki ovaller işlemi temsil eder ve aşağıdakiler dahil bilgileri gösterir:

  • Oturum kimliği veya SPID olarak da bilinen sunucu işlem kimliği.

  • Oturumun kilitlenme önceliği . İki oturumun kilitlenme öncelikleri farklıysa, düşük önceliğe sahip oturum kilitlenme kurbanı olarak seçilir. Bu örnekte her iki oturum da aynı kilitlenme önceliğine sahiptir.

  • Oturum tarafından bayt cinsinden kullanılan işlem günlüğü miktarı. Her iki oturum da aynı kilitlenme önceliğine sahipse kilitlenme izleyicisi, kilitlenme kurbanı olarak geri alınması daha düşük maliyetli olan oturumu seçer. Maliyet, her işlemdeki bu noktaya yazılan günlük baytlarının sayısı karşılaştırılarak belirlenir.

    Örneğimizde, session_id 89 daha düşük miktarda işlem günlüğü kullanmış ve kilitlenme kurbanı olarak seçilmiştir.

Ayrıca, fareyi her işlemin üzerine getirerek kilitlenmeden önceki her oturumda son deyim çalıştırması için giriş arabelleği görüntüleyebilirsiniz. Giriş arabelleği bir araç ipucunda görünür.

Screenshot of a deadlock graph displayed visually in SSMS. Two ovals represent processes. The inputbuff for one process is shown.

Kilitlenme grafiğinin XML görünümündeki işlemler için aşağıdakiler gibi ek bilgiler sağlanır:

  • Oturum için istemci adı, ana bilgisayar adı ve oturum açma adı gibi bilgileri tanımlama.
  • Kilitlenmeden önce her oturum tarafından çalıştırılan son deyimin sorgu planı karması. Sorgu planı karması, Sorgu Deposu'ndan sorgu hakkında daha fazla bilgi almak için kullanışlıdır.

Örneğimizde kilitlenme:

  • Her iki oturumun da chrisqpublic oturum açma bilgileri altında SSMS istemcisi kullanılarak çalıştırıldığını görebiliriz.
  • Kilitlenme kurbanımız tarafından kilitlenmeden önceki son deyim çalıştırmasının sorgu planı karması 0x02b0f58d7730f798. Giriş arabelleğinde bu deyimin metnini görebiliriz.
  • Kilitlenmemizdeki diğer oturum tarafından çalıştırılan son deyimin sorgu planı karması da 0x02b0f58d7730f798. Giriş arabelleğinde bu deyimin metnini görebiliriz. Bu durumda, eşitlik koşulu olarak kullanılan değişmez değer dışında sorgular aynı olduğundan her iki sorgu da aynı sorgu planı karması içerir.

Sorgu Deposu'nda ek bilgi bulmak için bu değerleri bu makalenin devamında kullanacağız.

Kilitlenme işlemi listesindeki giriş arabelleği sınırlamaları

Kilitlenme işlemi listesindeki giriş arabelleği bilgileriyle ilgili dikkat edilmesi gereken bazı sınırlamalar vardır.

Sorgu metni giriş arabelleğinde kesilebilir. Giriş arabelleği yürütülmekte olan deyimin ilk 4.000 karakteriyle sınırlıdır.

Ayrıca kilitlenmeye dahil olan bazı deyimler kilitlenme grafında yer almayabilir. Örneğimizde, Oturum A tek bir işlem içinde iki güncelleştirme deyimi çalıştırmıştı. Kilitlenmeye neden olan güncelleştirme olan yalnızca ikinci güncelleştirme deyimi kilitlenme grafiğine eklenir. Oturum A tarafından çalıştırılan ilk güncelleştirme deyimi, Oturum B'yi engelleyerek kilitlenmede bir rol oynadı. Oturum A tarafından çalıştırılan ilk deyimin giriş arabelleği, query_hashve ilgili bilgileri kilitlenme grafiğine dahil değildir.

Kilitlenmeye neden olan çok deyimli bir işlemde transact-SQL çalıştırmasının tamamını tanımlamak için, sorguyu çalıştıran saklı yordamda veya uygulama kodunda ilgili bilgileri bulmanız veya kilitlenme sırasında oturumlar tarafından çalıştırılan tam deyimleri yakalamak için Genişletilmiş Olaylar kullanarak bir izleme çalıştırmanız gerekir. Kilitlenmeye dahil olan bir deyim kesilmişse ve giriş arabelleğinde yalnızca kısmi Transact-SQL görünüyorsa, Deyimin Transact-SQL'ini Yürütme Planı ile Sorgu Deposu'nda bulabilirsiniz.

Kilitlenme kaynak listesi

Kilitlenme kaynak listesi, kilitlenmedeki işlemler tarafından hangi kilit kaynaklarının sahibi olduğunu ve beklediğini gösterir.

Kaynaklar, kilitlenmenin görsel gösterimindeki dikdörtgenlerle temsil edilir:

Screenshot of a deadlock graph, displayed visually in SSMS. Rectangles show the resources that are involved in the deadlock.

Dekont

Veritabanı adlarının, Azure SQL Veritabanı veritabanları için kilitlenme grafiklerinde benzersizdeğerler olarak gösterildiğini fark edebilirsiniz. Bu, physical_database_name sys.databases ve sys.dm_user_db_resource_governance dinamik yönetim görünümlerinde listelenen veritabanı içindir.

Bu örnekte kilitlenme:

  • Oturum A olarak belirttiğimiz kilitlenme kurbanı:

    • Tablodaki dizindeki bir anahtar üzerinde PK_Product_ProductID özel (X) kilidine SalesLT.Product sahip.
    • Tablodaki dizindeki SalesLT.ProductDescription bir anahtar üzerinde PK_ProductDescription_ProductDescriptionID güncelleştirme (U) kilidi ister.
  • Oturum B olarak adlandırılan diğer işlem:

    • Tablodaki dizindeki bir anahtar üzerinde PK_ProductDescription_ProductDescriptionID bir güncelleştirme (U) kilidine SalesLT.ProductDescription sahip.
    • Tablodaki dizindeki SalesLT.ProductDescription bir anahtar üzerinde PK_ProductDescription_ProductDescriptionID paylaşılan (S) kilidi ister.

Aynı bilgileri kaynak listesi düğümündeki kilitlenme grafiğinin XML'sinde de görebiliriz.

Sorgu Deposu'nda sorgu yürütme planlarını bulma

Kilitlenmeye dahil olan deyimler için sorgu yürütme planlarını incelemek genellikle yararlıdır. Bu yürütme planları genellikle kilitlenme grafiğinin işlem listesinin XML görünümünden sorgu planı karması kullanılarak Sorgu Deposu'nda bulunabilir.

Bu Transact-SQL sorgusu, örnek kilitlenme için bulduğumuz sorgu planı karmasıyla eşleşen sorgu planlarını arar. Sorguyu çalıştırmak için Azure SQL Veritabanı'daki kullanıcı veritabanına Bağlan.

DECLARE @query_plan_hash binary(8) = 0x02b0f58d7730f798

SELECT 
    qrsi.end_time as interval_end_time,
    qs.query_id,
    qp.plan_id,
    qt.query_sql_text, 
    TRY_CAST(qp.query_plan as XML) as query_plan,
    qrs.count_executions
FROM sys.query_store_query as qs
JOIN sys.query_store_query_text as qt on qs.query_text_id=qt.query_text_id
JOIN sys.query_store_plan as qp on qs.query_id=qp.query_id
JOIN sys.query_store_runtime_stats qrs on qp.plan_id = qrs.plan_id
JOIN sys.query_store_runtime_stats_interval qrsi on qrs.runtime_stats_interval_id=qrsi.runtime_stats_interval_id
WHERE query_plan_hash =  @query_plan_hash
ORDER BY interval_end_time, query_id;
GO

Sorgu Deposu CLEANUP_POLICY veya QUERY_CAPTURE_MODE ayarlarınıza bağlı olarak Sorgu Deposu'ndan sorgu yürütme planı alamayabilirsiniz. Bu durumda, sorgu için tahmini yürütme planını görüntüleyerek genellikle gerekli bilgileri alabilirsiniz.

Engellemeyi artıran desenleri arayın

Kilitlenmelere dahil olan sorgu yürütme planlarını incelerken engelleme ve kilitlenmelere katkıda bulunabilecek desenlere dikkat edin.

  • Tablo veya dizin taramaları. Verileri değiştiren sorgular RCSI altında çalıştırıldığında, güncelleştirilecek satır seçimi veri değerleri okundukça veri satırında bir güncelleştirme (U) kilidinin alındığı bir engelleme taraması kullanılarak yapılır. Veri satırı güncelleştirme ölçütlerini karşılamıyorsa güncelleştirme kilidi serbest bırakılır ve sonraki satır kilitlenir ve taranır.

    Değişiklik sorgularının satırları daha verimli bulmasına yardımcı olmak için dizinlerin ayarlanması, verilen güncelleştirme kilitlerinin sayısını azaltır. Bu, engelleme ve kilitlenme olasılığını azaltır.

  • Birden fazla tabloya başvuran dizinli görünümler. Dizinli görünümde başvuruda bulunan bir tabloyu değiştirdiğinizde, veritabanı altyapısının da dizinlenmiş görünümü koruması gerekir. Bunun için daha fazla kilit alınması gerekir ve daha fazla engelleme ve kilitlenmeye yol açabilir. Dizine alınan görünümler, güncelleştirme işlemlerinin okuma işlemi yapılan yalıtım düzeyi altında dahili olarak yürütülmesine de neden olabilir.

  • Yabancı anahtar kısıtlamalarında başvuruda bulunan sütunlarda yapılan değişiklikler. YABANCı ANAHTAR kısıtlamasında başvuruda bulunan bir tablodaki sütunları değiştirdiğinizde, veritabanı altyapısı başvuru tablosunda ilgili satırları aramalıdır. Bu okumalar için satır sürümleri kullanılamaz. Art arda güncelleştirmelerin veya silmelerin etkinleştirildiği durumlarda, hayalet eklemelere karşı koruma sağlamak için yalıtım düzeyi deyiminin süresi boyunca serileştirilebilir duruma getirilebilir.

  • Kilit ipuçları. Daha fazla kilit gerektiren yalıtım düzeylerini belirten tablo ipuçlarını arayın. Bu ipuçları arasında HOLDLOCK (serileştirilebilir ile eşdeğerdir), SERIALIZABLE, READCOMMITTEDLOCK (RCSI'yi devre dışı bırakır) ve REPEATABLEREADbulunur. Ayrıca, , TABLOCK, UPDLOCKve XLOCK gibi PAGLOCKipuçları engelleme ve kilitlenme risklerini artırabilir.

    Bu ipuçları yerindeyse, ipuçlarının neden uygulandığını araştırın. Bu ipuçları yarış koşullarını engelleyebilir ve veri geçerliliğini güvence altına alabilir. Gerekirse bu ipuçlarını yerinde bırakmak ve kilitlenmenin yeniden oluşmasını önleme bölümünde alternatif bir yöntem kullanarak gelecekteki kilitlenmeleri önlemek mümkün olabilir.

    Dekont

    İşlem kilitleme ve satır sürüm oluşturma kılavuzunda satır sürümü oluşturma kullanarak verileri değiştirirken davranışlar hakkında daha fazla bilgi edinin.

Yürütme planında veya uygulama sorgu kodunda bir işlemin tam kodunu incelerken, ek sorunlu desenler arayın:

  • İşlemlerdeki kullanıcı etkileşimi. Açık bir çok ekstreli işlem içindeki kullanıcı etkileşimi, işlemlerin süresini önemli ölçüde artırır. Bu, bu işlemlerin çakışması ve engelleme ve kilitlenmelerin oluşmasını daha olası hale getirir.

    Benzer şekilde, açık bir işlem tutmak ve ilgisiz bir veritabanı veya sistem orta işlemi sorgulamak engelleme ve kilitlenme olasılığını önemli ölçüde artırır.

  • Farklı siparişlerdeki nesnelere erişen işlemler. Eşzamanlı açık çok deyimli işlemler aynı desenleri izlediğinde ve nesnelere aynı sırayla eriştiğinde kilitlenmelerin oluşma olasılığı daha düşüktür.

Kilitlenmenin yeniden oluşmasını engelleme

Dizin ayarlama, Sorgu Deposu ile planları zorlama ve Transact-SQL sorgularını değiştirme de dahil olmak üzere kilitlenmelerin yeniden oluşmasını önlemeye yönelik birden çok teknik vardır.

  • Tablonun kümelenmiş dizinini gözden geçirin. Çoğu tablo kümelenmiş dizinlerden yararlanılır, ancak genellikle tablolar yanlışlıkla yığın olarak uygulanır.

    Kümelenmiş dizini denetlemenin bir yolu, sp_helpindex sistem saklı yordamını kullanmaktır. Örneğin, aşağıdaki deyimi yürüterek tablodaki SalesLT.Product dizinlerin özetini görüntüleyebiliriz:

    exec sp_helpindex 'SalesLT.Product';
    GO
    

    index_description sütununu gözden geçirin. Bir tabloda yalnızca bir kümelenmiş dizin olabilir. Tablo için kümelenmiş dizin uygulandıysa, index_description 'kümelenmiş' sözcüğünü içerir.

    Kümelenmiş dizin yoksa, tablo bir yığındır. Bu durumda, tablonun belirli bir performans sorununu çözmek için kasıtlı olarak yığın olarak oluşturulup oluşturulmadığını gözden geçirin. Kümelenmiş dizin tasarım yönergelerine göre kümelenmiş dizin uygulamayı göz önünde bulundurun.

    Bazı durumlarda, kümelenmiş dizin oluşturma veya ayarlama kilitlenmeleri engellemeyi azaltabilir veya ortadan kaldırabilir. Diğer durumlarda, bu listedeki diğerleri gibi ek bir teknik kullanmanız gerekebilir.

  • Kümelenmemiş dizinler oluşturun veya değiştirin. Kümelenmemiş dizinleri ayarlamak, değişiklik sorgularınızın güncelleştirme verilerini daha hızlı bulmasına yardımcı olabilir ve bu da gerekli güncelleştirme kilitlerinin sayısını azaltır.

    Örneğimizde, Sorgu Deposu'nda bulunan sorgu yürütme planı dizine karşı PK_Product_ProductID kümelenmiş dizin taraması içeriyor. Kilitlenme grafiği, bu dizinde paylaşılan (S) kilit beklemesinin kilitlenmedeki bir bileşen olduğunu gösterir.

    Screenshot of a query execution plan. A clustered index scan is being performed against the PK_Product_ProductID index on the Product table.

    Güncelleştirme sorgumuzun adlı vProductAndDescriptiondizinlenmiş görünümü değiştirmesi gerektiğinden bu dizin taraması gerçekleştiriliyor. Bu makalenin Engellemeyi artıran desenleri ara bölümünde belirtildiği gibi, birden çok tabloya başvuran dizinli görünümler engellemeyi ve kilitlenme olasılığını artırabilir.

    Veritabanında dizinlenmiş görünüm tarafından başvurulan sütunları SalesLT.Product "kapsayan" aşağıdaki kümelenmemiş dizini AdventureWorksLT oluşturursak, bu sorgunun satırları çok daha verimli bulmasına yardımcı olur:

    CREATE INDEX ix_Product_ProductID_Name_ProductModelID on SalesLT.Product (ProductID, Name, ProductModelID);
    GO
    

    Bu dizini oluşturduktan sonra kilitlenme artık yeniden oluşmaz.

    Kilitlenmeler yabancı anahtar kısıtlamalarında başvuruda bulunan sütunlarda değişiklik içeriyorsa, YABANCı ANAHTAR'ın başvuran tablosundaki dizinlerin ilgili satırları verimli bir şekilde bulmayı desteklediğinden emin olun.

    Dizinler bazı durumlarda sorgu performansını önemli ölçüde geliştiremese de dizinlerin ek yükü ve yönetim maliyetleri de vardır. Dizin oluşturmadan önce, özellikle büyük tablolardaki geniş dizinler ve dizinler için dizinlerin avantajlarını değerlendirmeye yardımcı olmak için genel dizin tasarımı yönergelerini gözden geçirin.

  • Dizine alınan görünümlerin değerini değerlendirin. Örnek kilitlenmenin yeniden oluşmasını önlemeye yönelik bir diğer seçenek de dizine alınmış görünümü bırakmaktır SalesLT.vProductAndDescription . Bu dizinlenmiş görünüm kullanılmıyorsa, bu durum zaman içinde dizine alınan görünümü koruma yükünü azaltır.

  • Anlık görüntü yalıtımını kullanın. Bazı durumlarda, kilitlenmeye dahil olan işlemlerden biri veya daha fazlası için işlem yalıtım düzeyini anlık görüntü olarak ayarlamak engellemeyi ve kilitlenmelerin yeniden oluşmasını engelleyebilir.

    Okuma işlemi yapılan anlık görüntü bir veritabanında devre dışı bırakıldığında SELECT deyimlerinde kullanıldığında bu teknik büyük olasılıkla başarılı olacaktır. Okundu anlık görüntüsü devre dışı bırakıldığında, tamamlanan okuma yalıtım düzeyini kullanan SELECT sorguları paylaşılan (S) kilitleri gerektirir. Bu işlemlerde anlık görüntü yalıtımının kullanılması, paylaşılan kilit gereksinimini ortadan kaldırır ve bu da engelleme ve kilitlenmeleri önleyebilir.

    Okundu anlık görüntü yalıtımının etkinleştirildiği veritabanlarında SELECT sorguları paylaşılan (S) kilitleri gerektirmez, bu nedenle verileri değiştiren işlemler arasında kilitlenmeler oluşma olasılığı daha yüksektir. Verileri değiştiren birden çok işlem arasında kilitlenmelerin oluştuğu durumlarda, anlık görüntü yalıtımı kilitlenme yerine güncelleştirme çakışması ile sonuçlanabilir. Buna benzer şekilde işlemlerden birinin işlemini yeniden denemesi gerekir.

  • Sorgu Deposu ile bir planı zorlama. Kilitlenmedeki sorgulardan birinin birden çok yürütme planı olduğunu ve kilitlenmenin yalnızca belirli bir plan kullanıldığında gerçekleştiğini görebilirsiniz. Sorgu Deposu'nda bir planı zorlayarak kilitlenmenin yeniden oluşmasını önleyebilirsiniz.

  • Transact-SQL'i değiştirin. Kilitlenmenin yeniden oluşmasını önlemek için Transact-SQL'i değiştirmeniz gerekebilir. Transact-SQL'in değiştirilmesi dikkatli bir şekilde yapılmalıdır ve değişiklikler eşzamanlı olarak çalıştırıldığında verilerin doğru olduğundan emin olmak için değişiklikler sıkı bir şekilde test edilmelidir. Transact-SQL'i yeniden yazarken şunları göz önünde bulundurun:

    • İşlemlerdeki deyimleri, nesnelere aynı sırayla erişebilecek şekilde sıralama.
    • Mümkün olduğunda işlemleri daha küçük işlemlere ayırma.
    • Gerekirse performansı iyileştirmek için sorgu ipuçlarını kullanma. Sorgu Deposu'nu kullanarak uygulama kodunu değiştirmeden ipuçları uygulayabilirsiniz.

Kilitlenmeleri en aza indirmenin diğer yollarını Kilitlenmeler kılavuzunda bulabilirsiniz.

Dekont

Bazı durumlarda, oturumlardan birinin yeniden denemeden başarıyla tamamlanması önemliyse veya kilitlenmeye dahil olan sorgulardan biri kritik değilse ve her zaman kurban olarak seçilmesi gerekiyorsa kilitlenmeye dahil olan bir veya daha fazla oturumun kilitlenme önceliğini ayarlamak isteyebilirsiniz. Bu, kilitlenmenin yeniden oluşmasını engellemese de, gelecekteki kilitlenmelerin etkisini azaltabilir.

XEvents oturumlarını bırakma

Uzun süreler boyunca kritik veritabanlarında çalışan kilitlenme bilgilerini toplayan bir XEvents oturumu bırakmak isteyebilirsiniz. Bir olay dosyası hedefi kullanırsanız, birden çok kilitlenme oluşursa bunun büyük dosyalara neden olabileceğini unutmayın. Blob dosyalarını, şu anda yazılmakta olan dosya dışında etkin bir izleme için Azure Depolama'dan silebilirsiniz.

Bir XEvents oturumunu kaldırmak istediğinizde, seçilen hedef türü ne olursa olsun Transact-SQL bırakma işlemi aynı oturumdur.

XEvents oturumunu kaldırmak için aşağıdaki Transact-SQL'i çalıştırın. Kodu çalıştırmadan önce oturumun adını uygun değerle değiştirin.

ALTER EVENT SESSION [deadlocks] ON DATABASE
    STATE = STOP;
GO

DROP EVENT SESSION [deadlocks] ON DATABASE;
GO

Azure Depolama Gezgini'ni kullanma

Azure Depolama Gezgini, Azure Depolama bloblarında depolanan olay dosyası hedefleriyle çalışmayı basitleştiren tek başına bir uygulamadır. Depolama Gezgini'ni kullanarak:

Azure Depolama Gezgini indirin..

Sonraki adımlar

Azure SQL Veritabanı performansı hakkında daha fazla bilgi edinin: