Siteye bir süredir elle tutulur bir şeyler yazamıyordum. İş yerinde zaten günler yorucu geçiyor ve üstüne teknik konularla uğraşmak istemedim açıkçası. :) Bir SQL Server'cı olarak bir süredir Oracle(Toad ile) kullanıyorum. Mimarisi hakkında bir yazı yazmak istedim. Uyguladıklarım ve öğrendiklerim ışığında hoş bir yazı olacak sanıyorum, çünkü gördüğüm kadarıyla netteki Türkçe yazılar genelde birbirlerinin aynısı ve anlamsız çevirilerden ibaret. Sıkmadan yazmak istiyorum her şeyden önce. :)
Oracle'ın aslında güçlü olmasını sağlayan en önemli konulardan birisi, belki de en önemlisi, memory management konusudur. Hafıza Yönetimi. Oracle'da iki temel hafıza bileşeni vardır:
- SGA(System Global Area)
- PGA(Program Global Area)
Anlatmaya SGA ile başlayalım isterseniz. Anlatımlardan sonra da kısa bir karşılaştırma yaparız.
SGA, alt alanlara bölünmüş bir yapıdır. Shared Pool(Library Cache-Data Dictionary Cache-Result Cache), Buffer Cache, Large Pool, Redo Log Buffer, Java Pool ve Stream Pool.
- Library Cache: Her PL/SQL ifadesi çalıştığında bir çalışma planı(execution plan) oluşur. Exec planın tutulduğu yerdir burası. Plan kısmını şöyle anlatayım: Burdan işe gitmem için 6 farklı yol(plan) var. Bu planlar içinde en az masraflısını çıkartır bize Optimizer(bunun ne olduğuna takılmayın, sonraski yazılarda yazarım bunu da). Dikkat edin, en hızlı plan demedim, en masrafsız plan dedim. İşe helikopterle gidersem en hızlısı olur şüphesiz ama çok çok masraflı olur. Bu yüzden eğer kullandıysanız daha önce, indeks yaratsanız da bazen yarattığınız indeks kullanılmayabiliniyor. Ayrıca bu exec plan aşaması, bir SQL ifadesi çalıştığında en çok masraf yapılan aşamadır.
- Data Dictionary Cache: Hak kontrolü, tablo kontrolü, istatistik kontrolü vs yapar. Hepsine bakar ve bilgileri cache'e atar.
- Result Cache: Sadece sonuç tutulur bu alanda. Lookup tabloları içindir daha ziyade. 11g ile geldi.
- Buffer Cache: Data file(veri dosyaları)'larından okunan data bloklarının kopyasını tutar. Yani bildiğiniz veri var bunda. :) İlk kez bir sql ifadesi çalıştığında, server process bir data bloğu ister ve bu bloğun buffer cache'de olup olmadığına bakar. Eğer varsa(cache hit), direkt olarak bellekten okur. Diske gitmez. Bellekten okumak mantıksal bir iştir; diske gitmek ise fiziksel bir iştir. Diske gitmek çok zaman kaybettirir. Eğer data bloğu buffer cache'te yoksa(cache miss), disteki data file'lardan data bloğunu alır, buffer cache'e koyar bir kopyasını.
- Large Pool: Opsiyonel bir alandır. Paralel işlerde, RMAN(Recovery Manager) işlerinde, Oracle Mimarisinde değişiklik yapıldığında vs. kullanılabilir.
- Redo Log Buffer: Veritabanına yapılan değişikliklerin bilgisini tutan buffer'dır. Bu bilgi Redo Entry'lerde tutulur. Veritabanının yeniden yapılandırılması, düzenlenmesi vs. gerektiğinde bu entry'lerdeki bilgi kullanılır. Redo entry'leri, server process'leri tarafından redo log buffer'a kopyalanır. Buffer'da sıralı bir şekilde tutulurlar. LGWR(log writer, I/O'dan sorumlu bir background process'i) de, redo log buffer'daki entry'leri, diskteki aktif redo log dosyasına yazar. Ne zaman yazacağı kısmı biraz farklı. Oracle'daki amcalar şöyle diyor: "Log Buffer'ın 3'te 1'i dolduğunda; LGWR'ye COMMIT veya ROLLBACK çakılırsa; DBWR, LGWR'ye yazmasını söylerse", LGWR de yazıyormuş. :) Makinenizdeki CPU sayısına bağlı olarak da, birden fazla redo log dosyanız olabilir.
- Java Pool: Bunu hiç kullanmadım. Java'ya özel durumlarda kullanıldığını duymuştum.(Java Virtual Machine'de veriler olduğunda, Java kodları olduğunda vs.)
- Stream Pool: Oracle streamleri tarafından kullanılır bu alan. Oracle'ın streamleri için bellekte yer açarlar. Replikasyon ürünüdür. Nerede lazım olur derseniz; işyerinizdeki sunucunuzun birebir kopyasını başka yere taşımak istediğinizde, Stream Pool ile işiniz var demektir. ;)
SGA'lar bitti arkadaşlar. Ufaktan PGA'lara dalalım artık. :)
PGA'da herkese özel bir bellek alanı verilir. Yani bir session kavramı söz konusu. Bunun yanında, Cursor bilgisi de mevcuttur. Örneğin siz bir silme(delete) işlemi yaptığınızda da cursor açılıyor. Ancak otomatik olarak açıldığı gibi, otomatik olarak da kapanıyor. Fakat siz kendi cursor'unuzu yazarsanız, kaydı bellekte tutulur. Ta ki siz onu kapatıncaya kadar. PGA'daki bir diğer kavram da SQL'lerin alanları. Bunlar: Sort alanı, Hash Join alanı, Bitmap Alanı. Sort'tan kastımız group by, order by gibi işlemler. Hash Join dediğim ise şu: 2 tane çok büyük tablonuz olduğunu düşünün. Bunları 50'şer 50'şer join etmenizdir. BitMap alanı ise, farklılığı az olan şeylerde kullanılan bir alandır. Bir select attığınızda kayıtların %50si gelebilmeli örneğin. Cinsiyet kavramı mesela BitMap'e çok uygun. 0,1 mantıksal işlemleri de aynı şekilde... PGA için toplam bellek alanı PGA_AGGREGATE_TARGET parametresi ile verilebilir.
Genel anlamda SGA ve PGA'ların ne oldukları konusunda artık fikriniz var tahmin ediyorum. Kıyaslama yapalım kısaca şimdi. OLETP çalışıyorsanız(örneğin bankacılık, para geldi-gitti vs. çok hareketli), memory'yi %80 SGA - %20 PGA olacak şekilde ayarlamalısınız. Datawarehouse çalışıyorsanız, PGA'ya yüklenmeniz gerekecektir. Keza bir raporlama yapıyorsanız bizim gibi, %50 SGA - %50 PGA uygun olabilir sisteminize. Yani işin özü; insert, update, delete önemliyse SGA çok önemlidir. Ancak select önemliyse, PGA baskındır.
10g'de SGA ve PGA için toplam bellek alanını veriyordun. Yani her ikisine de elinizle ayrı ayrı bellek alanı veriyorsunuz. Ancak kendi içlerinde Oracle onları otomatik olarak yönetiyordu.
11g'de ise, tek bir tane bellek alanı veriyorsunuz. SGA ve PGA'yı otomatik olarak arttırıp azaltabiliyorsunuz.
Bu yazı burada biter. Umarım açıklayıcı olmuştur. :) Sonra görüşürüz..
Hiç yorum yok:
Yorum Gönder