Pages

20 Nisan 2011 Çarşamba

Oracle muteksler

Mutex(mutual exclusion-karşılıklı dışlama), kısa formu karşılıklı dışlamaktır. Mandallarla benzerlik gösteren mutex, SGA alanındaki paylaşımlı veri yapısına kontrollü erişim için kullanılan düşük seviyeli bir serileştirme mekanizmasıdır.  Serileştirme, bir objeyi aşağıdakilerden korumak için gereklidir:

  • Ayrılırken birisi objeye eriştiğinde
  • Obje okunurken başkası tarafından düzenlendiğinde
  • Obje düzenlenirken başkası tarafından okunduğunda 
Muteks tarafından korunan her yapının kendine ait bir muteksi vardır(mesela, ebeveyn(parent) imlecin kendine ait bir muteksi vardır ve her bir yavru(child) imlecinde kendine ait muteksi vardır. Her bir yapı, her bir muteksin bu yapının değişik bir parçasını korumasıyla birden çok muteks tarafından korunabilmektedir. Şimdi bu paragrafı teker teker açalım.

Bir muteks, birden fazla yapıyı koruyabilir. Hem muteksler hemde mandallar serileştirme mekanizmaları olmasına rağmen, muteksler mandalların yapamadığı belirli özelliklere sahiptir.

  • Daha küçük ve daha hızlı
Muteksler, mandallara iyi bir alternatiftir, çünkü daha küçük ve daha hızlı olmasından dolayı daha kolay alınırlar. Muteks alımı, mandal alımı ile kıyaslandığında daha az talimat kullanmaktadır.

  • Daha düşük yanlış çekişme oranı
Mandal, genellikle birçok objeyi korumaktadır. Mandal, bir veya birden fazla “sıcak” objeyi korurken, mandalın kendisi, bu mandal tarafından korunan bir objeye erişirken serileştirme noktası meydana gelir. Bu olay, çekişmenin erişilmeye çalışılan hedef obje için olmasından ziyade, koruma mekanizması için(bu da mandaldır) olmasından dolayı "yanlış çekişme noktası" olarak adlandırılır. Mandalların aksine, muteksler ile her bir korunan yapı için muteks oluşturmak mümkündür.  Bu da demek olurki, her bir yapı kendine ait muteks tarafından korunabildiğinden, daha az yanlış çekişme meydana gelebilmektedir.

  • Mandallar ve pinlerin yerine
Bir muteks, pekçok oturum tarafından, tüm oturumların S(Shared) modda muteksi temin etmesi ile eşzamanlı olarak başvurulanabilir. S modda mutekse başvuran toplam oturum sayısı başvuru miktarı ("ref count") olarak adlandırılır. Bir muteks için “ref count” sayısı muteksin kendisi içinde saklıdır. Ayrıca bir muteks, tek bir oturum tarafından X(Exclusive) modda da tutulabilir.

Mutekslerin ikili bir yapısı vardır. mandallar gibi serileştirme mekanizması olarak işlev yapabildiği gibi, bir objenin library cache içinde bütünlüğünü yitirmesini(aged out) engelleme gibi pin işlevide yapabilir. Örneğin; bir muteksin “ref count” miktarı, library cache pin olayı yerine geçmektedir. Her bir oturum bir imleci çalıştırırken, “library cache pin”i oluşturmak ve silmek yerine, “ref count” miktarını arttırır ve azaltır. Böylece “ref count” deyimi “n distinct pin” ile yer değiştirmiş olur.

Önemli bir dip not olarak şunu bahsetmek gerekirki, mandallar ve muteksler birbirlerinden tamamen bağımsız mekanizmalardır ve böylece bir proses aynı anda hem mandal hemde muteks tutabilir.

Muteks operasyonları, mandallardan daha hızlı ve daha az çekişme meydana getirir, ancak muteks operasyonlarına bağlı bekleme olayları hala mevcuttur. İki tane V$ görünümü muteks uyumaları ile ilgili detaylı bilgi vermektedir.

Bu görünümlerden ilki olan V$MUTEX_SLEEP görünümü, özel bir muteks_tip/lokasyon bileşimi için özet uyuma ve bekleme sürelerini göstermektedir. Aşağıda örnek bir rapor yer almaktadır.

select * from v$mutex_sleep;

MUTEX_TYPE    LOCATION                              SLEEPS   WAIT_TIME
------------- -------------------------------       ------   ---------
Cursor Stat   kksIterCursorStat [KKSSTALOC6]          103    163
Cursor Stat   kksFindCursorStat [KKSSTALOC3]          23157  36724
Cursor Parent kksfbc [KKSCHLCREA]                     1799   10170
Cursor Parent kkspsc0 [KKSPRTLOC27]                   26     627
Cursor Parent kkspsc0 [KKSPRTLOC26]                   122    2872
Cursor Parent kkshbbr [KKSPRTLOC15]                   660    1779
Cursor Parent kksLoadChild [KKSPRTLOC4]               1181   6932
Cursor Parent kksfbc [KKSPRTLOC2]                     9006   34053
Cursor Paren  tkksfbc [KKSPRTLOC1]                    2831   144439
Cursor Pin    kksLockDelete [KKSCHLPIN6]             5021    1055990
Cursor Pin    kkslce [KKSCHLPIN2]                     265549 2792810468
Cursor Pin    kksfbc [KKSCHLPIN1]                     1203   5132409
Cursor Pin    kksfbc [KKSCHLFSP2]                     9279   56902065

İkinci muteks görünümü olan V$MUTEX_SLEEP_HISTORY görünümü ise, özel bir muteks_tip/lokasyon bileşimin belirli bir oturum tarafından tutulurken, oturumların zaman bazlı uyumasını göstermektedir.

Bunun yanında muteks beklemeleri ile ilgili yararlı pek çok script vardır. Andrey Nickolev’in blogunda bunlar yayınlanmıştır ve özellikle 11.2.0.2 öncesi sistemlerde oldukça faydalı scriptlerdir. 11.2.0.2 sürümü üzerine yüklenecek olan 10411618 nolu yama ile “_mutex_spin_count”, “_mutex_wait_time” ve “_mutex_wait_scheme” gibi ek parametreleri içeren ilave muteks bekleme şemaları sisteme yüklenecektir. Bunun yanında “library cache:mutex X” beklemelerinde AWR ile alınan snapshotlarda V$ ve X$ sorgularıda bekleme performans hesaplamasına dahil olduğundan, aşırı mutex çakışmaları raporlanacaktır ve bu bir bug’tır. Bu bug’ı düzeltmek ve gerçek “llibrary cache:mutex x” bekleme performansını gözlemlemek için 10145558 nolu yamanın veritabanına yüklenmesi gerekmektedir. Bu sebeple, muteks çekişmelerinde en optimal Oracle platformu 11.2.0.2 olmaktadır.

Muteks bekleme olayı iki kategoriye ayrılır:

  • “cursor:mutex” bekleme olayı, muteksin ebeveyn imleç üzerinde beklediğini ve blok işlemlerini istatistiklediğini işaret eder.
  • “cursor:pin” olayı ise, “latch:library cache pin” yerine gelen bu muteksin, imleç pin işlemleri esnasındaki beklemeleridir. 
Muteks bekleme olayları iki tiptir

  1. Kısa süreli beklemeler: Bu bekleme olayı nadiren meydana gelir ve bir prosesin muteksi güncellemeye çalışırken başka bir proses tarafından değiştirildiği anda meydana gelir. Bekleme prosesi muteks uygun hale gelene kadar spin çeker. Örneğin; “cursor:pin S” değeri, başka bir proses paylaşımlı imlecin “ref count” değerini güncellerken artar.

  1. Uzun süreli beklemeler: Uzun süreli beklemeler, bir proses başka bir prosesin işlemini bitirmesi için beklerken meydana gelir. Örneğin; “cursor:mutex X”  değeri, bir muteksin exclusive veya paylaşımlı olarak başka proses(ler) tarafından tutulduğu ancak prosesin exclusive erişim istediğinde artış gösterir. “cursor:mutex X” beklemesinde muteksin exclusive olarak verilebilmesi için muteksi tutan oturumun bu muteksi serbest bırakması gerekmektedir. 
Muteks kullanmak hız kazandırır, Oracle 11.0.2 sürümü vePatch 6904068 High CPU usage when there are “cursor: pin S” waits” yamasının yüklenmesinden itibaren daha az CPU tüketir, ve mevcut mandal mekanizması üzerinden anlamlı derecede eşzamanlılığı geliştirmeye izin verir. Library cache imleç pinleri ve ebeveyn çalışmaları için muteks kullanımı, _use_kks_muteks başlangıç parametre değerinin TRUE olarak ayarlanmasıyla etkinleştirilir. Oracle 10.2.0.2 sürümünden itibaren bu parametrenin varsayılan değeri TRUE olarak ayarlanmıştır.

Oracle 11g sürümünde, “library cache load lock” dışındaki tüm library cache ilişkili mandallar ortadan kalkmış ve eşzamanlı işlemler artık muteksler tarafından korunmaya alınmıştır. Library cache mandalları “library cache muteksleri” ile yer değiştirmiştir.

Mutex korumalı işlemler:
Oracle 10.2 sürümünden itibaren V$SQLSTATS görününümden SELECT işlemi muteksler tarafından korunma altına alınmıştır. Muteks korumasındaki işlemler mandallanmış(latched) işlemlerden anlamlı oranda daha hızlıdır ve alt imleç listeleride muteksler tarafından korunmaktadır.

Oracle’da mandallar KSL* modullerini, muteksler ise KGX* modullerini kullanmakta olduğundan birbirinden farklıdırlar.  Genel muteks işlemleri mandal işlemlerinden daha az CPU kullanmaktadır, çünkü muteksler mandallar gibi kompleks değildir ve mandalların yaptığı gibi get/miss oranını devam ettirmez.

Bunun yanında muteksler ve mandalların kıyaslanmasında aşağıdaki noktalar önemlidir;

1) “library cache mandallaması” parsing gibi işlemler için hala gereklidir, çünkü muteksler sadece library cache içindeki pinleme sorunlarını adrese yazar.  
2) Muteksler henüz library cache imleçleri için kullanılmaktadır( PL/SQL saklı yordamlar, tablo tanımlamaları gibi diğer objeler için uygun değildir henüz).
3) Muteksler sadece library cache’e mahsus değil, daha kapsamlı bir mekanizmadır. V$SQLSTATS gibi belli başlı yapılardada kullanılır.
4) Muteksler etkinleştirildiğinde, o andan itibaren X$KGLPN görünümünde,- ki bu görünümün KGL pin dizinine dayanan tablo olması sebebiyle bir daha imleç kullanılamayacağından-, imleç pinleri görülmeyecektir.

Bir proses oldukça fazla CPU tükettiğinde(ve az miktarda istemli IO uyuma yaptığında), işletim sistemi bu nedenle diğer proseslerin CPU zaman önceliğini düşürür, elbette düşük CPU ihtiyacındaki prosesler bu yeni CPU paylaşımdan adil bir pay alacaktır, hele hele IO beklemesinden geri geliyorlarsa…

Muteks tutan proses diğer proseslerden daha düşük önceliğe sahipse ve CPU’dan indiriliyorsa, “priority inversion - önceliğin tersine dönmesi” adı verilen olay meydana gelir. Diğer prosesler daha yüksek önceliğe sahip olsalar bile, bunların ihtiyaç duydukları kritik kilit veya kaynak, yüksek öncelikli proseslerin CPU’yu meşgul etmesi yüzünden çalışmasını tamamlayamayan daha düşük öncelikli diğer bir proses tarafından tutulmakta olduğundan, daha fazla ilerleyemezler.

Mandallar mevzu bahis olduğu durumda ise sorun o kadar önemli olmaz, çünkü mandal başka bir proses tarafından serbest bırakılması yayınlanana kadar mandal tutucular uykuya gider. Ancak muteksler mevzu bahis olduğunda Oracle 10.2'de “priority inversion” adlı olay, muteks tutucular uyumadığından(kısa bir an için bile olsa), CPU’yu açığa vurduğundan, ardından hemen geri dönmesinden ve bu döngünün bir muteks kapana devam etmesi sebebiyle çılgınca dönüş almaktadır. Haliylede yüksek oranda CPU tüketimi olur.

İşte bu sebeple Oracle 11g sürümünden itibaren muteks tutucular, sadece CPU’yu açığa vurmaktan ziyade uykuya geçerler. Oracle bu sorunun çözümünü proaktif olarak düzeltmek amacıyla 10.2.0.4 sürümünede bir yamayla eklemiştir ve Oracle 10g veritabanlarına bu yamanın yüklenmesi ve sentisaniye değerindeki uyku süresinin _first_spare_parameter parametresine eklenmesi gerekmektedir. Bu sayede muteks tutan hiçbir proses uzun süre boyunca geri itilmeyecek ve CPU’dan uzak tutulmayacaktır.

Muteks ve mandal beklemelerini ortaya çıkarmak ve diğer yüksek seviyedeki bekleme kategorileri ile kıyaslamak için aşağıdaki sorgu kullanılabilir.

SQL> WITH system_event AS
(SELECT CASE WHEN (event LIKE '%latch%' or event
LIKE '%mutex%' or event like 'cursor:%')
THEN event ELSE wait_class
END wait_type, e.*
FROM v$system_event e)
SELECT wait_type,SUM(total_waits) total_waits,
round(SUM(time_waited_micro)/1000000,2) time_waited_seconds,
ROUND( SUM(time_waited_micro) * 100 / SUM(SUM(time_waited_micro)) OVER (), 2) pct
FROM (SELECT wait_type, event, total_waits, time_waited_micro
FROM system_event e
UNION
SELECT 'CPU', stat_name, NULL, VALUE
FROM v$sys_time_model
WHERE stat_name IN ('background cpu time', 'DB CPU')) l
WHERE wait_type <> 'Idle'
GROUP BY wait_type
ORDER BY 4 DESC;

Kendi test ortamımda aldığım rapor sonucu aşağıdaki gibidir.

WAIT_TYPE                   TOTAL_WAITS TIME_WAITED_SECONDS   PCT
------------------------    ----------- -------------------   ------
CPU                         1,368.45                          68.59
latch: shared pool          1,109,834     426.20              19.13
latch free                     89,572     108.16               6.14
wait list latch free          336         58.91                2.52
User I/O                    9,471         29.08                2.12
latch: cache buffers chains 2,211         8.83                  .44
Other                          50         7.26                  .34
System I/O                  5,991         6.17                  .27
cursor: pin S                 261         3.16                  .16
Concurrency                    74         3.35                  .15
library cache: mutex X        271,287     2.74                  .14 

4 yorum:

  1. Çok fyadalı yazılar yazıyorsun ve türkçe olmasıda bu yazılara ayrı bir değer katıyor. Ancak terimleri türkçeleştirmek yerine direk kullanabilirmisiniz. Böylece konunun orjinalliğide bozulmamış olur.
    Çok Teşkkür ederim paylaşımlarınız için.

    YanıtlaSil
  2. Ünal hocam, güzel bir yazı olmuş, eline sağlık.

    Özcan, ben de bütün terimlerin Türkçeleştirilmesi taraftarı değilim ama Türkçeleştirmeyince insanlar neden böyle yarı Türkçe yarı İngilizce yazılar yazıyorsunuz diye tepki veriyorlar. Aşağı sakal sakal, yukarı tükürsen bıyık hesabı :)

    YanıtlaSil
  3. Kesinlikle Gökhan katılıyorum sana. Bu sefer ortaya yarım yamalak bir dil çıkıyor ayrıca ve baya tepki alıyor bu seferde...

    YanıtlaSil
  4. Ugur Hocam, degerleri bilgilerinizi bizlerle paylastiginiz icin cok tesekkur ederim. cok faydali bir makale olmus.

    YanıtlaSil