Aktív/aktív SQL cluster

(Ezt a cikket küldöm Tonesznak meg mindenkinek, aki szereti:)

Mint említettem, mostanság éppen próbálok egy aktív/aktív SQL clustert építeni, de mivel sokaknak ismeretlen a téma cégen belül is, kicsit úgy érzem magam, mint Gallilei: hol szép, hol kevésbé szép szóval próbálnak jobb belátásra bírni. Úgyhogy gondoltam, hogy ahelyett, hogy engedek, inkább leírom, hogy hogyan is működik a Microsoft eme remek találmánya.

Kezdjük az elején, a cluster fogalmánál. A Microsoft cluster egy failover cluster, azaz hibatűrésre van kitalálva. Nem várhatunk tőle nagyobb teljesítményt, párhuzamosítást, satöbbit. Egy adott feladatot (tipikusan valamilyen hálózati szolgáltatás nyújtása) egy adott pillanatban csak egy gép végez. Az SQL Server külön fel van okosítva arra, hogy ő hogyan is fusson egy clusteren, úgyhogy már egy “sima” aktív-passzív cluster is okozhat zavart arra fel nem készített fejekben. Ahhoz, hogy SQL clustert építsünk, először is kell telepítenünk két Windows 2003 Enterprise Editiont (a 2008-as clusteringhez még hülye vagyok egyelőre, elég sokat változott) két azonos hardverre (izé, működik különböző vasakkal is, csak problémáink lesznek a supporttal, meg esetleg a clusterrel is). Kell továbbá plusz egy IP cím és egy hozzá tartozó hálózati név, valamint egy megosztott diszk (a quorum, mely általában a Q: betűt szokja kapni), melyet mindkét gép (avagy node) lát lokális diszkként (SAN, DAS, vagy csak egyszerűen iSCSI). Nem kötelező, de ajánlott még egy heartbeat hálózati kapcsolat a gépek között, ez két node-os clustereknél gyakran egy keresztkábellel megoldható (ha a távolság elég kicsi a fizikai gépek között). Ha ezek mind megvannak, akkor az első node-on (CLNODE1) elindítjuk a cluadmin.exe nevű kütyüt, és építünk egy új clustert, megadva a cluster nevét (MYCLUSTER), IP-jét (172.18.1.104). Majd a második node-on is elindítjuk ezt, és hozzáadjuk őt az új clusterhez. Ezzel elértük az alsó, szürke keretben látható állapotot: van egy Microsoft failover clusterünk, mely ebben a pillanatban még semmilyen gyakorlati hasznot nem hajt. (Több, mint két node-os clustert is lehet építeni, a második node-on végrehajtott lépések ismételgetésével.) Amikor módosítunk a resource-okon vagy a node-okon, érdemes mindig kipróbálni, hogy mindegyik node át tudja-e venni azt, amit át kell tudnia venni, azaz működik-e a failover funkció.

Építsünk rá egy SQL clustert is. Ehhez hasonló dolgok kellenek, mint az előbb: diszk, IP cím + hálózati név. Plusz SQL telepítő. SQL 2005-től apró, de a pénztárnál jelentősnek tűnő öröm, hogy nemcsak az Enterprise Edition clusterezhető, hanem a Standard Edition is, igaz utóbbi csak két node-ra, de úgyis ez a leggyakoribb. A telepítés megkezdése előtt hozzunk létre egy új resource groupot a cluadminban, és tegyük bele az SQL-nek szánt diszkeket. Teszteljük le, hogy mindkét node tudja-e birtokolni a diszkeket (erről Andor tudna mesélni). Fontos tudni, hogy az SQL Server csak ezekre a diszkekre enged majd adatbázis fájlokat tenni. Continue reading ‘Aktív/aktív SQL cluster’ »

Mondatok, amiket nem akarsz mondani az interjún II.

A memória, a diszk és a tranzakció

Ez minden alkalommal tanulságos (és hosszú) beszélgetésekhez vezetett. Van egy nyitott tranzakcióm, ami már csinált egy csomó módosítást. Hol tartja a megváltozott, illetve a régi adatot az SQL szerver, iletve mi szerepel a tranzakciós naplóban? Bónusz: mi van a diszkre kiírva, és mi van csupán a memóriában? A kérdés megválaszolása némi adatbázis ismerettel és nagy adag józan paraszti ésszel (vagy ezek más jellegű lineáris kombinációjával) megválaszolható.
Induljunk az elejétől: hol lehet a megváltozott adat? Vagy a diszken vagy memóriában, vagy egyéb helyen. Nézzük a diszket: Vajon kiír-e az SQL minden egyes változást külön-külön diszkre? (Lehet-e okos az SQL szerver, és megvárhatja-e a módosítások végét? Nyilvánvalóan nem, hiszen ha olyanom van, öt napig futtatom a tranzakciómat.) Milyen érzést okozna ez abban, aki mondjuk másfélmillió rekordot módosít…? Mostanra eljutottunk oda, hogy nem ír ki diszkre mindent. Esetleg a memória? Hát, a temptáblákhoz hasonló ellenpélda itt is ül: végre lehet hajtani egy akkora tranzakciót, amelyik több adatot módosít, mint amennyit fejben (memóriában) tudna tartani az adatbáziskezelő. Marad az egyéb, és a kis adatbáziskezelői ismeret: a memóriában tartott módosult lapok esetében az SQL szervert olyan nagyon nem érdekli, hogy a módosító tranzakció kommitált lett-e vagy még fut. Ha a lap módosult (azaz dirty page lett belőle, nem egyezik meg a memóriában lévő másolat a diszken lévő másolattal), a checkpoint processz ki fogja írni a diszkre. Na ja, de mi van rollbacknél? Hát, egyrészt a tranzakciók elsöprő többsége committal zárul, tehát a hurráoptimizmusa az SQL szervernek elég indokolt a hatékonyság nézőpontjából. Amúgy pedig rollbacknél egyszerűen visszaírja a régi adatokat a lapokra, amik ettől megint dirty page-ek lesznek, és a következő checkpoint majd kiírja a diszkre megint.
Egy kérdést megválaszoltunk, itt az új: honnan írja vissza az eredeti adatot rollbacknél a szerver? Hát a tranzakciós naplóból! (Kis gondolkozással, illetve egy áramszünet utáni konzisztens adatbázis elképzelésével rájövünk, hogy a logot leginkább diszkre írja az SQL szerver.) És mi kerül a logba? Az, ami a rollbackhez illetve az esetleges újra-végrehajtáshoz kell (képzeljük el, hogy a tranzakció commitálódott, de a módosult rekordok még dirty page-en voltak, amikor a szomszédos építkezésen elkaparták a villamos kábelt a földben – ezt kiválóan fel tudja dolgozni az SQL Server – meg minden civilizált RDBMS). (És most nagyvonalúan ignorálom a bulk műveletek naplózásának kérdését.) Tehát kell minden módosult rekordnak az azonosítója (a primary key megteszi, ha van) és a változott oszlopok régi és új értékei. Azaz a naplóba nem maguk az utasítások kerülnek rögzítésre, hanem a hatásuk.
Mostanra már azt is tudjuk, hogy mikor mi van a diszken és a memóriában. Memóriában az az adat van, amit legutóbb használt az SQL, a diszken meg a többi. Nem volt ebben semmi különös, próbáltam kicsit illusztrálni, hogy hogyan lehet mély ismeretek nélkül mély ismereteket szerezni :) – vagy legalábbis megfejteni működési elveket: állítsunk fel modelleket, és teszteljük őket általános és szélsőséges esetekre.

Mondatok, amiket nem akarsz mondani a DBA interjúdon

Pár hónapja fejeztük be új DBA-nk beszerzését (welcome Andor), és az interjúk embert próbáló órái alatt napokat öregedtünk, és sok tévhittel találkoztunk. Nekem kicsit érdekes élmény volt, hogy emberek egymástól függetlenül ugyanazt gondolják rosszul. (Az is érdekes, sőt megdöbbentő élmény volt, hogy sokan dolgoznak informatikusként, tekiként úgy, hogy nem tudják, hogyan is működik a TCP/IP protokoll – subnet, gateway, router, stb.). Arra gondoltam végül, hogy megosztom élményeimet a nagyérdeművel. Hát tessék:

I. A temptáblák

Sokan gondolják, hogy a temptáblák a memóriában laknak. Ez nem igaz (sőt, a tábla típusú változókra sem igaz). Egyszerű kísérlettel igazolható: készíts egy akkora temptáblát, mint az SQL szervernek adott összes memória. Ez sikerülni fog, és az SQL szerver – lehet, hogy kicsit lassan, de – működni fog, amit memória nélkül pedig nem tudna megtenni. Még egy gondolat a temptáblákról: kétféle van belőlük: lokális és globális. A lokális így készül:

create table #a (int a)

Ezt az adott processz látja csak, senki másnak nem lesz hozzáférése, és akkor szűnik meg, amikor a készítő processz kilép. Ezzel szemben a globális temptáblaát minden processz eléri. Az állítás bizonyítása megint egyszerű: Az előző sorhoz csapjunk hozzá még egyet:

create table ##a (int a)

Majd nyissunk egy másik query window-t (aminek más lesz a spidje), és futtassuk le az alábbit:

select a from #a
select a from ##a

A különbség érezhető lesz: az első elbukik, a második nem. A globális tábla élettartama a lokálishoz hasonlóan nem nyúlhat túl az őt létrehozó session életén, legkésőbb a kapcsolat megszakításakor törlődik.

Sorting vs collation

Alaphelyzet a következő: van egy adatbázisunk, szép nagy táblákkal, Latin1_General_CI_AS collationnel, és egy napon a fejlesztő, aki megörökölte a rendszert, rájön, hogy az tulajdonképpen baj, hogy az SQL a számok elé sorolja az aláhúzást, azaz az AA01 előtt van az AA_ss01.
Megkérdezett az ember tehát, hogy át lehet-e alakítani ezt mezőt, mert ő a unicode rendezési elvét szokta meg, és abban gondolkodik. Mondtam, hogy meg lehet változtatni a mezőt nvarcharra, ami hirtelen megeszik egy csomó helyet, mert az UCS2-LE (amit az MS használ) mindig két byte. Meg lehet változtatni annak az egy oszlopnak a collationjét valami másra, ami esetleg úgy rendez, ahogy szeretné, de akkor egész érdekes módokon fog kiszúrni saját magával, ha véletlen pl. tempdb-t akar használni. Continue reading ‘Sorting vs collation’ »

GetMsSqlDump!!!

Végre, körülbelül másfél hét után, elkészült életem (majdnem) főműve, egy kütyü, mellyel SQL-ből ki lehet nyerni a táblák tartalmát insert into utasítások képében. Tipikusan a “nem nagy dolog, de jólesik” kategória, ugyanis nem MSSQL-en felnőtt ismerőseimnek az az első kérdése, hogy hogyan lehet ilyen módon kinyerni az adatokat MSSQL-ből, és már nagyon untam, hogy mindig azt kellett mondanom, hogy “ööööö… sehogy”.
Másrészt a Powershell mindig is foglalkoztatott, és például erre a célra tökéletesen alkalmas eszköz volt, úgyhogy PS-ben írtam, röpke 300 sor, kommentekkel, de hibakezelés nélkül. Mindenesetre működik, úgyhogy 0.1-es verzióval, béta állapotban elérhetővé tettem az emberiség számára egyrészt itt a saját oldalamon, másrészt pedig a CodePlexen.
Egyelőre néhány sebből vérzik, de ezeket szeretném befoltozni, meg majd egy C#-os command-line exét is akarok csinálni belőle. Meg portolni Linuxra :)
A cucc teljesen angolul van, de a doksit majd lefordítom magyarra, lássátok a részrehajlást :)