2008. április 19., szombat

Memória konfiguráció - Alapelvek

Az Oracle adatbázis alapvetően memóriában tárol minden információt. Azonban, ha nincs elegendő erőforrás, akkor az operációs rendszer kénytelen átmenetileg kitenni egy részét a merevlemezre, amíg ismét szükség lesz rá. Ez sajnos elkerülhetetlen elegendő memóriával nem rendelkező rendszerek esetében. (Ugye a memória olvasási és írási sebessége nagyságrendekkel gyorsabb, mint a lemezé.) Egy másik probléma pedig, hogy csak a működéshez elengedhetetlen információk vannak a memóriában, az adatok viszont a merevlemezen pihennek(a TimesTen az adatokat is a memóriában tárolja). Ezeket be kell olvasni, ha szükség van rájuk. A gyakran használt adatokat pedig valamilyen stratégia szerint minél tovább a memóriában kell marasztalni, hogy elkerüljük a felesleges I/O műveleteket.
A cél tehát kirajzolódni látszik. Csökkenteni a fizikai írás/olvasás műveleteket amennyire csak lehet akár cache-eléssel, vagy akár az adatblokkok behozásának hatékonyabbá tételével.

Az alapvető memória részek, melyek hatással vannak a teljesítményre:
  • Shared pool
  • Large pool
  • Java pool
  • Buffer cache
  • Streams pool size
  • Log buffer
  • Rendezéshez és hasheléshez szükséges memória(saját processz memória)

Automatikus memória kezelés

Alapesetben a telepített Oracle példányunk automatikusan kezeli a rendelkezésére álló memóriát. Ebbe csak nagyon kevés beleszólásunk van. Mindössze a felhasznált memória célméretét (MEMORY_TARGET) és maximumát (MEMORY_MAX_TARGET) szabhatjuk meg, minden más az adatbázis dolga. Elvégzi a területek kiosztását és méretezését az SGA-nak és PGA-nak. Törekszik a legoptimálisabb megoldásra.
Ha mégis úgy döntünk, hogy magunk szeretnénk kezelni a kiosztott memória területeket, akkor érdemes használni a beépített Memory Advisort.

Automatikus osztott memória kezelés
Ha a szerverpéldányunk SGA-ját szeretnénk egyszerűsítve kezelni, akkor ezt megtehetjük egyszerűen. Csupán az SGA_TARGET paramétert kell nullánál nagyobb értékre állítani (ezzel foglalhatjuk le az SGA-nak szükséges területet), utána pedig a STATISTICS_LEVEL-t TYPICAL vagy ALL módba kapcsolni. Ezekkel a beállításokkal az SGA automatikusan szétosztja a rendelkezésére álló memóriát az alábbi területek között: buffer cache, shared pool, large pool, java pool, streams pool. Ha az ezekhez tartozó memóriaterületeket nullánál nagyobb értékekre állítjuk, akkor ezzel a számukra szükséges minimum területet állítottuk be. Ezt figyelembe veszi az adatbáziskezelő a területek szétosztásánál.
Az SGA_TARGET változót dinamikusan is állíthatjuk, ezzel hozzá hangolva az éppen aktuális rendszerműködéshez. Ha az SGA_TARGET-et nullára állítjuk szerver induláskor, akkor a legutolsó beállítások fognak vonatkozni az SGA területeire(buffer cache, shared pool,...). Ezeket azonban személyesen is átállíthatjuk a megfelelő változókkal: DB_CACHE_SIZE, SHARED_POOL_SIZE, LARGE_POOL_SIZE, JAVA_POOL_SIZE, STREAMS_POOL_SIZE. Erről azonban majd később.
Vannak azonban olyan memóriaterületek is, melyekre az automatikus osztott memória kezelésnek nincsen hatása(log buffer, más cache-ek, belső SGA foglalások), azonban az SGA-ból területet vonnak el. Érdemes odafigyelni rájuk.

Memóriaterületek dinamikus változtatása
Ha magunk szeretnénk a memóriaterületeinket kezelni, akkor ezt megtehetjük, de ekkor körültekintően kell eljárnunk. A területek méretének beállítását az alábbi paraméterekkel tehetjük meg: DB_CACHE_ADVICE, JAVA_POOL_SIZE, LARGE_POOL_SIZE, LOG_BUFFER, SHARED_POOL_SIZE. Ezek közül a Log buffer beállítása indítás után nem változtatható meg, a többi viszont dinamikusan kezelhető. A memória foglalás alapegysége az SGA-nak 4MB, amíg 1GB alatt van, felette viszont 16MB. Ezt menet közben nem lehet megváltoztatni. (Egyébként a V$SGA_DYNAMIC_COMPONENTS nézet tartalmazza az aktuális alapegységet.)
Azzal, hogy beállítjuk induláskor az SGA maximális méretét (SGA_MAX_SIZE) korlátot szabunk a teljes memóriahasználatnak. Az ide tartozó komponenseknek nem adhatunk több operatív tárak, mint amennyit kezdetben allokáltunk. Ezért amikor kiszámoljuk, hogy mennyi hely fog kelleni a szerverünk működéséhez, mindig becsüljük kissé túl, hogy ha valamilyen váratlan okból meg kell növelnünk egyes komponensek rendelkezésére álló memória területet, akkor ne kelljen feltétlenül elvennünk valamely máséból, hogy beleférjünk a keretbe.
Segítség a dinamikus újraméretezéshez
Ahhoz, hogy olyan döntéseket hozzunk meg, melyek eredményeként át kelljen méretezni memória területeket, információra van szükségünk az adatbázisunk állapotáról, teljesítményéről, elvégzett műveleteiről. Ebben segítenek nekünk előre definiált nézetek, melyek az alábbiak:
  • V$MEMORY_CURRENT_RESIZE_OPS - A jelenleg is futó átméretezési műveletek listáját tartalmazó nézet.
  • V$MEMORY_DYNAMIC_COMPONENTS - Az összes dinamikusan állítható paraméter aktuális értéke, beleértve az SGA és PGA méretét is.
  • V$MEMORY_RESIZE_OPS - A legutóbbi 800 végrehajtott átméretezési művelet (csak a befejezettek).
  • V$MEMORY_TARGET_ADVICE - Hangolási tanácsokat tartalmaz a MEMORY_TARGET paraméter állítására.
  • V$SGA_CURRENT_RESIZE_OPS - Az éppen futó SGA átméretezési műveletek listáját jeleníti meg.
  • V$SGA_RESIZE_OPS - A legutóbbi 800 végrehajtott SGA átméretezési művelet (csak a befejezettek).
  • V$SGA_DYNAMIC_COMPONENTS - Az SGA dinamikus komponenseiről tárol információt. Tartalmazza az indítástól számított összes SGA átméretezési műveletet.
  • V$SGA_DYNAMIC_FREE_MEMORY - Az SGA számára fennálló szabad memória mennyiségét tárolja, ha a jövőben át szeretnénk méretezni.

Megfontolások alkalmazás oldalon
A memória konfigurációját természetesen az alkalmazáshoz kell igazítani, azonban ha a memóriahasználatot megfelelően hangoljuk, akkor nagyban csökkenthetjük az erőforrás szükségleteket. Ha hatékonyan használjuk az adatbázis erőforrásait, akkor jobb teljesítményt érhetünk el, mintha ezzel nem foglalkoznánk.
A legjobb teljesítmény elérése érdekében tehát az alkalmazás memóriahasználatát optimálisan kell kezelni, valamint az adatbázis memória struktúráját az alkalmazás igényeihez kell teljesen igazítani. Ha változtatunk az alkalmazáson, akkor újra kell gondolni az adatbázis memória használatát is.
Ha Java kódot használunk, akkor ezzel külön kell foglalkozni, mert az Oracle adatbáziskezelő külön erre a célra fenntart egy memória területet (Java pool).

Az operációs rendszer memóriahasználata
A legtöbb operációs rendszer használja a lapozási technikát. Vagyis ha nincs elegendő memória, akkor valamilyen stratégia szerint kiválaszt egy memóriaterületet és azt a merevlemezre mozgatja, hogy a helyére az éppen aktuálisan futó processz adatai kerüljenek. Ez teljesítmény csökkenést eredményez az operációs rendszer szintjén. Ebből a megközelítésből tehát a teljesítmény növelése csak a rendelkezésre álló memória növelésével érhető el. Vagy a felesleges processzek leállítása, így szabad memóriaterülethez juthatunk.
Az SGA szemszögéből nézve nagyban rontaná a hatékonyságot, ha egy szerverpéldány egy része nem férne el a memóriába (pl. sok más folyamat miatt) és így folyton használni kéne a lapozást. Ezért ajánlatos valamilyen módon az SGA-t mindig a memóriában tartani. Ennek egy módja, ha van elég hely ugyan a memóriában, hogy megparancsoljuk az operációs rendszernek, hogy nem nyúlhat az SGA-hoz. Ezt az adatbázis LOCK_SGA paraméterével állíthatjuk be. Azonban ha ezt beállítjuk, akkor nem használhatjuk a MEMORY_TARGET és MEMORY_MAX_TARGET paramétereket.
Ha megalkottuk a helyes SGA beállításokat az alkalmazásunkhoz, akkor sem szabad megfeledkeznünk a kapcsolódó felhasználókról, mert nekik is szükségük lesz szabad memóriára, hogy elvégezhessék a műveleteket.
Az SGA aktuális állapotáról a SHOW SGA PL/SQL parancs kiadásával tájékozódhatunk.

Forrás: Oracle Database Performance Tuning Guide 11g Release 1 (11.1) - 7 Memory Configuration and Use - 7.1 Understanding Memory Allocation Issues

1 megjegyzés:

Névtelen írta...
Ezt a megjegyzést eltávolította a blog adminisztrátora.