Az SQL Server több lehetőséget is biztosít számunkra, hogy magas rendelkezésre állású környezeteket alakíthassunk ki vele. Alapvetően négy út van, amin elindulhatunk:
- Failover clustering: ez a lehetőség egy kicsit kilóg a sorból, mert igazából nem (csak) SQL Server szolgáltatás: megosztott diszk(ek)en és azokat közösen használó cluster node-okon alapuló megoldás. Ezeket az erőforrásokat a Microsoft Cluster Service (MSCS) segítségével egyetlen virtuális erőforrássá gyúrhatjuk egybe a külvilág számára - ez a virtuális erőforrás saját azonosítóval (IP címmel, hosztnévvel, stb) rendelkezik, klienseink ehhez kapcsolódnak, és nem is tudják, hogy a clusteren belül melyik gép szolgálja ki őket.
Ez egyben azt is jelenti, hogy ez egy szerver-szintű megoldás, tehát nincs lehetőség arra, hogy egy SQL Server instance csak bizonyos adatbázisán használjuk, míg másokon ne.
Hátránya, hogy a közös disk single point of failure: ha az meghal, oda a cluster (tehát minimum érdemes valamilyen RAID megoldásban gondolkodni adattárolás szinten). Géphalál esetén, vagy ha az oprendszer megáll vagy megállítottuk (lásd: patchelés), a cluster többi gépe pillanatok alatt át tudja venni a kiszolgálást a működésképtelen node-tól, miközben a kliensek ebből jó esetben semmit nem vesznek észre.
- Database mirroring: ez esetben két adatbázisunk van, egy éles (principal), és annak egy készenléti tükre (mirror).
Látható, hogy ez egy database-level HA megoldás, tehát egy instance-on belül eldönthetjük, hogy mely adatbázisokat szeretnénk tükrözni, és melyeket nem.
A tükrözést kétféleképp is megvalósíthatjuk: szinkron (egy művelet akkor tekinthető végrehajtottnak, ha az élesről a tüköradatbázisba is átkerült az adat), illetve aszinkron módon (az tranzakciók az éles adatbázisban kommitálódnak, a tükör a háttérben szinkronizálódik). Az előbbi nagyobb adatbiztonságot, de rosszabb teljesítményt, míg az utóbbi az esetleges adatvesztés (a élesen már igen, de a tükrön még nem commitálódott tranzakciók) kockázata melletti jobb performanciát biztosít.
A mirror adatbázis a kliensek számára nem használhatók, de készíthetők róla snapshot-ok, amik az adatbázis adott időpillanatbeli, csak olvasható verziói - reporting feladatokra ideális lehet, ha nem szeretnék az éles szervert report-lekérdezésekkel terhelni, és nincs szükség abszolút real-time adatokra.
- Log shipping:
A log shipping némileg hasonlatos a mirroring-hoz, ahelyett vagy amellett is használható. A mirroringgal szemben egynél több másodlagos adatbázist is támogat.
Gyakorlatilag arról van szó, hogy az éles adatbázisról készítünk egy backup-ot, azt visszaállítjuk, mint másodlagos, majd (konfigurálható) időnként automatikusan log backup készül az élesről, ami a másodlagos adatbázis(ok)on visszaállításra kerül. Így lesz egy (konfigurálható) delay az éles és a tükrök között, ez néha nem jó, néha meg de: például ha egy kikommentezett WHERE feltétellel az összes munkavállalónk nevét Kovács Józsefnévá UPDATE-eljük, nem rossz, ha megvan az eredeti állapot.
- Replication: A replikáció szintén adatbázis-szintű megoldás, sőt: lehetőségünk van csak az adatbázis bizonyos részeit replikálni. A replikáció a publisher-subscriber modellre épül, az elsődleges adatbázisunk publikálja az adatokat (vagy azoknak egy részét), amire a másodlagos adatbázis(ok) "előfizetnek". A másodlagos adatbázisok használhatók lekérdezésre, vagy bármilyen reporting funkcióra. A replikáción belül három al-típus létezik:
- snapshot: minden egyes szinkronizációkor egy "fénykép" (snapshot) készül a publisher sémájáról és adatairól az adott időpillanatban és jut el a subscriberekhez. Ebben az esetben a másodlagos adatbázisok csak a szintkronizáció pillanatában lesznek up-to-datek (mint a megállt óra,ami napjában kétszer pontos). Akkor alkalmazható, ha ez megengedhető, vagy csak kis mennyiségű adatot mozgatunk. Hasznos lehet akkor is, hogy az éles adatbázisban rengeteg művelet történik, de minket igazából csak a végeredmény érdekel ("nap végi zárás" - mennyi lett a záróegyenleg?).
- transactional: itt az első lépés egy snapshot replikáció (ezzel áll elő a "tükör"), majd a publisher összes séma- és adatmódosítása real-time eljut a subscriberek felé is, így a tranzakcionalitás biztosított.
A subscriber adatbázis(ok) írhatók ugyan, de ezek a módosítások nem jutnak vissza a publisher felé, szóval gondoljuk át, hogy mit csinálunk.
- merge: itt is egy snapshot-tal indulunk, de mind a publisher, mint a subscriber(ek) módosításai követésre kerülnek, és alkalomadtán szinkronizálódnak (ez remek lehetőség konfliktusok kialakulására, amikor több subscriber próbálja ugyanazt az adatot módosítani).
- snapshot: minden egyes szinkronizációkor egy "fénykép" (snapshot) készül a publisher sémájáról és adatairól az adott időpillanatban és jut el a subscriberekhez. Ebben az esetben a másodlagos adatbázisok csak a szintkronizáció pillanatában lesznek up-to-datek (mint a megállt óra,ami napjában kétszer pontos). Akkor alkalmazható, ha ez megengedhető, vagy csak kis mennyiségű adatot mozgatunk. Hasznos lehet akkor is, hogy az éles adatbázisban rengeteg művelet történik, de minket igazából csak a végeredmény érdekel ("nap végi zárás" - mennyi lett a záróegyenleg?).
Bár ez egy relatíve hosszú post, mégis nagyon (nagyon-nagyon-nagyon) csak a felszínét kapargatja a magas rendelkezésre állás, megbízhatóság, skálázhatóság témakörének. Szerencsére elég sok szakirodalom található a témában (én most épp ezt gyúrom, ez ugyan nem csak HA témákat jár körül, de elég jó, küldeném mindenkinek aki szereti; de ezen felül sok más könyv, vagy akár a BOL is rengeteg információval szolgál).
Ennek ellenére szerettem volna összeszedni legalább nagy vonalakban a lehetőségeket, merthogy annyi van, hogy az ember könnyen eltévedhet, még mielőtt egyáltalán elindult volna - ami nem túl szerencsés.



