Latch Contention
- Şiddetli latch contention, veritabanınızı önemli ölçüde yavaşlatabilir. Bir latch contention sorunu ile uğraşırken, belirli sorgu türlerini ve her bir beklemenin neden olduğu toplam bekleme süresini öğrenmek için aşağıdaki sorguyu çalıştırabiliriz.
SQL> select event, sum(P3), sum(seconds_in_wait) seconds_in_wait
from v$session_wait
where event like 'latch%'
group by event;
- Önceki sorgu, bu oturum tarafından şu an için bekletilen kilitlemeleri gösterir. Tüm instance ın çeşitli kilitlemeler için beklediği süreyi bulmak için aşağıdaki SQL i çalıştırın:
SQL> select wait_class, event, time_waited / 100 time_secs
from v$system_event e
where e.wait_class <> 'Idle' AND time_waited > 0
union
select 'Time Model', stat_name NAME,
round ((value / 1000000), 2) time_secs
from v$sys_time_model
where stat_name not in ('background elapsed time', 'background cpu time')
order by 3 desc;
WAIT_CLASS EVENT TIME_SECS
------------ ------------------------- ----------
Concurrency library cache pin 622.24
Concurrency latch: library cache 428.23
Concurrency latch: library cache lock 93.24
Concurrency library cache lock 24.20
Concurrency latch: library cache pin 60.28
…
- Sorgudaki çıktı, Concurrency wait classın bir parçası olan latch ile ilgili wait events bekleme olaylarını gösterir.
- Ayrıca, burada gösterildiği gibi, lache contentionun bir sorun olup olmadığını görmek için AWR rapordaki top beş bekleme olayını görüntüleyebilirsiniz:
Event Waits Time(s) (ms) Time Wait Class
------------------------ ------------ ---------- ------- -------- ------------
db file sequential read 42,005,780 232,838 6 73.8 User I/O
CPU time 124,672 39.5 Other
latch free 11,592,952 76,746 7 24.3 Other
wait list latch free 107,553 2,088 19 0.7 Other
latch: library cache 1,135,976 1,862 2 0.6 Concurrency
- En yaygın Oracle latch wait türleri :
- Shared pool ve library latches: Bunların çoğu, her seferinde biraz değişen aynı SQL ifadesini tekrar tekrar çalıştıran veritabanından kaynaklanmaktadır. Örneğin, bir veritabanı her defasında bir değişken için farklı bir değerle 10,000 kez bir SQL deyimi çalıştırabilir. Tüm bu durumlarda çözüm, bind değişkenlerini kullanmaktır.
Her yürütmeden sonra tüm imleçleri açıkça kapatan bir uygulama da bu tür bir beklemeye katkıda bulunabilir.
Bunun çözümü CURSOR_SPACE_FOR_TIME başlatma parametresini belirtmektir. Shared pool çok küçük olduğunda latch sorununa katkıda bulunabilir, bu nedenle SGA boyutunuzu kontrol edin.
- Cache buffers LRU chain: Bu kilitlenme olayları genellikle aşırı buffer cache kullanımı nedeniyle oluşur ve gerek aşırı physical reads gerekse logical reads nedeniyle olabilir. Veritabanı "full table scans" gerçekleştiriyor veya "large index range scans" gerçekleştiriyor. Bu tür latch beklemelerinin olağan nedeni, bir index eksikliği veya unselective index varlığıdır. Ayrıca buffer cache boyutunu artırmanız gerekip gerekmediğini kontrol edin.
- Cache buffer chains: Bu beklemeler, art arda erişilen bir veya daha fazla hot bloktan kaynaklanmaktadır.
Sequence kullanmak yerine tablonun rowlarının sequence numaralarını oluşturmak için güncelleyen uygulama kodu , hot bloklara neden olabilir.
Benzer işlemlerle çok sayıda işlem unselective index tararken, cache buffer chains wait event olayını da görebilirsiniz.
- Ayrıca, sequences kullanıyorsanız bunları daha büyük bir cache boyutu ayarı ile yeniden oluşturun ve ORDER yan tümcesini kullanmaktan kaçınmaya çalışın. Bir sequence in CACHE değeri, veritabanının SGA'da önbelleğe alınması gereken sequence değerlerinin sayısını belirler. Veritabanınız çok sayıda insert ve update işliyorsa, sequence değerleri için contention u önlemek için cache boyutunu artırmayı düşünün. Varsayılan olarak, cache 20 değerlerine ayarlanır. Değerler, önbelleği sık sık tüketmek için hızlı bir şekilde istenirse, sonuç çıkabilir. Bir RAC ortamıyla uğraşıyorsanız, NOORDER yan tümcesini kullanmak sıraya alınan sıralı değerlerin zorla sıralanması nedeniyle enqueue contentionu önleyecektir.
Nasıl Çalışır:
- Oracle, çeşitli bellek yapılarını korumak için latches olarak adlandırılan iç kilitleri kullanıyor.
Bir sunucu işlemi bir latch almaya çalışırken bunu yapmazsa, bu girişim latchsız bir bekleme olayı olarak sayılır.
Oracle, tüm latch beklemelerini tek bir latchsız bekleme olayına gruplamıyor.
Oracle genel bir latchsız bekleme olayı kullanıyor, ancak bu yalnızca küçük latch ile ilgili bekleme olayları içindir.
En yaygın kullanılan latchlar için, Oracle bekleme olayı türünün adıyla çeşitli alt gruplardaki latch-related wait events olayları
kullanır. latch event türüne bakarak tam latch türünü belirleyebilirsiniz. Örneğin, latch event latch: library cache, library cache latches için çakışmayı belirtir.
Benzer şekilde, latch: cache buffer chains olayı arabellek önbellek için çakışmayı belirtir.
- Oracle, birden fazla oturumun SGA'nın aynı alanını güncellemesini önlemek için çeşitli latch işlemleri kullanır.
Çeşitli veritabanı işlemleri, SGA yı okumak veya güncellemek için sessionlar gerektirir. Örneğin, bir oturum bir veri bloğunu diskten SGA ya okurken, buffer cache de en son kullanılan kaydı değiştirmelidir. Benzer şekilde, veritabanı bir SQL deyimini pars ettiğinde, bu deyim SGA'nın library cache bileşenine eklenmelidir. Oracle, veritabanı işlemlerinin birbirine girmesini ve SGA'yı bozmasını önlemek için kilitleri kullanır.
- Bir veritabanı işlemi, çok kısa sürelerle, genellikle birkaç nanosaniye süren bir latch alıp tutmalıdır.
Latch zaten kullanımda olduğu için bir oturum bir latch kazanamazsa, oturum "sleep" durumuna geçmeden önce birkaç kez deneyecek. Oturum yeniden uyanacak ve ihtiyaç duyduğu mandalı hâlâ alamıyorsa, uyku moduna geçmeden önce birkaç kez daha deneyecek.
Oturum uyku moduna girdiğinde her sefer daha uzun süre kalır, bu durum her latch edinme girişimi arasındaki zaman aralığını artırır.
Dolayısıyla, veritabanızda latchler için ciddi bir contention varsa, yanıt sürelerinin ve çıktılarının ciddi bir şekilde düşmesine neden olur.
- Çok hızlı bir donanımda çalışan iyi tasarlanmış bir veritabanında bile "latch contention" olduğunu görünce şaşırmayın.
Bir miktar latch contention, "özellikle cache buffers chain latch events" olayları, kaçınılmazdır.
Latch beklemeleri çok yüksekse ve veritabanı performansını yavaşlatıyorsa endişelenmelisiniz.
- Shared pool latches ın yanı sıra library cache latches den kaynaklanan sorunlar, genellikle bind değişkenlerini kullanmayan uygulamalar nedeniyle oluşur.
Uygulamanız bind değişkenlerini içerecek şekilde yeniden kodlanamazsa, hepsi kaybolmaz.
CURSOR_SHARING parametresini, uygulamanız kodda belirtilmemiş olsa bile Oracle'ın bind değişkenlerini kullanmaya zorlaması için ayarlayabilirsiniz.
Bu parametre için hard-coded değişken değerleri için bind değişkenlerinin yerini zorlamak için FORCE veya SIMILAR ayarı arasından seçim yapabilirsiniz. Bu parametrenin varsayılan ayarı EXACT'tır; bu, veritabanının literal değişkenleri için bind değişkenlerini değiştirmeyeceği anlamına gelir. CURSOR_SHARING parametresini FORCE olarak ayarladığınızda Oracle tüm değişkenleri bind değişkenlerine dönüştürür. SIMILAR , bind değişkenlerini yalnızca bir deyimin execution planını değiştirmediğinde kullanır. Böylece, SIMILAR ayarı, veritabanını literal yerine bind değişkenlerini kullanmaya zorlamak için daha güvenli bir yol gibi görünüyor.CURSOR_SHARING parametresini FORCE olarak ayarlama güvenliğiyle ilgili bazı endişelerimiz olmasına rağmen, bu ayarı kullanırken gerçek bir sorun görmedik.
CURSOR_SHARING parametresini FORCE veya SIMILAR olarak ayarladığınızda library cachete contention genellikle kaybolur.
CURSOR_SHARING parametresi, latch contentionı ortadan kaldırarak hemen veritabanı performansını artıracak birkaç Oracle gümüş mermiden biridir. Library cache latch contention ile uğraşırken güvenle kullanın.
- Cache buffer chains latch contention, genellikle, aynı veri bloklarını art arda okuyan bir oturumdan kaynaklanmaktadır.
Öncelikle, cache buffers chain latches in en yüksek miktarından sorumlu olan SQL deyimini belirleyin ve onu tune edip etmeyeceğinize karar verin. Bu, latch contentionı azaltmazsa, art arda okunmakta olan gerçek hot blokları tanımlamanız gerekir.
- Hot bir blok bir index segmentine aitse, tabloyu partitioning yapmayı ve local indexleri kullanmayı düşünebilirsiniz.
Örneğin, bir hash partitioning şeması, yükü multiple partitioned index arasında yaymanıza izin verir.
Ayrıca, index eklenen sütunlara dayalı olarak tabloyu hash cluster based e dönüştürmeyi de düşünebilirsiniz.
Böylece indexin tamamını önleyebilirsiniz. Hot bloklar bunun yerine bir tablo partition a aitse,
bölmeyi dağıtmak için tabloyu bölümlemeyi düşünebilirsiniz. Aynı bloklara tekrar tekrar erişildiğini görmek için uygulama tasarımını yeniden gözden geçirmek ve böylece onları "hot" hale getirmek de isteyebilirsiniz.