Zwei DBs synchron halten

Hallo,
ich möchte gerne zwei DBs(LiveDB, BackupDB) synchron halten.
D.h. wenn in der LiveDB eine Änderung erfolgt, soll diese
gleichzeitig in der BackupDB erfolgen.

das Betriebsystem ist Linux, die Datenbank Postgres 8.0
die Datenbanken befinden sich auf unterschiedliche Rechner.

Gibt es evtl. eine Funktion, die Postgres schon bereitstellt?
oder muß ich einen anderen Weg suchen. z.B. über Trigger/Funktion.

Hat jemand evtl. eine schöne Lösung :slight_smile:

Gruß
Martin

hi,

mir ist jetzt keine direkte lösung für dein problem bekannt - aber das muss ja nicht unbedingt was heißen :wink:

in der FAQ zur postgresql steht im punkt 4.20 etwas zum thema replizieren (http://www.postgresql.org/docs/faqs.FAQ.html#item4.20). allerdings kannst du damit nicht 100 %ig das realisieren was du möchtest…

cu tb.

Hi,

das was du suchst, sollte sich ohne viel Aufwand mit PGCluster realisieren lassen! Musst allerdings mal schauen, inwieweit Postgres 8 unterstützt wird.

http://pgcluster.projects.postgresql.org/

Hi

gibts ne möglichkeit PGCluster irgendwie zu meiner von Debian gelieferten version von postgre hinzuzufügen ?
Oder führt ums neukompilieren nichts herum ?

mfg
henrik

Soviel ich weiss, kommst du ums neu compilieren nicht herum…

Schon mal jemand die Slony-I scripts ausprobiert?
Soll ja auch ne möglichkeit sein um DBs zu replizieren.

Ist zwar nicht mehr ganz taufrisch das Thema aber vielleicht hilfts noch jemandem.

Sofern die Daten via JDBC in die Datenbank gelangen wäre C-JDBC http://c-jdbc.objectweb.org/ bzw. Sequoia http://sequoia.continuent.org/ noch ein möglicher Lösungsweg.
Mit Carob http://carob.continuent.org gibt es aber auch eine C++ Lösung.

Hi

Jap! Slony-Skripts kann ich posten. Schwieriger wirds, wenn neue nodes dazukommen.

Slony ist asynchron und je nach DB kompliziert zu konfigurieren! Man sollte wissen was man tut! Ansonsten (wenn man überhaupt keine Ahnung hat) ein DRBD Cluster aufsetzen und die checkpoint_segments hochsetzen.

  1. Variablen erstmal:
HOST1="192.168.101.10"
HOST2="192.168.101.11"
DBNAME="testdb"
TABLE1="sltest1"
TABLE2="sltest2"
CLUSTERNAME="slonytest"
SLONY_USER="postgres"
INTERVAL="10"
  1. Datenbank und Tabellen auf Masternode erstellen:
createdb -U postgres -O postgres -h $HOST1 $DBNAME
createdb -U postgres -O postgres -h $HOST2 $DBNAME
psql -U postgres -h $HOST1 -c 'create language plpgsql;' -d $DBNAME
psql -U postgres -h $HOST1 -c "create table $TABLE1 (id serial primary key, name varchar(30));" -d $DBNAME
psql -U postgres -h $HOST1 -c "create table $TABLE2 (id serial primary key, name varchar(30));" -d $DBNAME
pg_dump -s -U postgres -h $HOST1 $DBNAME | psql -U postgres -h $HOST2 $DBNAME
  1. Cluster initialisieren:
slonik <<_EOF_
cluster name = $CLUSTER;
node 1 admin conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER';
node 2 admin conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER';

init cluster (
 id = 1,
 comment = 'Node 1' 
);

table add key (
 node id = 1, 
 fully qualified name = '${TABLE1}'
);

table add key (
 node id = 1,
 fully qualified name = '${TABLE2}'
);

create set (
 id = 1,
 origin = 1, 
 comment = '${SETNAME}'
);

set add table ( 
 set id = 1,
 origin = 1,
 id = 1,
 fully qualified name = '${TABLE1}',
 comment = 'Table test1'
);

set add table (
 set id = 1,
 origin = 1,
 id = 2,
 fully qualified name = '${TABLE2}',
 comment = 'Table test2'
);

store node (
 id = 2,
 comment = 'Node 2'
);

store path (
 server = 1,
 client = 2,
 conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER'
);

store path (
 server = 2,
 client = 1,
 conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER'
);

store listen (
 origin = 1,
 provider = 1,
 receiver = 2
);

store listen (
 origin = 2,
 provider = 2,
 receiver = 1
);
_EOF_

# store listen wird bei neueren Versionen automatisch gesetzt!
  1. slon-daemons auf beiden hosts starten:
root@node1:/ nohup slon slonycluster "dbname=${DBNAME} user=${SLONY_USER} host=${HOST1}" &
root@node2:/ nohup slon slonycluster "dbname=${DBNAME} user=${SLONY_USER} host=${HOST2}" &
  1. Von node1 nach node2 syncen geht so:
while true; do 
slonik <<_EOF_
 cluster name = $CLUSTER;
 node 1 admin conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER';
 node 2 admin conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER';
 subscribe set ( 
  id = 1, 
  provider = 1, 
  receiver = 2, 
  forward = no
 );
_EOF_
 sleep $INTERVAL
done
  1. tabellen zumüllen:
while true; do
 psql -U postgres -d $DBNAME -h $HOST1 -c "insert into $TABLE1 (name) values ("blabla");
 sleep 0.025
done
  1. gucken ob die nodes nahezu auf gleichem stand sind:
psql -U postgres -d $DBNAME -h $HOST1 -c "select count(*) from $TABLE1;"
psql -U postgres -d $DBNAME -h $HOST2 -c "select count(*) from $TABLE1;"

psql -U postgres -d $DBNAME -h $HOST1 -c "select count(*) from $TABLE2;"
psql -U postgres -d $DBNAME -h $HOST2 -c "select count(*) from $TABLE2;"
  1. failover wenn node1 noch ein bisschen lebt und noch syncen kann (transaktionen können währendessen weiterlaufen! die tabellen werden gelockt bis der sync vollständig von n1 auf n2 gegangen ist):
slonik <<_EOF_
 cluster name = $CLUSTER;
 node 1 admin conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER';
 node 2 admin conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER';
 lock set (id = 1, origin = 1);
 wait for event (origin = 1, confirmed = 2);
 move set (id = 1, old origin = 1, new origin = 2);
 wait for event (origin = 1, confirmed = 2);
_EOF_
  1. failback wenn node1 noch nicht per “drop node” aus dem cluster geschmissen wurde und wieder fit ist:
slonik <<_EOF_
 cluster name = $CLUSTER;
 node 1 admin conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER';
 node 2 admin conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER';
 lock set (id = 1, origin = 2);
 wait for event (origin = 2, confirmed = 1);
 move set (id = 1, old origin = 2, new origin = 1);
 wait for event (origin = 2, confirmed = 1);
_EOF_
  1. failover wenn node1 total im eimer ist und nicht mehr syncen kann (hier gehen transaktionen evtl. verloren, da slony asynchron :wink: ! ):
slonik <<_EOF_
 cluster name = $CLUSTER;
 node 1 admin conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER';
 node 2 admin conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER';
 failover ( id = 1, backup node = 2);
 drop node ( id = 1, event node = 2);
_EOF_
  1. failback wenn node1 aus dem cluster gelöscht wurde und wieder fit ist:
 psql -U postgres -h $HOST1 -c "drop schema _$CLUSTER cascade;" -d $DBNAME
 dropdb -h $HOST1 -U postgres $DBNAME
 createdb -h $HOST1 -U postgres $DBNAME
 psql -U postgres -h $HOST1 -c "create language plpgsql;" -d $DBNAME
 pg_dump -s -U postgres -h $HOST2 $DBNAME | psql -U postgres -h $HOST1 $DBNAME
slonik <<_EOF_
 cluster name = $CLUSTER;
 node 1 admin conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER';
 node 2 admin conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER';
 store node ( 
  id = 1, 
  comment = 'Node 1', 
  event node = 2 
 );
 store path ( 
  server = 2, 
  client = 1, 
  conninfo = 'dbname=$DBNAME host=$HOST1 user=$SLONY_USER'
 );
 store path ( 
  server = 1, 
  client = 2, 
  conninfo = 'dbname=$DBNAME host=$HOST2 user=$SLONY_USER'
 );
 store listen ( 
  origin = 2, 
  provider = 2, 
  receiver = 1 
 );
 store listen ( 
  origin = 1, 
  provider = 1,
  receiver = 2 
 );
_EOF_

Hoffe damit kann man was anfangen :wink: .

Gruß
pingufreak

Ich bin auf SUSE 10.1 umgestiegen. Wo bekomme ich ein fertiges rpm her? Ich habe schon viele Stunden gesucht, bin zwar fündug geworden, aber nicht für SUSE 10.1 und postgres 8.1…
Wer kann helfen?

Was spricht gegen den Download des SRPMs und dessen Build?

http://pgfoundry.org/frs/?group_id=1000122

So, ich hab mal im IRC-Chat gefragt und von X-Fade diesen Link bekommen:

http://fr2.rpmfind.net//linux/RPM/opensuse/OSS-factory/i586/slony1-1.1.5-18.i586.html

Andreas