Ekinlikler
31 Mar 23 - 2 Nis 23
En büyük SQL, Fabric ve Power BI öğrenme etkinliği. 31 Mart – 2 Nisan. 400 ABD doları tasarruf etmek için FABINSIDER kodunu kullanın.
Bugün kaydolunBu tarayıcı artık desteklenmiyor.
En son özelliklerden, güvenlik güncelleştirmelerinden ve teknik destekten faydalanmak için Microsoft Edge’e yükseltin.
Bu makalede, eşzamanlı işlemler sırasında kilit bellek tüketimini ve engellemeyi azaltmak için iyileştirilmiş bir işlem kilitleme mekanizması sunan bir veritabanı motoru özelliği olan optimize edilmiş kilitleme tanıtılmaktadır.
Optimizasyonlu kilitleme, büyük işlemler için bile çok az sayıda kilit tutularak kilit belleğinin azaltılmasına yardımcı olur. İyileştirilmiş kilitleme, ayrıca kilit yükseltmelerini de önler. Bu, tabloya daha fazla eşzamanlı erişim sağlar.
Optimize edilmiş kilitleme, iki birincil bileşenden oluşur: işlem tanımlayıcısı (TID) kilitleme ve nitelemeden sonra kilitleme (LAQ).
Mesela:
X
) satır kilidi gerektirebilir.X
satır kilidi gerekebilir, ancak her satır güncelleştirildiğinde her kilit serbest bırakılır ve işlemin sonuna kadar yalnızca bir TID kilidi tutulur. Kilitler hızlı bir şekilde yayınlandığından, kilit bellek kullanımı azalır ve kilit yükseltme oluşma olasılığı çok daha düşüktür, bu da iş yükü eşzamanlılığını iyileştirir.Not
İyileştirilmiş kilitlemeyi etkinleştirmek, INSERT
, UPDATE
, DELETE
, MERGE
gibi Veri Değiştirme Dili (DML) deyimleri tarafından alınan satır ve sayfa kilitlerini azaltır veya ortadan kaldırır. Şema kilitleri gibi diğer veritabanı ve nesne kilit türleri üzerinde hiçbir etkisi yoktur.
İyileştirilmiş kilitleme, Azure SQL Veritabanı'nda ve yalnızca Microsoft Fabric
İyileştirilmiş kilitleme şu anda Azure SQL Yönetilen Örneği'nde veya SQL Server'da kullanılamamaktadır.
İyileştirilmiş kilitleme, kullanıcı veritabanı başına etkinleştirilir. Veritabanınıza bağlanın ve ardından en iyi duruma getirilmiş kilitlemenin etkinleştirilip etkinleştirilmediğini denetlemek için aşağıdaki sorguyu kullanın:
SELECT IsOptimizedLockingOn = DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn');
Sonuç | Açıklama |
---|---|
0 |
İyileştirilmiş kilitleme devre dışı bırakıldı. |
1 |
İyileştirilmiş kilitleme etkinleştirildi. |
NULL |
İyileştirilmiş kilitleme kullanılamaz. |
Optimize edilmiş kilitleme, diğer veritabanı özelliklerine dayanır.
Azure SQL Veritabanı'nda hem ADR hem de RCSI varsayılan olarak etkindir. Geçerli veritabanınızda bu seçeneklerin etkinleştirildiğini doğrulamak için veritabanına bağlanın ve aşağıdaki T-SQL sorgusunu çalıştırın:
SELECT name,
is_read_committed_snapshot_on,
is_accelerated_database_recovery_on
FROM sys.databases
WHERE name = DB_NAME();
Bu, iyileştirilmiş kilitleme etkinleştirilmediğinde oluşan davranışın kısa bir özetidir. Daha fazla bilgi için İşlem kilitleme ve satır sürümleme kılavuzunugözden geçirin.
Veritabanı altyapısında kilitleme, işlemlerin ACID özelliklerini garanti etmek için birden çok işlemin aynı verileri aynı anda güncelleştirmesini engelleyen bir mekanizmadır.
Bir işlemin verileri değiştirmesi gerektiğinde, veriler üzerinde bir kilit talep eder. Veriler üzerinde başka çakışan kilitler tutulmazsa kilit verilir ve işlem değişiklikle devam edebilir. Veriler üzerinde çakışan başka bir kilit tutulursa, işlemin devam edebilmesi için kilidin serbest bırakılmasını beklemesi gerekir.
Birden çok işlem aynı verilere eşzamanlı olarak erişmeye çalıştığında, veritabanı altyapısının eşzamanlı okuma ve yazma işlemleriyle olası karmaşık çakışmaları çözmesi gerekir. Kilitleme, motorun ANSI SQL işlem yalıtım seviyelerininsemantiğini sağlayabildiği mekanizmalardan biridir. Veritabanlarında kilitleme çok önemli olsa da, düşük eşzamanlılık, kilitlenmeler, karmaşıklık ve kilit yükü performansı ve ölçeklenebilirliği etkileyebilir.
satır sürüm oluşturma tabanlı yalıtım düzeyleri kullanımda olduğunda veya ADR etkinleştirildiğinde, veritabanındaki her satır dahili olarak bir işlem kimliği (TID) içerir. Bu TID diskte kalıcı hale getirilir. Bir satırı değiştiren her işlem, bu satırı TID değeriyle damgalar.
TID kilitlemesi ile, satırın anahtarını kilitlemek yerine, satırın TID'sine kilit uygulanır. Değiştiren işlem, TID'si üzerinde bir X
kilidi tutar. Diğer işlemler, ilk işlem tamamlanana kadar beklemek için TID üzerinde bir S
kilidi edinir. TID kilitleme ile, değişiklikler için sayfa ve satır kilitleri alınmaya devam eder, ancak her satır değiştirildiğinde her sayfa ve satır kilidi serbest bırakılır. İşlem sonuna kadar tutulan tek kilit, TID kaynağındaki tek X
kilididir ve birden çok sayfa ve satır (anahtar) kilidini değiştirir.
Yazma işlemi etkinken geçerli oturum için kilitleri gösteren aşağıdaki örneği göz önünde bulundurun:
/* Is optimized locking is enabled? */
SELECT IsOptimizedLockingOn = DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn');
CREATE TABLE t0
(
a int PRIMARY KEY,
b int NULL
);
INSERT INTO t0 VALUES (1,10),(2,20),(3,30);
GO
BEGIN TRANSACTION;
UPDATE t0
SET b = b + 10;
SELECT *
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID
AND
resource_type IN ('PAGE','RID','KEY','XACT');
COMMIT TRANSACTION;
GO
DROP TABLE IF EXISTS t0;
İyileştirilmiş kilitleme etkinleştirilirse, istek X
(işlem) kaynağında yalnızca tek bir XACT
kilidi tutar.
İyileştirilmiş kilitleme etkinleştirilmediyse, aynı istek dört kilit tutar: satırları içeren sayfada bir IX
(amaç özel kullanım) kilidi ve her satırda üç X
anahtar kilidi:
sys.dm_tran_locks dinamik yönetim görünümü (DMV), en iyi duruma getirilmiş kilitlemeyi uygulamada gözlemleme gibi kilitleme sorunlarını incelemede veya gidermede yararlıdır.
TID altyapısını temel alarak yapılan iyileştirilmiş kilitleme, INSERT
, UPDATE
ve DELETE
gibi DML deyimlerinin kilit alma şeklini değiştirir.
İyileştirilmiş kilitleme olmadan, sorgu önkoşulları önce güncelleştirme (U
) satır kilidi alınarak bir taramada satır satır denetlenir. Koşul karşılanırsa, satırı güncelleştirmeden önce özel (X
) satır kilidi alınır ve işlem sonuna kadar tutulur.
İyileştirilmiş kilitleme ile ve READ COMMITTED
anlık görüntü yalıtım düzeyi (RCSI) etkinleştirildiğinde, önkoşullar hiçbir kilit alınmadan satırın en son kaydedilmiş sürümünde iyimser bir şekilde denetlenebilir. Koşul karşılamıyorsa, sorgu taramada bir sonraki satıra geçer. Koşul karşılanırsa, satırı güncelleştirmek için bir X
satır kilidi alınır.
Başka bir deyişle, değiştirilmek üzere satırın nitelemesi 'den sonra kilit alınır.
X
satır kilidi, satır güncelleştirmesi tamamlanır tamamlanmaz, işlem bitmeden önce serbest bırakılır.
Koşul değerlendirmesi hiçbir kilit alınmadan gerçekleştirildiğinden, farklı satırları değiştiren eşzamanlı sorgular birbirini engellemez.
Mesela:
CREATE TABLE t1
(
a int NOT NULL,
b int NULL
);
INSERT INTO t1
VALUES (1,10),(2,20),(3,30);
GO
Oturum 1 | Oturum 2 |
---|---|
BEGIN TRANSACTION; UPDATE t1 SET b = b + 10 WHERE a = 1; |
|
BEGIN TRANSACTION; UPDATE t1 SET b = b + 10 WHERE a = 2; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
İyileştirilmiş kilitleme olmadan oturum 2 engellenir çünkü oturum 1, 2. oturumun güncelleştirilmesi gereken satırda U
bir kilit tutar. Ancak optimize edilmiş kilitleme ile, U
kilitler alınmadığı ve 1. satırın en son işlenmiş sürümünde sütun a
1'e eşit olduğu için oturum 2'nin koşulunu karşılamadığından, oturum 2 engellenmez.
LAQ, bir satırın koşulu kontrol edildikten sonra değiştirilmediği varsayımıyla iyimser bir yaklaşımla uygulanır. Koşul karşılanırsa ve koşul denetlendikten sonra satır değiştirilmediyse, geçerli işlem tarafından değiştirilir.
U
kilitler alınmadığından, koşul değerlendirildikten sonra eşzamanlı bir işlem satırda değişiklik yapabilir. Satırda X
TID kilidi tutan etkin bir işlem varsa, veritabanı altyapısı işlemin tamamlanmasını bekler. Koşul daha önce değerlendirildikten sonra satır değiştiyse, veritabanı altyapısı satırı değiştirmeden önce koşulu yeniden değerlendirir (yeniden niteler). Koşul yine de karşılanırsa, satır değiştirilir.
Koşul yeniden niteleme, sorgu altyapısı işleçlerinin bir alt kümesi tarafından desteklenir. Koşul yeniden değerlendirmesi gerekiyorsa, ancak sorgu planı koşul yeniden nitelemesini desteklemeyen bir işleç kullanıyorsa, veritabanı motoru dahili olarak ifade işlemeyi durdurur ve LAQ olmadan yeniden başlatır. Böyle bir durdurma gerçekleştiğinde, lock_after_qual_stmt_abort
genişletilmiş olay tetiklenir.
Değişken ataması olan UPDATE
deyimleri ve OUTPUT yan tümcesine sahip deyimler gibi bazı deyimler, semantikleri değiştirilmeden durdurulamaz ve yeniden başlatılamaz. Bu tür deyimler için LAQ kullanılmaz.
Aşağıdaki örnekte, başka bir işlem satırı değiştirdiğinden koşul yeniden değerlendirilir:
CREATE TABLE t3
(
a int NOT NULL,
b int NULL
);
INSERT INTO t3 VALUES (1,10),(2,20),(3,30);
GO
Oturum 1 | Oturum 2 |
---|---|
BEGIN TRANSACTION; UPDATE t3 SET b = b + 10 WHERE a = 1; |
|
BEGIN TRANSACTION; UPDATE t3 SET b = b + 10 WHERE a = 1; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Niteleme sonrasında kilitleme (LAQ) kullanıldığında, bazı ifadeler dahili olarak yeniden başlatılabilir ve LAQ kullanılmadan işlenebilir, ve'de açıklandığı gibi. Bu sık sık gerçekleşirse, yinelenen işlemenin yükü önemli hale gelebilir. Bu ek yükü en düşük düzeyde tutmak için iyileştirilmiş kilitleme, yinelenen işlemleri izlemek için bir buluşsal mekanizma kullanır. Bu mekanizma, ek yük eşiği aşarsa veritabanı için LAQ'u devre dışı bırakır.
Heuristik mekanizmanın amaçları doğrultusunda, bir ifade tarafından yapılan iş, işlediği sayfaların sayısıyla (mantıksal okumalar) ölçülür. Veritabanı motoru, sorgu işleme başlatıldıktan sonra başka bir işlem tarafından güncellenmiş bir satırı güncelliyorsa, sorgu tarafından yapılan iş, sorgunun durdurulup yeniden başlatılabileceğinden potansiyel olarak boşa gitmiş kabul edilir. Sistem, potansiyel olarak boşa harcanabilecek toplam çalışmayı ve veritabanındaki tüm ifadeler tarafından yapılan toplam çalışmayı izler.
Boşa harcanan çalışma yüzdesi eşiği aşarsa, LAQ veritabanı için devre dışı bırakılır. Yeniden başlatılan deyimlerin sayısı belirli bir eşiği aşarsa LAQ da devre dışı bırakılır.
Eğer israf edilen iş ve tekrar başlatılan komutların sayısı ilgili eşiklerinin altına düşerse, LAQ veritabanı için yeniden etkinleştirilir.
Okunabilir onaylı anlık görüntü yalıtımı (RCSI) altındaki katı işlem yürütme sırasına dayanan eşzamanlı iş yükleri, optimize edilmiş kilitleme etkinleştirildiğinde sorgu davranışında farklılıklar yaşayabilir.
T2 işleminin T1 işlemi sırasında güncelleştirilen sütun t4
temelinde tablo b
güncelleştirdiği aşağıdaki örneği göz önünde bulundurun.
CREATE TABLE t4
(
a int NOT NULL,
b int NULL
);
INSERT INTO t4
VALUES (1,1);
GO
Oturum 1 | Oturum 2 |
---|---|
BEGIN TRANSACTION T1; UPDATE t4 SET b = 2 WHERE a = 1; |
|
BEGIN TRANSACTION T2; UPDATE t4 SET b = 3 WHERE b = 2; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Önceki senaryonun sonucunu nitelendirme sonrası kilit (LAQ) ile ve kilit olmadan değerlendirelim.
LAQ olmadan
LAQ olmadan, T2 işlemindeki UPDATE
deyimi engellenir ve T1 işleminin tamamlanmasını bekler. T1 tamamlandıktan sonra T2, koşulu karşılandığından b
satır ayarı sütununu 3
olarak güncelleştirir.
her iki işlem de işlendikten sonra tablo t4
aşağıdaki satırları içerir:
a | b
1 | 3
LAQ ile
LAQ ile T2 işlemi, sütun b
'ın 1
'e eşit olduğu satırın en son işlenmiş (commit edilmiş) sürümünü kullanarak koşulunu (b = 2
) değerlendirir. Satır uygun değil; bu nedenle atlanır ve ifade T1 işlemi tarafından engellenmeden tamamlanır. Bu örnekte LAQ engellemeyi kaldırır ancak farklı sonuçlara yol açar.
her iki işlem de işlendikten sonra tablo t4
aşağıdaki satırları içerir:
a | b
1 | 2
Önemli
LAQ olmadan bile uygulamalar, satır sürümlendirmeye dayalı yalıtım düzeyleri kullanılırken veritabanı motorunun kilitleme ipuçları kullanmadan katı sıralamayı garanti ettiğini varsaymamalıdır. RCSI altında eşzamanlı iş yükleri çalıştıran ve işlemlerin katı yürütme sırasını kullanan müşterilere yönelik genel önerimiz (önceki örnekte gösterildiği gibi) SERIALIZABLE
kullanmaktır.
Aşağıdaki iyileştirmeler, iyileştirilmiş kilitleme etkinleştirildiğinde engelleme ve kilitlenme sorunlarını izlemenize ve gidermenize yardımcı olur:
XACT
, S
kilidi üzerindeki bekleme türleri ve sys.dm_os_wait_stats (Transact-SQL)içindeki kaynak açıklamaları: LCK_M_S_XACT_READ
- Görev, okuma amacıyla XACT
wait_resource
türünde paylaşılan kilit beklediğinde gerçekleşir.LCK_M_S_XACT_MODIFY
- Bir görev, XACT
wait_resource
türünde değişiklik yapmak amacıyla bir paylaşımlı kilit beklediğinde gerçekleşir.LCK_M_S_XACT
- Görev, amacın çıkarılamadığı XACT
wait_resource
türünde paylaşılan kilit beklerken gerçekleşir. Bu senaryo yaygın değildir.XACT
kaynakları kilitliyor. Daha fazla bilgi için bkz. resource_description
sys.dm_tran_locks (Transact-SQL).XACT
bekleme kaynakları. Daha fazla bilgi için bkz. wait_resource
sys.dm_exec_requests (Transact-SQL).<resource-list>
kilitlenme raporundaki her kaynağın altında, her <xactlock>
öğesi, bir kilitlenmenin her üyesinin kilitleri için temel kaynakları ve belirli bilgileri raporlar. Daha fazla bilgi ve örnek için bkz. Optimizasyonlu kilitleme ve kilitlenmeler.lock_after_qual_stmt_abort
olayı, bir deyim başka bir işlemle yaşanan çakışma nedeniyle dahili olarak durdurulduğunda ve yeniden başlatıldığında tetiklenir. Daha fazla bilgi için bkz. Vasıflandırmadan sonra kilitleme (LAQ).İyileştirilmiş kilitlemenin avantajlarını en üst düzeye çıkarmak için, veritabanında okuma kaydedilmiş anlık görüntü yalıtımı (RCSI) etkinleştirmeniz ve varsayılan yalıtım düzeyi olarak READ COMMITTED
yalıtımı kullanmanız önerilir. Henüz etkinleştirilmemişse, master
veritabanına bağlanıp aşağıdaki deyimi yürüterek RCSI'yi etkinleştirin:
ALTER DATABASE [your-database-name] SET READ_COMMITTED_SNAPSHOT ON;
Azure SQL Veritabanı'nda RCSI varsayılan olarak etkinleştirilir ve READ COMMITTED
varsayılan yalıtım düzeyidir. RCSI etkinleştirildiğinde ve READ COMMITTED
yalıtım düzeyini kullanırken, okuyucular ifadeye başlandığında alınan anlık görüntüden satırın bir sürümünü okur. LAQ ile yazılımcılar, satırların en son işlenmiş sürümüne göre ve U
kilitleri almadan koşula göre satırları nitelendirir. LAQ ile sorgu, yalnızca satır uygun olduğunda ve o satırda etkin bir yazma işlemi mevcutsa bekler. En son taahhüt edilen sürüme göre nitelendirme ve yalnızca nitelikli satırları kilitleme, engellemeyi azaltır ve eşzamanlılığı artırır.
Azaltılmış engellemeye ek olarak, gerekli kilit belleği azalır. Bunun nedeni, okuyucuların hiçbir kilit almamalarından ve yazarların işlemin sonuna kadar tutulan kilitler yerine yalnızca kısa süreli kilitler almasıdır.
REPEATABLE READ
veya SERIALIZABLE
gibi daha katı yalıtım düzeyleri kullandığınızda, veritabanı altyapısı hem okuyucular hem de yazarlar için iyileştirilmiş kilitleme etkin olsa bile işlemin sonuna kadar satır ve sayfa kilitlerini tutar ve böylece bellek kullanımını engeller ve kilitler.
İyileştirilmiş kilitleme etkinleştirildiğinde, , UPDLOCK
, READCOMMITTEDLOCK
, XLOCK
gibi HOLDLOCK
dikkate alınır, ancak bunlar iyileştirilmiş kilitlemenin avantajını azaltır. Kilit ipuçları, veritabanı motorunu satır veya sayfa kilitleri almaya ve bu kilitleri kilit ipuçlarının amacı doğrultusunda işlem sonuna kadar tutmaya zorlar. Bazı uygulamalar, örneğin UPDLOCK
ipucuyla bir satırı okurken ve daha sonra güncelleştirirken kilit ipuçlarının gerekli olduğu bir mantığa sahiptir. Kilit ipuçlarını yalnızca gerektiğinde kullanmanızı öneririz.
İyileştirilmiş kilitleme sayesinde, mevcut sorgularda kısıtlama yoktur ve sorguların yeniden yazılması gerekmez. İpuçları kullanmayan sorgular, en iyi şekilde iyileştirilmiş kilitlemeden yararlanır.
Sorgudaki bir tablodaki tablo ipucu, aynı sorgudaki diğer tablolar için iyileştirilmiş kilitlemeyi devre dışı bırakmaz. Ayrıca, iyileştirilmiş kilitleme yalnızca INSERT
, UPDATE
, DELETE
veya MERGE
gibi bir DML deyimi tarafından güncelleştirilen tabloların kilitleme davranışını etkiler. Mesela:
CREATE TABLE t5
(
a int NOT NULL,
b int NOT NULL
);
CREATE TABLE t6
(
a int NOT NULL,
b int NOT NULL
);
GO
INSERT INTO t5 VALUES (1,10),(2,20),(3,30);
INSERT INTO t6 VALUES (1,10),(2,20),(3,30);
GO
UPDATE t5 SET t5.b = t6.b
FROM t5
INNER JOIN t6 WITH (UPDLOCK)
ON t5.a = t6.a;
Önceki sorgu örneğinde, yalnızca tablo t6
kilitleme ipucundan etkilenirken, t5
hala iyileştirilmiş kilitlemeden yararlanabilir.
UPDATE t5
SET t5.b = t6.b
FROM t5 WITH (REPEATABLEREAD)
INNER JOIN t6
ON t5.a = t6.a;
Önceki sorgu örneğinde, yalnızca tablo t5
REPEATABLE READ
yalıtım düzeyini kullanır ve işlemin sonuna kadar kilitleri tutar.
t5
için yapılan diğer güncelleştirmeler, iyileştirilmiş kilitlemeden yararlanmaya devam edebilir. Aynı durum HOLDLOCK
ipucu için de geçerlidir.
Azure SQL Veritabanı'nda evet.
Bkz. İyileştirilmiş kilitleme etkinleştirildi mi?.
ADR devre dışı bırakılırsa, iyileştirilmiş kilitleme de otomatik olarak devre dışı bırakılır.
RCSI kullanan müşteriler için, iyileştirilmiş kilitleme etkinleştirildiğinde iki sorgu arasında engellemeyi zorlamak için READCOMMITTEDLOCK
sorgu ipucunu kullanın.
Hayır, çünkü DML ifadeleri salt okunur çoğaltmalarda çalıştırılamaz ve bu nedenle karşılık gelen satır ve sayfa kilitleri alınmaz.
Şu anda yok.
Ekinlikler
31 Mar 23 - 2 Nis 23
En büyük SQL, Fabric ve Power BI öğrenme etkinliği. 31 Mart – 2 Nisan. 400 ABD doları tasarruf etmek için FABINSIDER kodunu kullanın.
Bugün kaydolunEğitim
Öğrenme yolu
Azure SQL'de sorgu performansını iyileştirme - Training
Azure SQL'de sorgu performansını iyileştirme
Belgeler
İşlem kilitleme ve satır sürüm oluşturma kılavuzu - SQL Server
İşlem kilitleme ve satır sürüm oluşturma kılavuzu
SQL Server'da Anlık Görüntü Yalıtımı - ADO.NET
SQL Server'da anlık görüntü yalıtımına ve satır sürümüne genel bir bakış okuyun ve yalıtım düzeyleriyle eşzamanlılığı yönetmeyi öğrenin.
Anlık görüntü işlemi yalıtım düzeyini etkinleştirme - SQL Server
Bu makalede, Analysis Services'te anlık görüntü işlem yalıtım düzeyini etkinleştirmek için izlemeniz gereken adımlar açıklanmaktadır.