2007. december 3., hétfő

Architektúra part #3 – Tranzakciókezelés

A tranzakció legalább egy SQL utasítást magába foglaló műveletsorozatot jelent. Elemi műveletként értelmezzük, ami annyit tesz, hogy a tranzakciót alkotó SQL utasítások mindegyike végrehajtódik (commitálódik), vagy egyik sem (roll back – visszagörgetés). Egy tranzakció jóváhagyása vagy visszagörgetése explicit módon a COMMIT vagy ROLLBACK utasításokkal, implicit módon az alkalmazásból való kilépéssel vagy egy DDL utasítás végrehajtásával történhet.
Utasítás szintű visszagörgetésről akkor beszélünk, ha egy SQL utasítás valamilyen hiba folytán nem tud lefutni. Ilyen hiba lehet például, ha már létező elsődleges kulcsot akarunk létrehozni, ha két SQL utasítás között versenyhelyzet áll elő, vagy egyszerűen csak szintaktikailag nem helyes az utasítás. A hibás utasítás nem okozza az egész tranzakció visszagörgetését, pusztán csak a saját feladatát nem tudja végrehajtani.

Nagy adatbázis műveletek számára előnyös lehet, hogyha egy tranzakció helyfoglalási problémák következtében nem tud tovább futni, akkor nem visszagörgetés következik, hanem lehetősége van az adatbázis adminisztrátornak a hibát elhárítania, majd a tranzakciók zökkenőmentesen futhatnak tovább. (Resumable space allocation)

Egy tranzakció futásának kezdetén a visszagörgetéshez szükséges információk tárolására hozzárendelünk a tranzakcióhoz egy undo tablespacet. A tranzakció végén a következők állhatnak elő:
  • a felhasználó COMMIT vagy ROLLBACK utasítást ad ki.

  • a felhasználó valamilyen DDL utasítást (CREATE, DROP, RENAME vagy ALTER) ad ki. Ebben az esetben az adatbázis először commitálja a tranzakciót, majd csak azután hajtja végre a DDL utasítást, mint egy egy utasításból álló külön tranzakciót.

  • a felhasználó kapcsolatot bont az adatbázissal. Ekkor automatikusan commit hajtódik végre.

  • a felhasználói processz abnormálisan áll le. Ekkor automatikusan rollback hajtódik végre.


Commitálni egy tranzakciót annyit tesz, mint véglegesíteni az adatbázisban az SQL utasítások által végzett műveleteket. A commit előtt az adatbázis a következő műveleteket hajtja végre: undo információkat generál, melyek a az SQL utasítások által módosított adatok módosítás előtti változatát tárolják. Illetve az SGA redo log bufferjébe redo log bejegyzéseket tesz, melyek az adatblokkokon illetve roll back blokkokon történt változásokat rögzítik. Előrefordulhat, hogy ezek az adatok a tranzakció commitálását megelőzően már a lemezre kerülnek. A commit után a következők mennek végbe:
  1. az undo tablespacehez tartozó belső tranzakciós táblában feljegyezzük, hogy a tranzakciót commitálták, s beírjuk a tranzakció egyedi SCN (system change number) számát.

  2. az SGA redo log bufferjének redo log fájljába bejegyzéseket tesz az LGWR (log writer process), s szintén beírja a tranzakció SCN számát, ami egyben a tranzakció commitálását is jelenti.

  3. az adatbázis elengedi a tranzakció által használt zárakat.

  4. a tranzakciót késznek jelöli.


Egy tranzakció visszagörgetése (roll back) annyit jelent, hogy egy lezáratlan tranzakció minden addigi adatmódosítását visszaállítjuk az adatok eredeti értékére. A régi adatokat az undo tablespaceben, a változtatásokat a redo logban tároljuk. Lehetőség van savepointok definiálására, amikkel egy nagyobb tranzakciót kisebb részegységekre bonthatunk, így ha valahol hiba történik, akkor a visszagörgetés nem teljesen a tranzakció elejéig történik, hanem a legutolsó savepointig (már ha volt addig). A visszagörgetés a következő lépésekből áll:
  1. az adatbázis az undo tablespace alapján minden addigi, a tranzakció SQL utasításai által végrehajtott módosítást visszacsinál. Savepoint esetén természetesen csak az adott savepointig kell visszacsinálni mindent, vagyis csak a savepoint után szereplő SQL utasítások által módosított adatokat kell a régi értékükre visszaállítani.

  2. Ha volt savepointunk, akkor azt az adott savepointot természetesen megőrizzük, de minden utána megállapított savepointot törlünk.

  3. Elengedjük a tranzakció zárjait. Természetesen ha savepointot alkalmaztunk, akkor itt is csak a savepoint után igényelt zárakat engedjük el. Azok az adatok, melyek a savepoint előtt már zárolva voltak, természetesen továbbra is zárolva maradnak.


Kétfázisú commit működési elve:
Egy elosztott adatbázisban hálózati vagy rendszer hibák esetén is gondoskodni kell a hálózat feletti tranzakcióvezérlésről és az adatok konzisztenciájáról. Elosztott tranzakciónak nevezünk egy tranzakciót, ha tartalmaz legalább egy olyan utasítást, ami módosít legalább két különböző hálózati végpontokon lévő adatbázisokat. A kétfázisú elv biztosítja, hogy elosztott tranzakció minden adatbázisa konzisztens marad, vagyis az összes adatbázis vagy commitálja a tranzakciót, vagy visszagörgeti annak addigi hatásait.

Léteznek ún. autonóm tranzakciók, melyeket más tranzakciók hívnak meg, de azoktól teljesen függetlenül futnak le. A hívást követően a meghívó tranzakció felfüggesztődik, a meghívott tranzakció teljesen független zárakkal és utasításokkal lefut, majd függetlenül attól, hogy committáltunk vagy visszagörgettük a tranzakciót, folytatódik a meghívó tranzakció futása. Ezáltal természetesen létre lehet hozni holtpontot, amit az adatbázis hibaüzenettel ugyan jelez, de ezekért a holtpontokért teljes mértékben az alkalmazás fejlesztője felel. Egy autonóm tranzakció is meghívhat más autonóm tranzakciókat, nincs semmilyen korlát a hívások mélységére. Lehetőség van azonban nem autonóm tranzakciók meghívására is. Ekkor a meghívott tranzació örökli a hívó tranzakció környezetét.


Kapcsolódó link:
Oracle® Database Concepts: Transaction Management

Architektúra part #2 – Táblaterek és Adatfájlok

A logikai adattárolás legnagyobb egységei a tablespacek, míg a fizikai tárolás datafileok formájában történik. Az Oracle adatbázis tartalmaz legalább két tablespacet, a SYSTEM-t és a SYSAUX-t, illetőleg egy harmadik, TEMP nevű tablespacet opcionálisan. A tablespacek adatait fizikailag egy vagy több datafile tárolja. A fájlrendszer további részeit képezik még a visszagörgetéshez használt Redo log fájlok, illetve az adatbázis indításához és működéséhez elengedhetetlen Control fájlok. Az adatbázisunk méretét háromféleképpen növelhetjük:

  • új tablespacet hozunk létre

  • egy már létező tablespacehez új datafilet adunk hozzá

  • egy már létező datafile méretet növeljük (engedélyezhetjük, hogy az adatbázis ezt dinamikus hajtsa végre, amint szüksége van több területre)


A tablespacek, ahogyan azt már tárgyaltuk, szegmensekből épülnek fel, melyeket extentek alkotnak, amiket pedig összefüggő adatblokkok képeznek.

A 64-bites rendszerek képességeinek kiaknázása érdekében lehetőség van ún. „bigfile tablespace”-k létrehozására. Ez lényegében annyit jelent, hogy az adott tablespaceünket mindössze egyetlen datafile alkotja, így a szokványos „smallfile tablespace”-kkel szemben jóval nagyobb datafilet használthatunk – egészen pontosan mivel a smallfile tablespacek maximum 1024 datafilet tartalmazhatnak, ezért a bigfile tablespaceünk egyetlen datafileja akár 1024szer lehet nagyobb. A datafilek számára is van egy felső korlát (64K), ezért mivel a bigfile tablespacek tablespacenként csak egy datafilet tartalmaznak, lehetőségünk van hatalmas adatbázisok tárolására egészen 8 exabyte (10^18) méretig, illetve a kevesebb datafile miatt könnyebben kezelhető lesz az adatbázisunk. Cserébe viszont a bigfile tablespacek (néhány kivételtől eltekintve) csak lokálisan vezérelt (locally managed), automatikus szegmens-foglalási tablespaceként működhetnek.

A SYSTEM táblaspace automatikusan létrejön, amikor az adatbázist létrehozzuk. Alapvetően könyvtár vezérelt (dictionary managed), de természetesen ezt átállíthatjuk lokális vezérlésre is, azonban ezáltal a későbbiekben nem tudunk könyvtár vezérelt tablespaceket létrehozni, s a létezőket is csak olvasni tudjuk. A SYSTEM tablespaceben tároljuk a data dictionary táblákat, illetve a tárolt PL/SQL eljárásokat.
A SYSAUX tablespace a SYSTEM-t kiegészítő tablespace. Sok adatbázis komponens használja alapértelmezett tárolási helyként, illetve az összes, nem a SYSTEM tablespaceben lévő metaadatot itt tároljuk.
Az UNDO tablespacek csak és kizárólag undo infomárciókat tartalmaznak, s csak automatikus undo menedzselt módban (alapértelmezett) alkalmazhatóak. Lehet ugyan több ilyen tablespaceünk, azonban használatban egyszerre csak egy lehet. Az undo tablespacek automatikusan létrejönnek, mindig lokálisan vezéreltek, s néhány ritkán előforduló körülménytől eltekintve a tranzakciókat első DML eljáráshívásuk után hozzárendeljük egy undo szegmenshez.
Ha a SYSTEM tablespaceünket lokális vezérlésre állítottuk, mindenképpen definiálnunk az ideiglenes adatok tárolására egy ideiglenes tablespacet, de ajánlott könyvtár vezérelt módban sem a SYSTEM-be szemetelni. A könnyebb kezelhetőség és a versenyhelyzet elkerülése érdekében természetesen ajánlott a felhasználók adatainak számára is külön tablespace(ke)t létrehozni.

A tablespacek területének menedzselésére kétféle mód kínálkozik:

  1. A lokálisan vezérelt tablespacek egy bitmapben tartják számon a datafileban használt és szabad területeket. Előnyük, hogy ezáltal nem kell foglalkozni a szomszédos szabad területek összeolvasztásával, illetve nincs szükség rekurzív területvezérlési műveletekre (pl. ha felszabadítunk helyet egy extentben, akkor az nem idéz elő semmilyen más műveletet a data dictionaryben vagy rollback szegmensben). A SEGMENT SPACE MANAGENT paraméterrel beállíthatjuk, hogy AUTO (alapértelmezett) vagy MANUAL módban szeretnénk-e kezelni a szegmensen belüli területeket. Előbbi esetben az adatbázis a bitmap alapján automatikusan kezeli a szabad területeket, míg utóbbiban egy (az előző részben már említett) free list-ben tartjuk nyilván az olyan adatblokkokat, ahova van lehetőség új sor beillesztésére.

  2. A könyvtár vezérelt mód az Oracle 9i verziójától elérhető. Ebben az esetben bitmapek helyett az adatbázis a SYSTEM tablespacen belül kezel egy data dictionaryt, melyet minden extentfoglalás és –felszabadítás esetén frissít, s ezekről a frissítésekről a rollback szegmensekben tárol információt.


Lehetőség van a SYSTEM tablespace kivételével (mivel annak data dictionaryjére mindig szüksége van egy futó adatbázisnak) bármely tablespacet online módból offline módba átállítani. Erre karbantartáskor vagy biztonsági mentés létrehozásakor lehet szükség, de bizonyos hibák esetén az adatbázis automatikusan is offline módba állíthat egy tablespacet. Ilyenkor természetesen semmilyen olyan SQL utasítás nem hajtható végre, ami az adott tablespacen belüli objektumokra hivatkozik.

Biztonsági okokból adott tablespaceket lehet csak olvasásra (read-only) is engedélyezni.

A CREATE TEMPORARY TABLESPACE utasítással ideiglenes tárolási célokra használt tablespaceket hozhatunk létre. Ezek nagyban növelhetik a rendezést használó utasítások végrehajtásának hatékonyságát. Természetesen egy temporary tablespace nem használható állandó sémaobjektumok tárolására.

Lehetőség van tablespaceink adatbázisok közti szállítására is. Ehhez nyújt segítséget a tablespace repository, amelyben a tablespacek egy halmazának szállításához szükséges fájlokat tároljuk. Nem árt ügyelni arra, hogyha egy könyvtár vezérelt tablespacet költöztetünk át egy lokálisan vezérelt SYSTEM tablespaceszel rendelkező adatbázisba, akkor azt ott csak olvasni tudjuk majd, írni nem.

Egy tablespacet ugyebár fizikailag datafile(ok) alkotnak. Egy datafile csak egy tablespacehez és adatbázishoz tartozhat. Létrehozásakor az általa kijelölt terület formatálódik, s az adatbázis lefoglalja a későbbiekben szükséges extentek létrehozására. Az ideiglenes táblahelyek ideiglenes datafilejai kevesebb tulajdonsággal bírnak szokványos társaiknál: például nem logolnak és nem lehet őket read-only módra állítani.

Az adatbázis indításához és működéséhez az ún. control fileokat használja. Ezeknek mindig írásra alkalmasnak kell lenniük, hisz az adatbázis működés közben folyamatosan frissíti bennük a fizikai architektúra és a visszagörgetéshez szükséges redo logok leírását. Ebből kifolyólag ha a control fileok nem elérhetőek vagy sérülnek, az adatbázis nem fog helyesen működni, ezért erősen ajánlott több azonos control filet egyszerre, különböző fizikai lemezeken tárolni és frissíteni.


Kapcsolódó link:
Oracle® Database Concepts: Tablespaces, Datafiles, and Control Files