Adatbazis csokkentes

Udv!

Van egy nagy adatbazis (meretileg talan 500GB lehet, de ami fontosabb, hogy 396 model(django) van benne, ami 428 tablat hasznal), amit szeretnek rendszeresen klonozni. No de nincs szuksegem az osszes adatra, hanem csak egy kis reszere. Akar 20 adat minden tablabol eleg lenne.

A problemat az okozza, hogy rengeteg constraint talalhato benne, igy ha veszem minden tablabol az utolso 20 adatot, alig lesz valami, amit tenyleg importalni tudok, es nem hibas adat lesz. Nyilvan itt a sorrendet kellene felderiteni, de ez igen nagy munka lenne ennyi adatnal.

Valami olyan megoldast keresek vegso soron, amivel az adatbazist eles rendszerbol at tudom masolni teszt rendszerbe egy minimalis adatmennyiseggel. A rendszer maga django alapu, es az osszes tabla is django alapon lett letrehozva.

Amiket probaltam: valamilyen modon exportalni a szukseges adatokat (serializer, pickle, cPickle), fileba kiirni, beolvasni a tuloldalon, es importalni (deserializer, pickle, cPickle), de ezek mind hibasak lettek a contrainek miatt.

Barmilyen otlet erdekel :- ).

Koszi a valaszokat.

Hozzászólások

Ez pontosan milyen adatbázis? SQL alapú?

Szerintem klónozd le (de ne mysqldump-pal :)) és töröld belőle a felesleget.

Replikáció? Ott meg tudod mondani, melyik adatbázis melyik tábláit szeretnéd replikálni.

-----------
"Pontban 0:00-kor nem nagyon szoktak véletlen dolgok történni"

A jó teszt környezet pont olyan mint az éles. Ha az éles adatbázisban egy táblázatban van 30 ezer sor, akkor a 100 sort tartalmazó teszt adatbázis nem jó teszt.

A konkrét hibák úgyis (nagyrészt) a friss adatokkal lesznek kapcsolatosak, és azokat tesztelni csak a friss adatok birtokában lehet.

Alternatív megoldás: az éles szerveren üzemeltetsz egy teszt adatbázist is, amit az élesből copy-zol. A program tesztelés során pedig a teszt adatbázishoz csatlakozol.

A lenyeg ugye pont az lenne, hogy a friss adatokat tudjam egy masik adatbazisba atrakni, erre keresek megoldast. Nyilvan a kinyeresuk nem okoz problemat, a problema az adatok fuggosegeivel van (constrainek).

Az alternativ megoldasodnal mit ertesz azon, hogy az elesbol copyzom? Ha az egeszet atmasolom, ott vagyok, ahol a part szakad, ha pedig csak egy reszet... . Nos, pont erre keresek megoldast.

Azt értem alatta, hogy az éles szerveren levő éles adatbázist dump-olod, és visszaállítod az éles szerveren levő teszt adatbázisba. Mivel ez a szerveren belül történik, ezért megfelelően gyors. Még akkor is ha több gigás az adatbázis. (Mondjuk 1TB méret esetén már nem annyira gyors...)

A tesztelésnél úgyis az történik, hogy csatlakozol a teszt adatbázishoz, futtatsz egy lekérdezést ami visszaad max. 1000 sort. Ez megfelelően gyors lesz akkor is, ha a szerver távoli. (Kivéve ha rossz a query plan, de akkor meg a tesztelés célja pont a query plan qyorsítása lesz.) Ha ennél több sorra van szükséged, akkor az batch feldolgozás és ahhoz nem lesz szükséged friss adatokra (legalábbis a teszteléshez biztosan nem). Ha pedig nem batch feldolgozás hanem interaktív/oltp megoldásról van szó és mégis több 10 ezer sort kell lekérdezni, akkor az tervezési hiba.

Fel terrarol van szo, igy szerintem az sem lenne tul gyors :- ).

Amit nem irtam, es lehet kellett volna, a cel nem egy ilyen tesztadatbazis letrehozasa, hanem az, hogy periodikusan (legalabb hetente ketszer) csinaljunk egy minimalis adatbazist, amit a fejlesztok le tudnak tolteni. Szoval adott esetben kellene 50 peldany is, ami nem lenne tul jo. Nagyon sok migration van, es jo lenne, ha mindenki tudna a sajatjat hasznalni.

"A lenyeg ugye pont az lenne, hogy a friss adatokat tudjam egy masik adatbazisba atrakni" - egyébként ez elméleti lehetetlenség. Egy táblázatban levő friss adat hivatkozhat egy másik táblázatban levő nagyon régi adatra. Nagy általánosságban nem lehet tudni hogy melyik adat melyiktől függ, és ha egy függőségi fát akarsz felépíteni az exportáláshoz akkor az többe fog kerülni mint az egész adatbázist dump-olni.

Vannak olyan adatbázisok amelyekben előre lehet tudni hogy mely részét lehet exportálni a hivatkozási integritási megszorítások megsértése nélkül. De ezek jellemzően azok az adatbázisok amik direkt erre a célra lettek kitalálva. Egy általános django model-en alapuló adatbázis nem ilyen.

Amúgy vannak blob mezők? És napló táblák? Én ezt a kettőt vizsgálnám meg először. Ha kiveszed a napló táblázatokat és a blob mezőket, és még mindig 10GB nagyságrendű lesz az adatbázis?

Igen, nekem is ez a problemam, hogy minden hivatkozik mindenre, es felepiteni a fuggosegi fat, nem egyszeru. Legvegso esetben lehet tenyleg azt fogom csinalni, amit dotnetlinux javasolt, hogy hetente egy full dump, es torlok belole... . Bar meg a torles sem tunik nagyon trivialisnak.

Igazabol az a baj, hogy van 30- 40 tabla, aminek a sorszama 40 millio felett van (nem is picivel), es ezek altalaban hivatkoznak egymasra. Van nehany log tabla, es hasonlok, de ezek pont azok, amiknel a 64 napnal regebbi adatok mentodnek, es torlodnek, szoval ez pont jatszik. Blob? Hm, nem ismerem az osszes modelt, de eddig meg nem talalkoztam ilyesmivel.

Ami igazabol szoget ver a fejembe, az az, hogy nem hiszem, hogy en lennek az egyetlen, akinek olyan igenye van, hogy egy meglevo nagy production db- t lekicsinyitsen tesztelesi celra. Biztos sokan belefutottak mar ebbe a problemaba, es irtak ra valami okosat - meg ha nem is feltetlenul django alapon.

Subscribe, mert érdekes.

Egy esetleges megoldás, ami akár működhet is (kora délután nagyobb végiggondolás nélkül).

information_schema-ból/show create table-öknől kiturkálni a G=(Táblák, FK-k) gráfot, ebben keresni egy spanning forest-et, az erdő fáit tetszőleges sorrendben bejárva létrehozni a táblákat.
Második körben a gráfban meg kell keresni a legnagyobb sorméretű táblákat (ezek nagyobb valószínűséggel lesznek az entitások táblái, mint a kapcsoló táblák), ezekből iteratívan (mondjuk mindig kétszerezve a kiemelt mennyiséget) másolni sorokat, amíg el nem érsz egy treshold-ot. A másolásnál rekurzívan a kapcsolódó táblák adatait is át kell hozni (insert into ... select * from foo where exists ...), ügyelve a módosított sorok számára [pl. önmagára hivatkozásnál addig ismételgetni, amíg nem kapsz nullát]. Aztán ezt ismételgeted, amíg nem érted el a kívánt mennyiséget minden táblában.
Ha mindenhol meg van a kívánt mennyiségű sor és már nem hoz be új adatot egyik select se, akkor lehet az FK-kat feldobálni az új táblákra.

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

Azzal is, csak utólag kell rádobnod az FK-kat (annó szakdolgozathoz szórakoztam egy Entity-Relationship - Object - Relational mappinggel, ott mondjuk kihasználtam a PostgreSQL deferred foreign constraint-jét, pont ezért, de az is gyakorlatilag ugyanez, csak a tranzakció végén kell konzisztensnek lennie az adatbázisnak, de akkor muszáj)

BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)

"A problemat az okozza, hogy rengeteg constraint talalhato benne, igy ha veszem minden tablabol az utolso 20 adatot, alig lesz valami, amit tenyleg importalni tudok, es nem hibas adat lesz. "

Most neked vagy tényleg érdemi ADAT kell, és akkor kénytelen vagy bejárni az adatokat a kapcsolataik alapján, vagy kijelented, hogy jó kamu adat is (de ekkor a teszt legfeljebb csak kapargathatja a lényeget), és akkor tényleg kidobálhatsz importálható és szerkeszthető formába akármilyen rekordokat, azokban a kulcsmezőket azonosra hazudod a kedvenc szkriptnyelveddel, és importálsz.

Alternatíva, hogy kinyered a db-d ddl-jét, és kitörlöd belőle a constraintek definícióját (szívás, ha maga a constraint létrehozása jelenti teljesítményhez (is) kellő indexek megadását), és úgy importálod az akármilyen rekordokat.

Mindenesetre remélem, többé nem hiszel annak, aki azt mondta, hogy "áááhhh, a tesztadatokkal nem lesz dolgod".

Még egy gányolási lehetőség (voltam már kénytelen élni ezzel is), arra az esetre, ha jó sok időd van az import szkript(rendszer) futására:
- nem 20, hanem 1-2 nagyságrenddel több rekordot exportálsz ki a táblákból,
- fittyet hányva a szülő-gyerek kapcsolatokra ABC-sorban egy szkripbe írod az összes tábla import parancsát,
- ciklusban futtatod a szkriptet x-y-szor egymás után (közben elmész ebédelni),
- bízol abban, hogy nincs x-y-szorosnál mélyebb kapcsolatrendszer a db-ben.

Ezzel a saját tervezési munkádat a gép rabszolgamunkájává konvertálhatod, tudva, hogy a rabszolgamunka minősége nem feltétlenül éri el a kívántat.

Tehat azt mondod, hogy kiimportalok 1000 adatot minden tablabol, es az importalas ciklikusan futtatom? Van ra esely, hogy lesz talalat (bar ha egy tabla 10.000.000+ soros, akkor mar eleg pici), de ezzel az a gond - szerintem -, hogy marad rossz adat a db- ben. Tehat pl. beimportal egy usert, de nem lesz meg egy userhez kapcsolodo tabla. Legalabbis ha jol ertettem az otleted.

Igen, jól - erre céloztam a rossz minőséggel.

Sajnos ha nincs lehetőség vagy szándék a struktúra mintavett bejárására, akkor a komplett másoláson kívül minden lutri.
500G-nyi mysql-reláció viszont már nem az a kimondott idekopiodakopi volumen.

(Nem tudom, lejön-e a finom presszió: hosszabb távon azért kifizetődne az a fafeltárás.
((Feltárás, mert dok arról biztosan nincs, hisz a db mindig csak van, és a félreértett paradigma szerint pont azért választatott le a hőskorban a kódról, hogy eszetlenül lehessen bárki által beledobálni mindent, aminek nem találtak jobb helyet))
).

En eleget szivok a tesztekkel. Par hete 6 napot toltottem egy elkepeszto hulyeseggel, amirol vegul kiderult, hogy a hiba az 1.7- es django kodjaban keresendo, es termeszetesen nem mindenkinel jon elo, csak nalam... .

Elkezdtem most a teljes importot, es utana majd a torlest, de kozel 1 nap alatt a harmadaig jutott. Nem hinnem, hogy heti 3 napom lenne erre (meg ha csak gepido is) + meg a torles.

Kamu adat reszben jo, vannak olyan reszek, amik masik szolgaltatohoz csatlakoznak, es onnan kernek le adatokat. Ezeket nem lehet random adatokkal tesztelni.

Már felvetették, hogy importáld be az egészet, és törölj felesleges rekordokat.
MySQL-t nem ismerem.
A felesleg törléséhez Oracle alatt létezik a "FOREIGN KEYS WITH CASCADE DELETE" lehetőség.

nekem erre az jut eszembe, hogy felvenni a tesztadatbazist a DATABASES-be es irni egy admin taszkot, ami minden modellbol betolti az utolso n darabot az eles adatokbol es elmenti a tesztadatbazisba