Shery és RePa

2008. szeptember 24.

PostgreSQL adatbázis replikálás

dyuri @ 19:58:53

A nemrég látott előadás kapcsán felmerült bennem, hogy ki kéne próbálni, hogyan lehet adatbázist replikálni. Mert olyat még nem csináltam, legalábbis eddig.

Mire is lehet ez jó? Először is biztonságos, ha kiesik egy gép, akkor sincs nagy katasztrófa, mert van másik, ami ráadásul eléggé up-to-date. Ami viszont szintén nem elhanyagolható dolog, az a terheléselosztás, azaz van pl. egy master replikánk, amibe mennek a módosítások (INSERT, DELETE, UPDATE), és van több slave egységünk, amiket lehet kérdezgetni (SELECT). Egy tipikus alkalmazás esetében a kérdezgetések száma nagyságrendekkel nagyobb ugyebár.

Na lássuk, hogy megy a dolog, ha postgresql szervert szeretnénk használni:

A próbát Solaris 10 alatt csináltam, egy gépen felhúztam gyorsan két zónát (pgmaster és pgslave), amiknek a /opt könyvtáruk is közös volt a global zónáéval, így a dolgokat csak egyszer kellett lefordítanom, és megvoltak egyből mindenhol. PostgreSQL-ből letöltöttem a legújabbat, biztos ami biztos, gond nélkül fordult. Többféle replikációs szoftver is van postgreshez, nekem a Slony-I volt a legszimpatikusabb, ezért azt töltöttem és fordítottam le. (A Solarishoz adott bison valamiért segfaultolt, de a sunfreeware-ről töltöttel simán fordult ez is.)

A postgresql konfigurációjánál annyira kell odafigyelni, hogy mindkét gép elérje a másikon futó adatbázis szervert, ehhez annyi kell, hogy a pg_hba.conf aljára beszúrjuk mindkét gépet a megfelelő módon.

Csináljunk egy adatbázist, amit majd replikálunk. A könnyebbség kedvéért beállítottam néhány környezeti változót:

export CLUSTERNAME=proba
export MASTERDBNAME=cica
export SLAVEDBNAME=cica
export MASTERHOST=192.168.7.64
export SLAVEHOST=192.168.7.65
export PGUSER=cica
export REPLICATIONUSER=postgres
export REPLICATIONPASS=jelszo

A replikálást végző felhasználónak mindenféle jog kell postgres oldalon, ezért én az alap postgres usert használtam, de élesben persze van értelme új felhasználót létrehozni.
Az adatbázist és a táblákat is meg kell csinálni mindkét oldalon, mert az adatbázis sémát nem viszi át a slony, csak az adatokat. (Tehát akinél percenként fut az ALTER TABLE, annak ez nem jó megoldás, de ő egyébként is gondolkozzon el a programozási technikáján :) )

$ createuser -A -D $PGUSER
$ createdb -O $PGUSER adatbázis
$ createlang plpgsql cica
$ psql
postgres=# create table probatabla (id serial primary key, szoveg varchar(200));
CREATE TABLE

Egy rövidke scripttel a master oldalon felkonfiguráljuk a slony-t, hogy tudja, mit kell neki replikálni:

#!/bin/sh

slonik < <_EOF_
# sema nev
cluster name = $CLUSTERNAME;

# admin kapcsolatadatok a szerverekhez
node 1 admin conninfo = 'dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER password=$REPLICATIONPASS';
node 2 admin conninfo = 'dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER password=$REPLICATIONPASS';

# az 1-es csomopont inicializalasa, ez a parancs letrehozza a _ semat, es benne a replikalashoz szukseges dolgokat
init cluster ( id=1, comment = 'Master Node');

# halmazokba (set) kell rendezni a tablainkat, amiket replikalni akarunk
# egy adott slave egy halmazra tud "feliratkozni"
create set (id=1, origin=1, comment='proba tabla egyedul');
set add table (set id=1, origin=1, id=1, fully qualified name = 'public.probatabla', comment='proba tabla');

# masodik node elkeszitese, kapcsolodasi informaciok
store node (id=2, comment = 'Slave node');
store path (server = 1, client = 2, conninfo='dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER password=$REPLICATIONPASS');
store path (server = 2, client = 1, conninfo='dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER password=$REPLICATIONPASS');
_EOF_

Ezután a mindkét oldalon indulhat is a slon. (Ez persze jó, ha a gép újraindításakor a postgres elindulása után maga is elindul.)

pgmaster# slon $CLUSTERNAME "dbname=$MASTERDBNAME user=$REPLICATIONUSER host=$MASTERHOST password=$REPLICATIONPASS"
pgslave# slon $CLUSTERNAME "dbname=$SLAVEDBNAME user=$REPLICATIONUSER host=$SLAVEHOST password=$REPLICATIONPASS"

Annyit kell már csak tennünk, hogy a slave-vel feliratkozunk arra a set-re, amit replikálni szeretnénk:

#!/bin/sh
slonik < <_EOF_
# sema nev
cluster name = $CLUSTERNAME;

# admin kapcsolat leirok
node 1 admin conninfo = 'dbname=$MASTERDBNAME host=$MASTERHOST user=$REPLICATIONUSER password=$REPLICATIONPASS';
node 2 admin conninfo = 'dbname=$SLAVEDBNAME host=$SLAVEHOST user=$REPLICATIONUSER password=$REPLICATIONPASS';

# a 2-es node feliratkozik az 1-es node 1-es set-jere, amit nem tovabbit
subscribe set ( id = 1, provider = 1, receiver = 2, forward = no);
_EOF_

Igazából ennyi. Ezt meg lehet csinalni jó sok géppel, akár több szinten is. Nézzük, hogy sikerült-e a művelet:

Master oldalon beleteszünk valamit a táblánkba:

cica=# insert into probatabla (szoveg) values ('ez itt a szoveg');
INSERT 0 1

És nézzük meg az eredményt a slave oldalon:

cica=# select * from probatabla;
 id |    szoveg
----+--------------
  1 | szoveg
(1 row)

Ottvan. Örül!

A Django 1.1 tervei között szerepel az ilyen master-slave (illetve más jellegű) adatbázis replikák támogatása, sok jó ötlet szóba került, majd meglátjuk mi lesz belőle, a djangós srácokban eddig nem csalódtam (pedig nincs is komoly szakálluk! :) ). Hajrá!

Címkék: , és

Comments are closed.

Ez egy blog. A velemenyunk a mienk, ezert szubjektiv, es meglehet, hogy neha csak picit fedi az egyetemes igazsagot. Mellesleg akinek nem tetszik, az nezze helyette a tvt.

Egyebkent nyugodtan lehet idezni, kepeket toltogetni, szabadok vagyunk.

Ha esetleg valami szemelyes kozolnivalod van, amit nem szeretnel kommentbe leirni, akkor tobbek kozott elerhetsz minket a [akiacikketirta] kukac horak pont hu emailcimen.