Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Şunlar için geçerlidir:Azure SQL Veritabanı
Fabric'te SQL veritabanı
Bu makalede kilitlenmeleri tanımlama, kilitlenme grafiklerini ve Sorgu Deposu'nı kullanarak kilitlenmedeki sorguları tanımlama ve kilitlenmelerin yeniden oluşmasını önlemek için değişiklikleri planlama ve test etme öğretildi. Bu makale, Azure SQL Veritabanı ve Azure SQL Veritabanı'nın birçok özelliğini paylaşan Fabric üzerindeki SQL Veritabanı için geçerlidir.
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.
Kilitlenmeler nasıl oluşur?
Azure SQL Veritabanı'ndaki her yeni veritabanında varsayılan olarak okuma kaydedilmiş anlık görüntü yalıtımı (RCSI) veritabanı ayarı etkindir. RCSI, eşzamanlılığı artırmak için satır sürümleme kullanır; veri okuma ve veri yazma oturumları arasında engelleme en aza indirilir. Ancak engelleme ve kilitlenmeler Azure SQL Veritabanı'ndaki veritabanlarında yine de oluşabilir çünkü:
Verileri değiştiren sorgular birbirinizi 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 TRANSACTION ISOLATION LEVEL aracılığıyla belirtilebilir.
RCSIdevre dışı bırakılabilir, bu da veritabanının, okuma onaylı yalıtım düzeyi altında çalıştırılan
SELECTdeyimlerini korumak için paylaşılan (S) kilitler kullanmasına neden olabilir. Bu, engellemeyi 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.
Örneğin:
Oturum A, açık bir işlem başlatır ve tabloda bir satır için güncelleştirme (U) kilidi edinen ve bunun
SalesLT.Productbir güncelleştirme deyimi çalıştırır.Oturum B , tabloyu değiştiren
SalesLT.ProductDescriptionbir güncelleştirme deyimi çalıştırır. Güncelleme ifadesi, doğru satırları bulup güncellemek içinSalesLT.Producttablosuyla birleşir.Oturum B , tablodaki 72 satırda
SalesLT.ProductDescriptionbir güncelleştirme (U) kilidi alır.Oturum B, A Oturumu tarafından kilitlenmiş olanlar dahil olmak üzere tablodaki
SalesLT.Productsatırlarda paylaşılan bir kilide ihtiyaç duyar. Oturum B, üzerinde engellenmiştir.
A oturumu işlemine devam eder ve şimdi tabloya karşı bir güncelleme
SalesLT.ProductDescriptionçalıştırır. Oturum A,SalesLT.ProductDescriptionüzerindeki Oturum B tarafından engellendi.
Kilitlenmedeki tüm işlemler, örneğin oturumu sonlandırıldığı için 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 1205 hatasıyla işlemini sonlandırır: Transaction (Process ID <N>) was deadlocked on lock resources with another process and is chosen as the deadlock victim. Rerun the transaction. Kilitlenmeyi bu şekilde bozmak, kilitlenmedeki diğer görev veya görevlerin işlemlerini tamamlayabilmesini sağlar.
Not
Bu makalenin Kilitlenme işlemi listesi bölümünde kilitlenme kurbanı seçme ölçütleri hakkında daha fazla bilgi edinin.
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, davranışını, deyimleri için paylaşılan (S) kilitleri kullanılmadan SELECT kullanarak deyim düzeyinde tutarlılık sağlamak üzere 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 SNAPSHOT olarak ayarlaması 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ın 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ütunu 1değerini döndürür. Anlık görüntü yalıtımı etkinleştirilirse, snapshot_isolation_state_desc sütunu ONdeğerini döndürür.
Azure SQL Veritabanı'ndaki bir veritabanı için RCSI devre dışı bırakıldıysa, yeniden etkinleştirmeden önce RCSI'nin neden devre dışı bırakıldığını araştırın. Uygulama kodu, verileri okuyan sorguların veri yazan sorgular tarafından engellenmesini bekleyerek RCSI etkinleştirildiğinde yarış koşullarından yanlış sonuçlar elde edilmesine neden 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, kilitlenme 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 Transaction (Process ID <N>) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction. içerecek şekilde yazılmalıdır
Ancak, kilitlenmeler yeniden oluşaabildiği için uyarıları ayarlamak yararlı olur. Kilitlenme uyarıları, veritabanınızda yinelenen kilitlenmeler olup olmadığını araştırmanıza olanak tanır ve 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, AdventureWorksLT örnek veritabanını kullanarak kilitlenmelere yönelik uyarılar ayarlayacağız, örnek bir kilitlenmeye neden olacak, kilitlenme grafiğini örnek kilitlenme için analiz edeceğiz ve kilitlenmenin yeniden oluşmasını önlemek için değişiklikleri test edeceğiz.
Bu makaledeki SQL Server Management Studio (SSMS) istemcisini, kilitlenme grafiklerini etkileşimli bir görsel modda görüntüleme işlevselliği içerdiğinden kullanırız. Örnekleri takip etmek için Visual Studio Code için MSSQL uzantısı, sqlcmd veya sık kullandığınız Transact-SQL sorgulama aracı gibi diğer istemcileri kullanabilirsiniz, ancak kilitlenme grafiklerini sadece 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ı'nda tek bir veritabanı oluşturma başlığı altında istediğiniz 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ı'nda Genişletilmiş Olaylar (XEvents) ve Fabric'teki SQL veritabanında kilitlenme grafları toplamak için sqlserver.database_xml_deadlock_report olayını yakalayın.
Halka arabellek 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:
Kullanmak istediğiniz hedef türü seçin:
Halka arabelleği hedefi kullanımı kolay ve kurulumu basittir, ancak kapasitesi sınırlıdır ve bu da eski olayların kaybolmasına neden olabilir. Halka arabelleği, olayları depolamada kalıcı hale getirmez 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 geldiği anlamına gelir. Bir olay dosyası hedefine hemen bir XEvents oturumu ayarlama olanağınız yoksa, halka tampon hedefi, öğrenme ve kısa vadeli ihtiyaçlar için en iyi seçenektir.
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.
Ring buffer hedefi için bir XEvents oturumu oluşturup başlatmak üzere sqlserver.database_xml_deadlock_report veritabanınıza bağlanın ve aşağıdaki Transact-SQL komutunu ç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
Kilitlenmeye neden olur
İyileştirilmiş kilitleme her zaman Azure SQL Veritabanı'nda ve Doku'daki SQL veritabanında etkinleştirildiğinden kilitlenme olasılığı daha düşüktür. Daha fazla bilgi için ve iyileştirilmiş kilitleme ile oluşabilecek bir kilitlenme örneği için bkz . İyileştirilmiş kilitleme ve kilitlenmeler.
XEvents oturumundaki kilitlenme grafiklerini görüntüleme
kilitlenmeleri toplamak için bir XEvents oturumu ayarlarsanız ve oturum başladıktan sonra kilitlenme oluşursa, 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 AS sysname = N'deadlocks';
WITH ring_buffer
AS (SELECT CAST (target_data AS XML) AS rb
FROM sys.dm_xe_database_sessions AS s
INNER 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 de analiz 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:
- Dosya'yı seçin ve Farklı Kaydet....
- Kayıt türü değerini varsayılan olarak XML Dosyaları (*.xml) şeklinde bırakın.
- Dosya adı'nı tercih ettiğiniz isme ayarlayın.
- 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:
Kilitlenme grafiğinin
deadlock_xmlXML'sini SSMS'de yeni bir pencerede açmak için herhangi bir satırdaki sütundaki değeri seçin.Dosya'yı seçin ve Farklı Kaydet....
Kayıt türünü Tüm Dosyalar olarak ayarlayın.
Dosya adını istediğiniz ada, uzantısını ise
.xdlolarak ayarlayın.Kaydet'i seçin.
Pencerenin üst kısmındaki sekmedeki X işaretini seçerek veya Dosya'yı ve ardından Kapat'ı seçerek dosyayı kapatın.
SSMS'de dosyayı yeniden açmak için sırasıyla Dosya, ardından Aç, sonra da Dosya seçeneklerini seçin. Uzantıyla
.xdlkaydettiğ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.
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, bir oturumda çalışan işlemi temsil etmek için 'işlem' 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ş.
Bir kilitlenme grafiğinin XML görünümünde düğüm, victim-list kilitlenmenin kurbanı olan işlem için bir kimlik verir.
Örneğimizdeki kilitlenmede, kurban işlem kimliği process24756e75088'dır. 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 durumu işlem 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:
SPID olarak da bilinen oturum 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.
Oturumun kullandığı işlem günlüğü miktarı, bayt cinsindendir. 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şlemde o noktaya kadar yazılan günlük baytlarının sayısı karşılaştırılarak belirlenir.
Örneğimizde,
session_id89 daha düşük miktarda işlem günlüğü kullanmış ve kilitlenme kurbanı olarak seçilmişti.
Ayrıca, fareyi her işlemin üzerine getirerek kilitlenme öncesinde her oturumda çalıştırılan son deyimin giriş arabelleğini görüntüleyebilirsiniz. Giriş arabelleği, bir araç ipucunda görünür.
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ı özeti. Sorgu planı karması, Sorgu Deposu'ndan sorgu hakkında daha fazla bilgi almak için kullanışlıdır.
Örneğimizde kilitlenme:
İki oturumun
chrisqpublicoturum açma kimliği altında SSMS istemcisi kullanılarak çalıştırıldığını görebiliriz.Kilitlenme yaşayan kurbanımız tarafından kilitlenmeden önce çalıştırılan son ifadenin sorgu planının karması
0x02b0f58d7730f798. Giriş arabelleğinde bu deyimin metnini görebiliriz.Kilitlenmemizde diğer oturumun çalıştırdığı 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 bulmakiçin bu makalenin devamında bu değerleri kullanırız.
Kilitlenme işlemi listesindeki giriş arabelleği sınırlamaları
Kilitlenme süreci listesindeki giriş arabelleği bilgileriyle ilgili farkında olunması gereken bazı sınırlamalar vardır.
Sorgu metni giriş arabelleğinde kısıtlanabilir. 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 Bengelleyerek kilitlenmede bir rol oynadı. query_hash tarafından çalıştırılan ilk deyim için giriş arabelleği, ve ilgili bilgiler kilitlenme grafiğine dahil değildir.
Bir kilitlenmeye karışan çok deyimli bir işlemdeki tam Transact-SQL çalışmasını belirlemek için, sorguyu çalıştıran saklı yordamda veya uygulama kodunda ilgili bilgileri bulmanız ya da kilitlenme sırasında bir kilitlenmeye dahil olan oturumlar tarafından çalıştırılan tam deyimleri yakalamak için uzatılmış olaylar kullanarak bir iz sürümü gerçekleştirmeniz gerekir. Kilitlenmeye dahil olan bir deyim kesilirse ve giriş arabelleğinde yalnızca kısmi Transact-SQL görünürse, bu deyimin Transact-SQL'yi Sorgu Deposu'nda Yürütme Planıile bulabilirsiniz.
Kilitlenme kaynağı listesi
Kilitlenme kaynak listesi, kilitlenmedeki işlemler tarafından sahip olunan ve beklenen kilit kaynaklarını gösterir.
Kaynaklar, kilitlenmenin görsel gösterimindeki dikdörtgenlerle temsil edilir:
Not
Veritabanı adları, Azure SQL Veritabanı ve Fabric içindeki SQL veritabanı için kilitlenme grafiklerinde GUID'ler (uniqueidentifier) olarak temsil edilir. 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
PK_Product_ProductIDindekste bir anahtar üzerindeSalesLT.Productözel (X) kilidine sahip.Tablodaki
PK_ProductDescription_ProductDescriptionIDdizinindekiSalesLT.ProductDescriptionanahtar üzerinde güncelleştirme (U) kilidi ister.
Oturum B olarak adlandırılan diğer işlem:
PK_ProductDescription_ProductDescriptionIDtablosundakiSalesLT.ProductDescriptiondizininde bir anahtar üzerinde bir güncelleştirme (U) kilidine sahip.PK_ProductDescription_ProductDescriptionIDtablosundakiSalesLT.ProductDescriptiondizinindeki bir anahtar üzerinde paylaşılan (S) kilidi ister.
Aynı bilgileri kaynak listesi düğümünde kilitlenme grafiğinin XML'sinde de görebiliriz.
Sorgu Deposu'nda sorgu yürütme planlarını bulma
Kilitlenmeye dahil olan ifadeler için sorgu yürütme planlarını incelemek genellikle yararlı olur. 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ı'deki kullanıcı veritabanına bağlanın.
DECLARE @query_plan_hash AS 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
INNER JOIN sys.query_store_query_text AS qt
ON qs.query_text_id = qt.query_text_id
INNER JOIN sys.query_store_plan AS qp
ON qs.query_id = qp.query_id
INNER JOIN sys.query_store_runtime_stats AS qrs
ON qp.plan_id = qrs.plan_id
INNER JOIN sys.query_store_runtime_stats_interval AS 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 açılması gerekir ve daha fazla blokaj ve kilitlenmeye yol açabilir. Dizinlenmiş görünümler, güncelleştirme işlemlerinin 'read committed' yalıtım seviyesi 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.
FOREIGN KEYkısıtlamasında başvuruda bulunan bir tablodaki sütunları değiştirdiğinizde, veritabanı altyapısı başvuruda bulunan tabloda ilgili satırları aramalıdır. Bu okumalar için satır sürümleri kullanılamaz. Art arda güncellemelerin veya silmelerin etkinleştirildiği durumlarda, hayalet eklemelere karşı koruma sağlamak için yalıtım düzeyi ifade süresi boyunca serileştirilebilir hale 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) veREPEATABLEREADbulunur. Ayrıca, ,PAGLOCK,TABLOCKveUPDLOCKgibiXLOCKipuç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ı önleyebilir ve veri geçerliliğini sağlayabilir. Gerekirse bu ipuçlarını yerinde bırakmak ve gelecekteki kilitlenmeleri önlemek, bu makalenin Diğer bir yöntemi kullanarak Kilitlenmenin Yeniden Oluşmasını Önleme bölümünde mümkün olabilir.
Not
İş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 gibi 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.Productdizinlerin özetini görüntüleyebiliriz:EXECUTE sp_helpindex 'SalesLT.Product'; GOindex_descriptionsütununu gözden geçirin. Bir tabloda yalnızca bir kümelenmiş dizin olabilir. Tablo için kümelenmiş dizin uygulandıysa,index_descriptionclusteredsö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, kilitlenmelerde bloke olmayı azaltabilir veya ortadan kaldırabilir. Diğer durumlarda, bu listedeki diğerleri gibi ek bir teknik kullanabilirsiniz.
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ğimizdeki çıkmazda, Sorgu Deposu'nda bulunan sorgu yürütme planı ,
PK_Product_ProductIDdizinine karşı bir kümelenmiş dizin taraması içeriyor. Kilitlenme grafiği, bu dizinde bekleyen paylaşımlı (S) kilidin kilitlenmeye katkıda bulunan bir bileşen olduğunu gösterir.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 arayın 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.Eğer
AdventureWorksLTveritabanında, dizinlenmiş görünüm tarafından başvurulanSalesLT.Productsütunlarını "kapsayan" aşağıdaki kümelenmemiş dizini 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); GOBu dizin oluşturulduktan sonra kilitlenme artık tekrar meydana gelmez.
Yabancı anahtar kısıtlamalarına başvuran sütunlarda yapılan değişikliklerden kaynaklanan kilitlenmelerde,
FOREIGN KEYreferans 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 geniş dizinler ve büyük tablolardaki dizinler için dizinlerin avantajlarını değerlendirmeye yardımcı olmak amacıyla, 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
SalesLT.vProductAndDescriptiondizine alınmış görünümü bırakmaktır. Bu dizinli 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, bir kilitlenmeye dahil olan işlemlerden biri veya daha fazlası için işlem yalıtım düzeyini anlık olarak ayarlamak, tıkamaları ve kilitlenmelerin yeniden oluşmasını önleyebilir.
Bu teknik,
SELECTdeyimlerinde kullanıldığında, veritabanında okundu olarak taahhüt edilen anlık görüntü devre dışı bırakıldığında büyük olasılıkla başarılı olacaktır. Okunduğunda onaylanan anlık görüntü devre dışı bırakıldığında, okuma onaylı yalıtım düzeyini kullananSELECTsorguları paylaşılan (S) kilitler 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.Okunabilir anlık görüntü yalıtımının etkinleştirildiği veritabanlarında,
SELECTsorgular paylaşılan (S) kilitleri gerektirmez, bu da verileri değiştiren işlemler arasında kilitlenmelerin oluşma olasılığını artırır. Verileri değiştiren birden çok işlem arasında kilitlenmelerin oluştuğu durumlarda, anlık görüntü izolasyonu kilitlenme yerine güncelleme çakışmasıyla sonuçlanabilir. Buna benzer şekilde işlemlerden birinin işlemini yeniden denemesi gerekir.Sorgu Deposu ile bir planı zorla. 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 fark edebilirsiniz. Sorgu Deposu'nda bir planı zorlayarak kilitlenmenin tekrar oluşmasını önleyebilirsiniz.
Transact-SQL'i değiştirin. Kilitlenmenin yeniden oluşmasını önlemek için Transact-SQL 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 ifadeleri, nesnelere aynı sırayla erişilecek ş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.
Not
Bazı durumlarda, kilitlenmeye dahil olan 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, bir veya daha fazla oturumun kilitlenme önceliğini ayarlayabilirsiniz. Bu, kilitlenmenin yeniden oluşmasını engellemese de, gelecekteki kilitlenmelerin etkisini azaltabilir.
XEvents oturumlarını bırakma
Kritik veritabanlarında kilitlenme bilgilerini toplamak için bir XEvents oturumunu uzun süre çalışır durumda bırakabilirsiniz. Bir olay dosyası hedefi kullanırsanız, birden çok kilitlenme oluşursa bu büyük dosyalara neden olabilir. Azure Depolama'daki blob dosyalarını, şu anda yazılmakta olan dosya hariç, etkin bir izleme için silebilirsiniz.
Bir XEvents oturumunu kaldırmak istediğinizde, seçilen hedef türü ne olursa olsun, Transact-SQL'de oturumu bırakma işlemi aynıdır.
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'daki bloblarda depolanan olay dosyası hedefleriyle çalışmayı basitleştiren tek başına bir uygulamadır. Depolama Gezgini kullanarak:
XEvent oturum verilerini tutmak için bir blob kapsayıcısı oluşturun.
Blob kapsayıcısı için paylaşılan erişim imzasını (SAS) alın.
Genişletilmiş Olaylar ile Azure SQL Veritabanı'de kilitlenme graflarını toplama bölümünde belirtildiği gibi okuma, yazma ve liste izinleri gereklidir.
?alanındaki baştakiQuery stringkarakterini kaldırarak, değeri veritabanı kapsamlı kimlik bilgisi oluştururken bir gizli dizi olarak kullanın.
Blob kapsayıcısından genişletilmiş olay dosyalarını görüntüleyin ve indirin .
Azure Depolama Gezginiİndirin.
İlgili içerik
- Engelleme sorunlarını anlama ve çözme
- İşlem Kilitleme ve Satır Sürümü Oluşturma Kılavuzu
- Kilitlenmeler kılavuzu
- İŞLEM YALITIM DÜZEYİNİ AYARLAMA
- Azure SQL Veritabanı: Otomatik ayarlama ile performans ayarlamasını iyileştirme
- Azure SQL ile tutarlı performans sunma
- Geçici hatalar için yeniden deneme mantığı