2008. március 7., péntek

Architektúra part #7 – Memória architektúra

Az Oracle adatbázis memóriájában a következő komponenseket tároljuk:

  • programkód

  • információ a csatlakozott active és inactive sessionökről

  • programvégrehajtás közben szükséges információk, állapotok

  • az adatbázis processzei között megosztott információk (pl. zárak)

  • cachelt adatok, mint pl. adatblokkok és redo log bejegyzések, amik ugyanakkor természetesen tárolva vannak a merevlemezeken is


A memória struktúrája ábra alapvetően három része osztható:

  • szoftver kód területek: az éppen futó vagy futtatható kódokat tartalmazza. Általában a felhasználói programoktól eltérő helyen van.

  • System Global Area (SGA): az összes szerver- és háttérfolyamat (processz) között megosztott memória struktúrák (SGA komponensek – lásd fenti ábra) csoportja. Adat és vezérlési információkat tartalmaz.

  • Program Global Area (PGA): egy bizonyos szerver processzhez tartozó adat és vezérlési információkat tartalmazó memóriaterület, mely a szerverprocessz indításakor jön létre, s csak ő fér hozzá. Minden egyes szerverprocesszhez (és háttérfolyamathoz) tartozik egy-egy PGA. Az adatbázis inicializálási paramétereinél megadott PGA méret az összes PGA együttes méretére, s nem az egyes példányokra vonatkozik.



System Global Area (SGA):
Az adatbázis processzeinek halmaza az SGA-val együtt alkot egy adatbázis példányt (instance). Minden egyes adatbázis példány létrehozásakor az Oracle adatbázis automatikusan lefoglal memóriát az SGA számára, s visszaadja az operációs rendszernek a példány a leállításakor.
Az SGA egy írható és olvasható memóriaterület. Minden szerverprocessz és háttérfolyamat olvashatja, s néhány processz adatbázis műveletek során írhatja is.
Az SGA egy része a háttérfolyamatok számára tartalmaz általános információkat az adatbázis és a példány állapotáról. Ezt a területet hívjuk fixed SGA-nak. A változó rész elsősorban a processzek között kommunikált információt (pl. zárolási információk), illetve osztott szerver-architektúra esetén a kérés/válasz sorokat és a PGA tartalmának egy részét tárolja.

A legfontosabb SGA komponensek:

Database Buffer Cache: az adatfájlokból (datafiles) beolvasott adatblokkok (data blocks) másolatait tartalmazza. Minden felhasználó konkurensen hozzáfér.
A cache bufferjei két listát tartalmaznak:
1. A write list tartalmazza a piszkos (dirty) buffereket, melyekben a módosított, de a diszkre még nem kiírt adatok vannak.
2. Az LRU (Least Recently Used) list tartalmazza az üres buffereket, a pinned (éppen hozzáférés alatt álló) buffereket és az olyan piszkos buffereket, amelyeket még nem tettünk át a write listbe.
Egy bufferhez történő hozzáférést követően a buffert az LRU lista MRU végére mozgatjuk. Minél több buffert helyezünk folyamatosan az LRU lista MRU végére, annál gyorsabban öregednek a dirty bufferek, s kerülnek az LRU lista LRU végére.
Ha az adatbázisnak szüksége van egy konkrét adatra, akkor először a buffer cacheben kezdi el keresni. Ha megtalálja az adatot a cacheben (cache hit), akkor közvetlenül a memóriából be tudja olvasni. Ha nincs bent az adat a cacheben (cache miss), akkor először be kell olvasni a merevlemezről az adatblokkot a memóriába, s csak utána lehet hozzáférni. Ebből következik az LRU lista előnye, hogy a gyakran használt adatokat bent tartja a memóriában, s ezáltal hozzájuk sokkal gyorsabb hozzáférést biztosít.
Az adatblokk cachebe történő beolvasásához először keresni kell egy üres (free) buffert az LRU listában. A keresést a lista LRU végéről kezdi. Ha keresés közben piszkos buffert találunk, akkor azt a buffert áthelyezzük a write listába, majd folytatjuk a keresést. Ha találtunk egy üres (free) buffert, akkor beolvassuk oda az adatblokkot, s a buffert az LRU lista MRU végére mozgatjuk. Ha elértük a keresési limitet, s nem sikerült üres (free) buffert találni, akkor leállítjuk a keresést, és jelzünk a DBW0 háttérfolyamatnak, hogy írjon ki néhány piszkos buffert a merevlemezre.
Full table scan esetén – mivel a beolvasott adatok általában csak rövid ideig kellenek – az adatokkal feltöltött buffereket az LRU lista LRU végére tesszük (a hagyományos adatbeolvasásnál ugyebár a lista MRU végére pakoljuk a buffereket, hogy ne egyből őket dobjuk majd ki). Ha a buffereket mégis a lista MRU végére szeretnénk pakolni, akkor a CREATE/ALTER parancs CACHE klózával tudjuk ezt megadni.

Redo Log Buffer: itt tároljuk az adatbázison végrehajtott változtatásokat. Egy körkörös, fix méretű buffer, melynek merevlemezre írását az LGWR processz végzi. A Redo bejegyzések az adatbázis esetleges helyreállításához szükségesek. Mivel minden INSERT, UPDATE, DELETE, CREATE, ALTER és DROP művelet által végrehajtott módosítást tartalmaznak, így remélhetőleg könnyedén vissza tudunk állítani egy korábbi, konzisztens állapotot.

Shared Pool: a Shared Pool három cache területből áll:

1. Library Cache: tartalmazza a megosztott (shared) és privát (private – csak shared server konfiguráció esetén) SQL területeket (areas), PL/SQL eljárásokat és csomagokat, valamint vezérlési struktúrákat.
A shared(/private) SQL areak tartalmazzák a futtatott és éppen futás alatt álló SQL utasítások elemzési fáját és végrehajtási tervét. Az Oracle adatbázis automatikusan felismeri, hogyha két felhasználó ugyanazt az SQL utasítást futtatja, ezáltal sokfelhasználós rendszerek esetén, amikor egy utasítást gyakran és sokszor futtatnak le a felhasználók, jelentős memóriát takaríthatunk meg, mivel elegendő az utasítás elemzési fáját és végrehajtási tervét csak egy példányban tárolnunk, s ahhoz minden felhasználó egyaránt hozzáfér. A shared pool memóriájának menedzselésére szintén az LRU algoritmust használjuk (részletesebben lásd „Buffer Cache” vagy „Kapcsolódó Linkek”).
PL/SQL programok kezelése majdnem teljesen hasonlóan történik a sima SQL utasításokéhoz. A lefordított programnak ugyanúgy foglalunk helyet a shared SQL areaban, de a session specifikus változókat a private SQL areaban tároljuk.
Néhány, az alap LRU algoritmustól eltérő esetben is kiteszünk egy shared SQL areat a Shared Poolból. Ezek:

  • Az ANALYZE statisztikagyűjtő utasítás használata esetén minden olyan shared SQL areat kidobunk a shared poolból, ami tartalmaz hivatkozást az analizált séma objektumra.

  • Ha egy SQL utasítás által hivatkozott objektum az utasítás shared poolba kerülését követően módosul, akkor az utasítás shared SQL areajá invaliddá válik, s az utasítást újra le kell fordítani a következő futtatása előtt.

  • Ha az adatbázis globális nevét megváltoztatjuk, minden információt kiürít az adatbázis a shared poolból.

  • Az ALTER SYSTEM FLUSH SHARED_POOL utasítással az adminisztrátor manuálisan kiürítheti az egész shared poolt. Ezzel az adatbázis újraindítása nélkül tud a shared pool adatbázispéldány indítása utáni teljesítményéről információkat gyűjteni.


2. Dictionary Cache: az adatszótár (data dictionary) cacheelésére szolgál. Két részből áll: a data dictionary cache (másik nevén row cache) az adatokat sorok (rows) formájában, s nem blokkokban (bufferekben) tárolja. A másik rész, a library cache buffereket használ.

3. Result Cache: a SQL query result cacheből és a PL/SQL query cacheből áll, melyekben a lekérdezések/függvények eredményét cacheeljük. A DBMS_RESULT_CACHE csomag, illetve a V$RESULT_CACHE_* nézetek segíthetnek az adminisztrátornak a karbantartásában. A RESULT_CACHE_MODE-ban állíthatjuk be, hogy minden SQL lekérdezés eredményét szeretnénk-e cacheelni, vagy csak bizonyos megjelölt lekérdezéseket. Természetesen, ha egy tranzakció egy olyan objektum bármely adatát vagy metaadatát módosítja, amit a lekérdezés eredményének kiszámításához használtunk, akkor a cacheelt eredmény azonnal invaliddá válik.

Large Pool: az adatbázis adminisztrátor által konfigurálható opcionális memóriaterület, mely a következők számára biztosít extra, nagyméretű memóriát:

  • session memória az osztott szervernek és az Oracle XA interfésznek (több adatbázissal kommunikáló tranzakciók használják), hogy ne a shared SQL cachet pakolják tele

  • I/O szerver processzek

  • Oracle adatbázis biztonsági mentési és visszaállítási műveletei


Ellentétben a Shared Pool–lal, a Large Pool nem használ LRU listákat.

Java Pool: a session-specifikus Java kódok és adatok használják. A Java Pool Advisor segítségével statisztikát gyűjthetünk, amely segítségével információt kapunk arról, hogy hogyan változtassuk a Java Pool méretét a hatékonyabb működés érdekében. Az Advisor a statistics_level legalább TYPICAL–ra állításával van bekapcsolva.

Streams Pool: az Oracle Folyamok (Streams) használják. Mérete nulláról indul, és dinamikusan növekszik, amikor a Folyamoknak szüksége van memóriára.


Program Global Area (PGA):
Az Oracle adatbázis minden szerverfolyamat számára automatikusan lefoglal egy PGA-t. SQL utasítások végrehajtására, illetve session-specifikus (pl. bejelentkezési) információk tárolására használják. Két részből áll:

Session Memória: session specifikus információkat tárol. Shared szerver konfiguráció esetén megosztottan működik, amúgy privát.

Privát SQL terület (Private SQL Area): bind variable értékeket, lekérdezések végrehajtásának állapotinformációit és munkaterületeit tartalmazza. Minden sessionhöz tartozik egy külön privát SQL terület, így ha két felhasználó ugyanazt a lekérdezést futtatja, mindegyiknek külön privát SQL területük van, de egy osztott SQL területet használnak. A privát SQL területek elhelyezkedése kapcsolatfüggő. Ha dedikált szerveren keresztül csatlakozunk, akkor a szerverfolyamat PGA-jában kap helyet. Azonban ha osztott szerveren keresztül kapcsolódunk, akkor a privát SQL terület egy része az SGA-ban tárolódik.
Implicit kurzorok számára osztott SQL területeket használ az adatbázis, de az explicit kurzoroknak külön privát SQL területet foglal le. Az OPEN_CURSORS inicializálási paraméterben adhatjuk meg, hogy egy felhasználói processz maximum hány privát SQL területet foglalhat le magának. A paraméter alapértéke 50.
Memóriafoglalás alapján a különbségek dedikált és osztott szerver esetén: táblázat


Memóriakezelési eljárások (Memory Management Methods - táblázat): inicializálási paraméterben adható meg. Az Oracle az automatic management method-t ajánlja. Instance PGA = az adatbázispéldányhoz tartozó összes egyedi PGA-k halmaza.

  • Automatic Memory Management – SGA & Instance PGA: 11g újdonság. Csak a teljes memóriaterületet kell megadnunk, s onnantól az Oracle adatbázis mindent automatikusan elvégez. Dinamikusan elosztja a memóriát az SGA és az Instance PGA között, valamint külön-külön az egyes SGA komponensek és egyedi PGA-k méretét is meghatározza.

  • Automatic Shared Memory Management – SGA: az Automatic Memory Managementtel szemben ebben az üzemmódban meg tudjuk adni az SGA célzott és maximális méretét. Ebben az esetben a rendszer megpróbálja az SGA méretét a célméreten tartani, és dinamikusan állítja az egyes SGA komponensek méretét.

  • Manual Shared Memory Management - SGA: ebben az üzemmódban nem csak az SGA méretét állíthatjuk be, hanem szabályozhatjuk az egyes SGA komponensek rendelkezésére álló memóriát is.

  • Automatic PGA Memory Management – Instance PGA: Az Automatic Memory Management kikapcsolásával, s az Automatic Shared Memory Management vagy a Manual Shared Memory Management bekapcsolásával implicit bekapcsoljuk ezt az üzemmódot is. Beállíthatjuk az Instance PGA célzott méretét, és az egyedi PGA-k méretet a rendszer dinamikusan szabályozza majd. Ha nem adunk meg célzott méretet, akkor az adatbázis automatikus kiszámol és beállít egy értelmes alapértéket.

  • Manual PGA Memory Management – Instance PGA: az Oracle adatbázis korábbi verzióiban a DBA-nak manuálisan kellett definiálnia a maximális munkaterületet (work area) minden SQL operátor számára, ez azonban nagyon körülményes és nehéz feladat, hiszen a munkaterület mérete állandóan változik. Az Oracle erősen ajánlja, hogy ne használjuk ezt az üzemmódot!


Ha az adatbázist a Database Configuration Assistant (DBCA) segítségével hozzuk létre, akkor „basic” installálási opciót választva automatic memory management lesz beállítva. „Advanced” installálást választva az alábbi három konfiguráció közül választhatunk:
1. automatic memory management
2. automatic shared memory management + automatic PGA memory management
3. manual shared memory management + automatic PGA memory management
Ha kézzel, a CREATE DATABASE SQL paranccsal akarunk adatbázist létrehozni, akkor a 3. konfiguráció az alapértelmezett.


Szoftver kód területek (Software Code Areas):
Olyan memóriaterületek, amiket az Oracle adatbázis futó vagy futtatható kódjainak tárolására használunk. Általában statikus méretű, csak szoftverfrissítéskor vagy újratelepítéskor változik. Az igényelt terület mérete operációs rendszertől függ. Csak olvasható, megosztottan (shared) és nem megosztottan (nonshared) installálhatjuk. Ajánlott az előbbit használni, mivel így a felhasználóknak nem kell többszörös másolatokat a memóriában tartaniuk, ami amúgy az általános teljesítményt rontaná.


Kapcsolódó Link
Oracle® Database Concepts – Memory Architecture
http://en.wikipedia.org/wiki/Cache_algorithms

Nincsenek megjegyzések: