Párhuzamos batch futások DB oldali automatizált összehasonlítása
Az IT-vezetőség döntése alapján az IBM zServer mainframe gépeken z/OS és z/Linux operációs rendszer alatt futó összes alkalmazást és kiszolgáló rendszert át kellett telepíteni IBM pSerias RISC szerveren futó AIX operációs rendszert és Oracle adatbázis-kezelőt használó környezetbe.
Bevezetés
A feladat szükségessé tette regressziós tesztelés elvégzését. A regressziós tesztelés a batch folyamatoknak a régi és az új környezetben történő párhuzamos futtatásából és az eredmény összehasonlításából áll.
Az AIX-en futó adatbázis-kezelő megfelelő működését a nagy adatmennyiséget mozgató batch-folyamatok futásával teszteltük. A batch-környezet migrálása a batch-programok tényleges átírását követelte, ezért itt nem módszertani kérdés volt a batch-folyamatok párhuzamos futtatása, majd az eredmények összehasonlítása, hanem sokkal inkább funkcionális és regressziós tesztelés egyidejű elvégzését jelentette.
A fenti konkrét feladaton túlmenően, és ahhoz hasonlóan a jövőben többször is szükség lesz batch-folyamatok összehasonlító tesztelésére, azon belül a táblák összehasonlítására két különböző környezetben végrehajtott futtatás után. Ilyen szituációk lehetnek: archiválás, reorganizáció, Oracle-verzióváltás, a tranzakciós biztosítási rendszer verzióváltása, batch-folyamat lényeges (de a funkcionalitást nem érintő) átírása, batch-alkatrészek változása.
Párhuzamos batch vagy batch-sorozat futását akkor tekintjük ekvivalensnek, ha azonos bemenő adatokra (input) azonos (üzleti, esetleg funkcionális szempontból azonosnak tekinthető) kimenő adatokat (output) produkál. Kimenő adat lehet: file, adatbázistábla, adatbázistábla sora, e-mail, SMS, kinyomtatott papír.
Ebben a cikkben csak az adatbázistáblák adattartalmi azonosságát vagy különbözőségét megállapító, általunk kifejlesztett eszközről lesz szó.
Erre a feladatra kialakítottunk egy meglehetősen általános algoritmust és egy ezen alapuló automata eszközt, mely minimalizálja a manuális tesztelési tevékenységet, és az abból szükségképpen eredő hibákat.
Adatbázisok, tesztelési környezet
A párhuzamos batch-tesztek tesztelési környezetét a következőképpen alakítottuk ki. A batch-futásokat két adattartalmában azonos, de a tesztelendő új elem szempontjából eltérő, az éles rendszernek megfelelő környezeten hajtjuk végre.
A tesztkörnyezetet kiegészítettük egy adatbázissal, melyet a továbbiakban vezérlő adatbázisnak nevezünk. A vezérlő adatbázisból adatbázislinkeket kreáltunk a két tranzakciós rendszer minden adatbázisához. Az összehasonlításokat a vezérlő adatbázisból indítjuk, és ugyancsak ide gyűjtünk adatokat a tranzakciós adatbázisokról a batch-futtatások előtt és után. Ez az adatbázis őrzi a kódgenerálóval készített utasításokat és a teszteredményeket is.
A tranzakciós adatbázisok felületi hozzáférése le van állítva, hogy on-line adatmódosítás a batch-futtatások mellett ne történjen.
A táblaösszehasonlítás
Az adatbázistáblákat a párhuzamos futásokat követően összehasonlítjuk. Természetesen nem az összes táblát, hanem csak az adott futtatási szakaszban érintetteket. Érintettnek nevezzük azt a táblát, amit a batch-futtatás módosít, vagyis amelyre INSERT, UPDATE, DELETE, TRUNCATE, DROP, CREATE hajtódott végre. Azt, hogy a futások során mely táblákat kell összehasonlítani, az ORACLE audit bekapcsolásával nyerjük
Kétféle adatgyűjtést hajtunk végre. Az egyik az ún. üzemi adatgyűjtés, ami arra szolgál, hogy bizonyos táblák összehasonlítása ne a tábla összes sorára vonatkozzon, csak a sorok egy részhalmazára, egy ID-jellegű oszlop szerinti új sorokra. A másikat táblasorszám-gyűjtésnek nevezzük. Ez a releváns sémák tábláiban lévő sorok számának gyűjtését végzi.
Mindkét adatgyűjtés elmenti a gyűjtött adatokat a vezérlő adatbázis egy táblájába. Ezeket az adatokat is használjuk az összehasonlításkor. Egyrészt, ha a sorok száma nem azonos, akkor már biztosan hibát találtunk. Másrészt, ha a sorszámok megegyeznek, akkor nem szükséges szimmetrikus differenciát képezni, hanem elegendő az ellenőrző select utasításban a mínusz halmazműveletet csak az egyik irányba elvégezni.Formalizálva a legegyszerűbb összehasonlító select utasítás a következő. Legyen:
- DB1, DB2: a vezérlő adatbázis adatbázis linkjei a tranzakciós adatbázisok felé,
- TABL: az összehasonlítandó tábla neve,
- COLUMN_LIST: a TABL tábla összehasonlítandó oszlopainak listája
SELECT COLUMN_LIST
FROM TABL@DB1
MINUS
SELECT COLUMN_LIST
FROM TABL@DB2
Az összehasonlító select utasításokat kódgenerátorral állítjuk elő több okból. Egyrészt a select utasításban lehetnek a táblasorokra vonatkozó futásfüggő megszorítások a gyorsítás érdekében. Másrészt nem feltétlenül hasonlítjuk össze egy tábla összes oszlopát, az ellenőrzendő oszlopokra vonatkozóan változhatnak a szempontok menet közben. Harmadrészt a kódgenerálás csökkenti a manualitást, könnyebben áttekinthetővé teszi az egy-egy szakaszban összehasonlítandó táblák körét.
A kódgenerátorral előállított összehasonlító select utasításokat egy automata futtatja, és az eredményt a vezérlő adatbázis egy táblájába naplózza. Valójában a kódfuttató az összehasonlító select utasítás eredmény sorainak a számát számolja, tehát az alábbit futtatja:SELECT COUNT(*)
FROM (SELECT COLUMN_LIST
FROM TABL@DB1
MINUS
SELECT COLUMN_LIST
FROM TABL@DB2)
Előkészítés: Táblaellenőrzési paraméterek rögzítése
A kódgeneráláshoz szükséges adatokat a vezérlő adatbázis egy adminisztrációs táblájában tároljuk. Itt a tranzakciós adatbázis minden szóba jövő táblájának van egy sora. Egy-egy táblához a következő adatokat tároljuk, frissítjük a futtatási tapasztalatainknak megfelelően:
- Az összehasonlításból kimaradó, kihagyandó oszlopok listája, például nem hasonlítunk futás időpontját tároló, szekvenciából értéket kapó ID-jellegű adatokat, fájlnév jellegű adatokat. Az itt megadott adatok a COLUMN_LIST oszlop listát befolyásolják.
- Oszlophelyettesítések listája: ha egy összehasonlítandó oszlop helyett annak egy függvényét kell összehasonlítani. (pl. egy string oszlop helyett annak substringjét), a megadásnál speciális szintaxist használunk, melyet a kódgeneráló dolgoz fel.
- ID_NAME, MAX_ID_NAME: valamennyi sor összehasonlítása nagy rekordszám és sok oszlop esetén kerülendő. Ha csak újonnan keletkezett sorokat hasonlítunk össze, mert tudjuk, hogy egy táblában a batch-feldolgozás programjai nem törölnek sort és nem módosítanak meglévő sorokat, akkor batch-futás előtt és után mentjük a tábla megfelelő oszlopának (ID-jének) maximális értékét, és csak a batch-futás során keletkezett sorok összehasonlítására szorítkozunk.
- WHERE_CLAUSE: a sorok szűrésének további feltételét adjuk meg. Korrekt, SQL szintaxist követő feltételt kell megadni, az oszlopneveket prefixelt szintaxis szerint, melyet a kódgeneráló dolgoz fel.
- Összehasonlítás szükséges-e: flag mely jelzi, hogy egy tábla összehasonlítandó-e. Például kihagyhatunk az összehasonlításból ki nem ürített munkatáblákat.
- DARABOLO_OSZLOP: nagyméretű táblák esetében az összehasonlítás sokáig tart és óriás méretű TEMP táblaterületet igényel. Gyakran elfogyott a táblaterület. Ennek elkerülésére ezeket a táblákat a tábla egy ID-jellegű oszlopa szerint ID-tartományokra darabolva hasonlítjuk össze, vagyis az összehasonlító select utasítás where feltételéhez hozzátesszük az ID-tartományba esés feltételét. Ebben az oszlopban kell megadni a daraboló ID-oszlop nevét. Előnye még a darabolásnak, hogy hibakereséskor elég egy tábladarabban keresni, nem kell ismét az egész táblát végigolvasni.
- Darabolás szakasz hossza: Ebben az oszlopban kell megadni a darabolási tartomány méretét.
Ha az ID_NAME, MAX_ID_NAME, WHERE_CLAUSE adatok meg vannak adva, akkor a formalizált összehasonlító utasítás az alábbi:
SELECT COUNT(*)
FROM (SELECT COLUMN_LIST
FROM TABL@DB1
WHERE WHERE_CLAUSE
AND MAX_ID_NAME értéke batch futás előtt < ID_NAME
AND ID_NAME <= MAX_ID_NAME értéke batch futás után
MINUS
SELECT COLUMN_LIST
FROM TABL@DB2
WHERE WHERE_CLAUSE
AND MAX_ID_NAME értéke batch futás előtt < ID_NAME
AND ID_NAME <= MAX_ID_NAME értéke batch futás után)
Párhuzamos batch-futási eredmények összehasonlítása, az összehasonlítás lépései
Auditálás beállítása
A tranzakciós adatbázis releváns sémáinak tábláira auditálást kell beállítani. A teszt elindítása előtt célszerű a régi audit rekordokat törölni a SYS.AUD$ táblából.
Összehasonlítandó táblák kijelölése
Az adott batch-futásokat követően az audit rekordok alapján összeállítjuk az összehasonlítandó táblák listáját. Ehhez a következő utasítást használjuk:SELECT DISTINCT OBJ$NAME
FROM SYS.AUD$
WHERE ACTION# IN (1, 2, 6, 7, 12, 85)
Az összehasonlítandó táblák nevét, a futás nevet, a szakasz nevet és az összehasonlításhoz szükséges táblaspecifikus adatokat a vezérlő adatbázis egy másik táblájába beírjuk. Ide kerülnek majd az automata összehasonlítás eredményei, és szükség esetén a kézi tesztelés feljegyzései is.
Adatgyűjtés
A batch-programok futása előtt és után végrehajtjuk az üzemi adatgyűjtést és a táblasorszámgyűjtést. A táblasorszámgyűjtés időigényes, a rendszerünkben mintegy 4800 tábla van, ezért több szálon párhuzamosan futtatjuk.
Táblanevek szinkronizálása
Az „Előkészítés: Táblaellenőrzési paraméterek rögzítése” című fejezetben írtuk, hogy a tranzakciós adatbázis tábláira vonatkozó, és az összehasonlításhoz szükséges információkat a vezérlő adatbázis egy táblájában tároljuk és folyamatosan módosítjuk.
Egymást követő batch-sorozatok futásához a tranzakciós adatbázis más és más állapotát töltjük a tesztadatbázisokba. Előfordulhat, hogy a tesztadatbázisban olyan tábla szerepel, amely egyetlen korábbi tesztadatbázisunkban sem szerepelt még, sőt a tesztelés során végrehajtott batch-eljárások is kreálhatnak új táblákat.
A vezérlő adatbázisban lévő táblalistánkat batch-futtatás előtt és után frissítjük, azaz hozzávesszük a tesztadatbázisok új tábláit.
Összehasonlító select utasítások generálása (kódgenerálás)
Az előző lépésben felvett összehasonlítandó táblákhoz programmal kreálunk összehasonlító select utasítást, és elmentjük a vezérlő adatbázisba. Az összehasonlító select utasítás egyrészt a már korábban felvett táblaspecifikus adatok alapján készül.
Particionált táblák esetében, valamint ha darabolás van specifikálva az adott táblára, a kódgeneráló program egyetlen formális összehasonlító select utasítást generál. Ebbe a kódfuttató program helyettesíti be az Online partíciók nevét (@PARTITION_NAME@), illetve a darabolásnak megfelelő határokat (@LOWERBOUND@ és @UPPERBOUND@), majd lefuttatja az így kapott összehasonlító utasítást.
Particionált tábla esetében szinonimát kell kreálnunk a vezérlő adatbázisban a két tranzakciós adatbázisokban lévő táblára. Ezeket TABL_SYN_DB1, TABL_SYN_DB2-vel jelölve, az összehasonlító utasítás így módosul:SELECT COLUMN_LIST
FROM TABL_SYN_DB1 PARTITION(@PARTITION_NAME@)
MINUS
SELECT COLUMN_LIST
FROM TABL_SYN_DB2 PARTITION(@PARTITION_NAME@)
A darabolós összehasonlító utasítás:
SELECT COLUMN_LIST
FROM TABL@DB1
WHERE DARABOLO_OSZLOP BETWEEN @LOWERBOUND@ AND @UPPERBOUND@
MINUS
SELECT COLUMN_LIST
FROM TABL@DB2
WHERE DARABOLO_OSZLOP BETWEEN @LOWERBOUND@ AND @UPPERBOUND@
Táblaösszehasonlítás automatizált végrehajtása, teszteredmények naplózása
A táblaösszehasonlításokat a kigenerált összehasonlító select utasítások lefuttatásával hajtjuk végre. A kódfuttató program az eredményeket a vezérlő adatbázisba naplózza, kvalifikálva az eredményeket (OK, NOT OK), regisztrálva az eltérések számát, a futás kezdetének és végének időpontját, a futási időt. A program log file-ba és a DBMS_OUTPUT-ra is ír, e-mailt és SMS-t küld az eljárás befejeztekor, illetve a táblák bizonyos százalékának megvizsgálásának befejezésekor.
Táblaösszehasonlítás manuális végrehajtása, teszteredmények naplózása
Azon táblák, melyeknél a különbséghalmaz rekordjainak a száma nem nulla, manuális vizsgálatot igényelnek. A manuális tesztelés eredményét is az automata összehasonlító által használt tábla erre a célra szolgáló oszlopaiba jegyezzük be.
Szerző: Angyal Tibor, Hoffer János
A szerző
-
Oracle szakértő.
1987-ben szerzett programtervező mate- matikus diplomát. Néhány évig programozóként dolgozott nagy- vállalatoknál. 1990 óta Oracle adatbázis-kezelővel foglalkozik, elsősorban adatbázis admini- sztrátorként, kisebb részben programozóként. 1994 és 2004 között nagy németországi projektekben vett részt, ebből két évig az IBM frankfurti központjában dolgozott. 2004 óta az Allianz Hungária Zrt-nél dolgozik Oracle szakértőként. Feladata az adatbázis adminisztráció és a teszt folyamatok szakmai támogatása.