Többszintű replikáció költöztetése

Pár hónapja találkoztam egy érdekes problémával: adott egy többszintű MSSQL tranzakcionális replikáció, azaz a subscriber továbbpublisholja az adatokat valahova, ahonnan ezt még tovább publikálják. Hogy mi ebben a ráció, azt nem akarom firtatni, a lényeg, hogy azért van benne, például nem látják egymást a gépek, és az eleje és a vége között van párezer mérföld távolság. Ebben a helyzetben a második publishert kellett kicserélni, mivel upgrade-elték az SQL-t 2005-re. A replikált adatmennyiség elég nagy volt, WAN-on napokig tartott egy újrainicializálás, úgyhogy valami frappáns megoldás után néztem… A végeredmény sokak szerint merész lett, de senki nem tudott belekötni, úgyhogy ezt javasoltam végső megoldásnak.
Az “adatforrás” szervert nevezzük A-nak, az ő subscriberét B-nek, aki publikálja az A-tól kapott adatokat C-nek, és ne is menjünk tovább, ennyi elég a történet szempontjából, hiszen B-t cseréljük ki BB-re. A legegyszerűbb felállásban új publikációkat kellett volna létrehozni BB-n, amire C-nek fel kell iratkozni, és a kezdeti incializálás duplán fáj: a hosszú snapshot applikáció mellett a már a C-n lévő adatokat onnan előbb el kell tüntetni: vagy delete, ami többgigás tábláknál elég csúnya hatással van az adatbázis használhatóságára, ráadásul továbbreplikálódik D-re, ahol ugyanezt a hatást váltja ki; vagy drop-create table, ami gyorsabb, de ehhez a C-n lévő publikációt el kell dobni és újra létrehozni majd, ami egy vertikálisan és horizontálisan is filterezett gigásznál szintén elég kalandos tud lenni.
A kettes számú megoldás, amit a BOL-ba belenézve kitalál az ember: adatbázis backup B-n, restore BB-n, a WITH KEEP_REPLICATION clause-zal. Ez kicsit egyszerűbbnek tűnik, de egyrészt mindenki szívesebben látott volna egy új, üres adatbázist, ami nem hordoz meglepetéseket magában, másrészt (és ez egy sokkal jobb indok volt) az ilyen módon előálló érdekes helyzet, miszerint az adatbázis publikál dolgokat, de az instance sosem hallott a subscriberekről, illetve a forrás A szerver sem hallott BB-ről. Ezt a BOL a következőképpen fogalmazza meg:

Replication supports restoring replicated databases to the same server and database from which the backup was created. If you restore a backup of a replicated database to another server or database, replication settings cannot be preserved. In this case, you must re-create all publications and subscriptions after backups are restored.

Azaz nem állíthatod vissza másik szerverre a replikáció megőrzésével az adatbázist. Ez is kiesett.
Végül legvadabb ötletem nyerte a tendert, mely a következő lépéseket foglalja magában:

  1. Iratkozzunk fel BB-ről A megfelelő publikációira, és hozzuk létre a B-n is létező publikációkat, azaz készítsük elő BB-t az éles üzemre.
  2. Állítsuk le a Log Reader Agentet A-n. Várjuk meg, amíg végimegy minden már kiolvasott módosítás B-re és onnan C-re.
  3. Irassuk le C-t B publikációiról, és irassuk fel BB ekvivalens publikációira, méghozzá NOSYNC módon, azaz NE INICIALIZÁLJUK A SUBSCRIPTIONT. Hiszen pont ugyanazokat az adatokat hozná át, mivel B és BB számára A nem változik (mert leállítottuk a Log Reader Agentet, és nincs, aki a forrásadatbázisban történő változásokat kiolvassa).
  4. Hozzuk létre a replikációhoz szükséges tárolt eljárásokat C-n. Most páran benéznek: tessék? hát azt megcsinálja az SQL… Persze, megcsinálja, amikor inicializáljuk a subscriptiont. Ha nem, akkor úgy gondolja, hogy biztos valami nagyon érdekeset tervezünk, és inkább nem szól bele. Ha mégis szeretnénk a tárolt eljárásainkat megkapni, akkor a publisher adatbázisban kell lefuttatni a frappáns sp_scriptpublicationcustomprocs nevű tárolt eljárást, mely egyetlen paraméterként a publication nevét várja, kimenete pedig sok sor, amelyeket le kell futtatni a subscriber adatbázisban, és így megkapjuk a szükséges tárolt eljárásokat.
  5. Ellenőrizzük, hogy működik-e a dolog: egy előre kiválasztott és leegyeztetett rekordot módosítsunk BB-n, és nézzük meg, hogy átment-e C-re a módosítás. Muszáj neki.
  6. Indítsuk el a Log Reader Agentet A-n, és ellenőrizzünk.
  7. Írjuk meg mindenkinek, hogy menniyre jók voltunk megint, és kb. 30 perc késleltetéssel megoldottuk a dolgot.

Nem azért, mert én találtam ki, de szerintem gyönyörű terv, abszolút kihasználja a replikáció működési mechanizmusát, és mégis egyszerű és átlátható (sőt, kipróbáltam, és működött is). Ezt mindenki elismerte. Kivéve a madzag végén lakókat, akik sok pénzt fizettek egy cégnek, hogy SQL-t szakértsen nekik, szerintem alaptalanul. A cég közölte minden részletezés és indoklás nélkül, hogy ez veszélyes, inkább a három nap kiesést javasolják. Nem kérdeztem vissza, mert ez a cég mondta azt korábban, hogy nem tudják, hogy mi fog történni az SQL 2000 szerverrel, ha egy Management Studiót telepítenek az alatta futó Windows 2003-ra, meg hogy ezt támogatja-e egyáltalán a Microsoft. Szóval nem éreztem úgy, hogy vannak szakmai indokaik, éppen ezért mélységesen csalódott voltam, hogy elrontották a gyönyörű játékomat, amit így élesben nem is láthattam működni, csak kicsit tesztben, de az meg nem az igazi. Ha esetleg valaki megvalósítaná ezt a tervet, vagy már megvalósította, mesélje el, hogy mennyire váltotta be a hozzá fűzött reményeimet. Köszönöm.

6 Comments

  1. Tonesz:

    Szia,

    a scriptek előállításakor nem kellett még hegeszteni a kész scriptekben? Saját tapasztalat alapján (igaz merge replikáció) az előállt scriptekben szoktak lenni furcsaságok.:)

    a leírás amúgy nagyon tetszett! Az első dolog ami eszembe jutott róla, hogy cool.:)

    Mennyi idő volt, míg eljutottál eddig a megoldásig?

    Üdv.
    Tonesz

  2. erik:

    Szia Tonesz!

    Ez a script csak legenerálja a tárolt eljárásokat, aztán kész is van. A replikáció kiscriptelése engem is többször meggyalázott, úgyhogy amikor lehet, elkerülöm…
    A megoldás kitalálása egyébként nettó 3 óra volt, a validálás 8 – az egész elkenve egy hétre.

    Erik

  3. Tonesz:

    Szia,

    az szép.:)

    Üdv.
    Tonesz

  4. erik:

    Na ja, azért azt tegyük hozzá, hogy előtte azért különböző apropókból eltöltöttem már alsó hangon 150 órát tranzakcionális replikációval, úgyhogy a lehetőségeket elég jól ismertem. Az üzemeltetés meg mindig határeset a művészet és a gányolás között :)

    Mindenesetre köszönöm.
    Erik

  5. zsorzs:

    Szia Erik!
    A “hogy mi fog történni az SQL 2000 szerverrel, ha egy Management Studiót telepítenek az alatta futó Windows 2003-ra, meg hogy ezt támogatja-e egyáltalán a Microsoft.” : ra reagálnék:
    Mi ilyet csináltunk és bizony van vele szívás: Ha az MSDTC (MS Distributed Transaction Cordinator ha jól emlékszem fejből) is áldozatul esik a telepítésnek, akkor az SQL2000-es szerveren és az összes linked szerverről be fognak bukni a tranzakciók! Mivel az újonnan feltelepített MS DTC, ami az VS hez járó MsSQL2005-é, sajnos csak a gazdájával áll szóba, a MSSQL2000-es pórnéppel nem. A régi szerencsére nem ilyen finnyás, tehát egy 2000-es MSDTC újratelepítéssel, és újra-configgal visszaállhat a régi rend, és az Studió-hoz járó MSSQL2005 is tud dolgozni.

  6. erik:

    Szia Zsorzs!

    Igaz, mindennel meg lehet szívni (egyszer egy cluster node-ot egy olyan hotfix nyírt ki, amit 200 másik gépre gond nélkül feltettünk, beleértve a tök ugyanolyan másik node-ot is). Azért a Management Studio mag asszem nem hoz sok változást a .NET fw-n kívül, és igazából az egészből az zavart, hogy lejött h fogalmuk sincs az egészről. El tudom fogadni, ha valaki azt mondja, h ő nem vállal fel egy 0.01%-os kockázatot, mert nem engedheti meg, vagy csak nem akar izgulni – üzemeltetek, állok én is eleget a szőnyeg szélén. De az, amikor valaki nem ért ahhoz, ami a munkája, és a fáradságot sem veszi, hogy utánanézzen, az nagyon felbosszant.
    Erik

Leave a comment