#!/bin/sh # # ********** # test_J_pgbench # # This test script creates a standalone pgbench database # as slony_test1 and then: # # - initializes a primary node and starts the node daemon # - creates a set containing all 4 pgbench tables # - creates a second database as slony_test2 # - adds database slony_test2 to the system # - starts the second replication daemon # - creates the pgbench tables (schema only) # - subscribes the replication set from the primary node # - creates a 3rd database node similar that replicates # cascaded from the second node. # - waits until the pgbench is terminated and the user # stopped all 3 replication engines. # - compares the 3 database. # ********** TERMPROG=xterm WHICHPROG=which PATH=/usr/local/slony1/bin:$PATH export PATH TMPOUT=/tmp/output.$$ DB1=slony_test1 DB2=slony_test2 DB3=slony_test3 DEBUG_LEVEL=2 PGBENCH_SCALE=2 PGBENCH_CLIENTS=2 PGBENCH_TRANS=`expr 50000 / $PGBENCH_CLIENTS` trap ' echo "" echo "**** user abort" if [ ! -z $pgbench_pid ] ; then echo "**** killing pgbench" kill -15 $pgbench_pid fi if [ ! -z $slon1_pid ] ; then echo "**** killing node daemon 1" kill -15 $slon1_pid fi if [ ! -z $slon2_pid ] ; then echo "**** killing node daemon 2" kill -15 $slon2_pid fi if [ ! -z $slon3_pid ] ; then echo "**** killing node daemon 3" kill -15 $slon3_pid fi exit -1 ' 2 15 ###################################################################### # Preparations ... create a standalone pgbench database and # have the "application" (pgbench) running. ###################################################################### ##### # Make sure the install is up to date ##### WGM=`$WHICHPROG gmake | egrep '^/'` if [ -z "$WGM" ] ; then MAKE=make CGNU=`make -v | grep GNU` if [ -z "$CGNU" ] ; then echo "GNU Make not found - please install GNU Make" exit 1 fi else MAKE=gmake fi echo -n "**** running 'make install' in src directory ... " if ! ${MAKE} -C .. install >$TMPOUT 2>&1 ; then echo "failed"; cat $TMPOUT; rm $TMPOUT; exit -1 fi echo "done" rm $TMPOUT ##### # Remove old databases, if they exist ##### echo "**** remove old test databases" dropdb $DB1 || echo "**** ignored" sleep 1 dropdb $DB2 || echo "**** ignored" sleep 1 dropdb $DB3 || echo "**** ignored" sleep 1 ##### # Create the "Primary Node" ##### echo "**** creating database for Node 1" createdb $DB1 || exit -1 pgbench -i -s $PGBENCH_SCALE $DB1 pg_dump -s $DB1 >pgbench_schema.sql ##### # Start pgbench in the background and give it rampup time ##### pgbench -n -s $PGBENCH_SCALE -c $PGBENCH_CLIENTS -t $PGBENCH_TRANS $DB1 & pgbench_pid=$! echo "**** pgbench is running in background with pid $pgbench_pid" echo -n "**** sleeping 10 seconds to give pgbench time for rampup ... " sleep 10 echo "done" echo "" echo "**********************************************************************" echo "**** $DB1 is now a standalone database with a running pgbench" echo "**********************************************************************" echo "" ###################################################################### # Setup DB1 as the primary cluster T1 node, start the node daemon, # and create a replication set containing the pgbench tables. ###################################################################### echo "**** initializing $DB1 as Primary Node for Slony-I cluster T1" slonik <<_EOF_ cluster name = T1; node 1 admin conninfo = 'dbname=$DB1'; node 2 admin conninfo = 'dbname=$DB1'; node 3 admin conninfo = 'dbname=$DB1'; init cluster (id = 1, comment = 'Node 1'); echo 'Database $DB1 initialized as Node 1'; _EOF_ if [ $? -ne 0 ] ; then kill $pgbench_pid; exit -1 fi echo "**** starting the Slony-I node daemon for $DB1" $TERMPROG -title "Slon node 1" -e sh -c "slon -d$DEBUG_LEVEL T1 dbname=$DB1; echo -n 'Enter>'; read line" & slon1_pid=$! echo "slon[$slon1_pid] on dbname=$DB1" echo "**** creating a replication set containing the 4 pgbench tables ... " slonik <<_EOF_ cluster name = T1; node 1 admin conninfo = 'dbname=$DB1'; node 2 admin conninfo = 'dbname=$DB2'; node 3 admin conninfo = 'dbname=$DB3'; try { table add key (node id = 1, fully qualified name = 'public.history'); } on error { exit -1; } try { create set (id = 100, origin = 1, comment = 'Set 100 - accounts'); create set (id = 200, origin = 1, comment = 'Set 200 - branches'); create set (id = 300, origin = 1, comment = 'Set 300 - tellers'); create set (id = 400, origin = 1, comment = 'Set 400 - history'); set add table (set id = 100, origin = 1, id = 1, fully qualified name = 'public.accounts', comment = 'Table accounts'); set add table (set id = 200, origin = 1, id = 2, fully qualified name = 'public.branches', comment = 'Table branches'); set add table (set id = 300, origin = 1, id = 3, fully qualified name = 'public.tellers', comment = 'Table tellers'); set add table (set id = 400, origin = 1, id = 4, fully qualified name = 'public.history', key = serial, comment = 'Table accounts'); } on error { exit -1; } _EOF_ if [ $? -ne 0 ] ; then echo "failed" kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null cat $TMPOUT rm $TMPOUT exit -1 fi echo "**** set created" ##### # Check that pgbench is still running ##### if ! kill -0 $pgbench_pid 2>/dev/null ; then echo "**** pgbench terminated ???" kill $slon1_pid 2>/dev/null exit -1 fi echo "" echo "**********************************************************************" echo "**** $DB1 is now the Slony-I origin for sets 100..400" echo "**********************************************************************" echo "" ###################################################################### # Setup DB2 as a subscriber node and let it subscribe the replication # set of the running pgbench ###################################################################### echo "**** creating database for Node 2" if ! createdb $DB2 ; then kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null exit -1 fi echo "**** initializing $DB2 as Node 2 of Slony-I cluster T1" slonik <<_EOF_ cluster name = T1; node 1 admin conninfo = 'dbname=$DB1'; node 2 admin conninfo = 'dbname=$DB2'; node 3 admin conninfo = 'dbname=$DB3'; try { store node (id = 2, comment = 'Node 2', event node=1); store path (server = 1, client = 2, conninfo = 'dbname=$DB1'); store path (server = 2, client = 1, conninfo = 'dbname=$DB2'); } on error { exit -1; } echo 'Database $DB2 added as Node 2'; _EOF_ if [ $? -ne 0 ] ; then kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null exit -1 fi echo "**** starting the Slony-I node daemon for $DB2" $TERMPROG -title "Slon node 2" -e sh -c "slon -d$DEBUG_LEVEL T1 dbname=$DB2; echo -n 'Enter>'; read line" & slon2_pid=$! echo "slon[$slon2_pid] on dbname=$DB2" ##### # Check that pgbench is still running ##### if ! kill -0 $pgbench_pid 2>/dev/null ; then echo "**** pgbench terminated ???" kill $slon1_pid 2>/dev/null exit -1 fi ###################################################################### # And now comes the moment where the big elephant starts to pee # and the attendants in the first row climb on their chairs ... ###################################################################### echo "**** creating pgbench tables and subscribing Node 2 to set 1" ( cat pgbench_schema.sql ) | psql -q $DB2 slonik <<_EOF_ cluster name = T1; node 1 admin conninfo = 'dbname=$DB1'; node 2 admin conninfo = 'dbname=$DB2'; node 3 admin conninfo = 'dbname=$DB3'; subscribe set ( id = 100, provider = 1, receiver = 2, forward = yes ); subscribe set ( id = 200, provider = 1, receiver = 2, forward = yes ); subscribe set ( id = 300, provider = 1, receiver = 2, forward = yes ); subscribe set ( id = 400, provider = 1, receiver = 2, forward = yes ); echo '**** Waiting for node 2 to finish subscription of set 400'; wait for event (origin = 2, confirmed = 1, wait on = 2); sync (id = 1); wait for event (origin = 1, confirmed = 2, wait on = 1); _EOF_ echo "" echo "**********************************************************************" echo "**** $DB2 should now be attempting to catch up." echo "**********************************************************************" echo "" ###################################################################### # Setup DB2 as a subscriber node and let it subscribe the replication # set of the running pgbench ###################################################################### echo "**** creating database for Node 3" if ! createdb $DB3 ; then kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null kill $slon2_pid 2>/dev/null exit -1 fi echo "**** initializing $DB3 as Node 3 of Slony-I cluster T1" slonik <<_EOF_ cluster name = T1; node 1 admin conninfo = 'dbname=$DB1'; node 2 admin conninfo = 'dbname=$DB2'; node 3 admin conninfo = 'dbname=$DB3'; store node (id = 3, comment = 'Node 3', event node=1); store path (server = 1, client = 3, conninfo = 'dbname=$DB1'); store path (server = 2, client = 3, conninfo = 'dbname=$DB2'); store path (server = 3, client = 1, conninfo = 'dbname=$DB3'); store path (server = 3, client = 2, conninfo = 'dbname=$DB3'); echo 'Database $DB2 added as Node 2'; _EOF_ if [ $? -ne 0 ] ; then kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null kill $slon2_pid 2>/dev/null exit -1 fi echo "**** starting the Slony-I node daemon for $DB3" $TERMPROG -title "Slon node 3" -e sh -c "slon -d$DEBUG_LEVEL T1 dbname=$DB3; echo -n 'Enter>'; read line" & slon3_pid=$! echo "slon[$slon3_pid] on dbname=$DB3" ##### # Check that pgbench is still running ##### if ! kill -0 $pgbench_pid 2>/dev/null ; then echo "**** pgbench terminated ???" kill $slon1_pid 2>/dev/null exit -1 fi ###################################################################### # Create the pgbench tables and subscribe to set 1 ###################################################################### echo "**** creating pgbench tables and subscribing Node 2 to set 1" ( cat pgbench_schema.sql ) | psql -q $DB3 slonik <<_EOF_ cluster name = T1; node 1 admin conninfo = 'dbname=$DB1'; node 2 admin conninfo = 'dbname=$DB2'; node 3 admin conninfo = 'dbname=$DB3'; subscribe set ( id = 100, provider = 2, receiver = 3, forward = no ); subscribe set ( id = 200, provider = 2, receiver = 3, forward = no ); subscribe set ( id = 300, provider = 2, receiver = 3, forward = no ); subscribe set ( id = 400, provider = 2, receiver = 3, forward = no ); echo '**** Waiting for node 3 to finish subscription of set 400'; wait for event (origin = 3, confirmed = 1, wait on = 3); sync (id = 1); wait for event (origin = 1, confirmed = 3, wait on = 1); _EOF_ echo "" echo "**********************************************************************" echo "**** $DB3 should now be attempting to catch up." echo "**********************************************************************" echo "" echo -n "**** waiting for pgbench to finish " while kill -0 $pgbench_pid 2>/dev/null ; do echo -n "." sleep 10 done echo "**** pgbench finished" echo "**** please terminate the replication engines when caught up." wait $slon1_pid wait $slon2_pid wait $slon3_pid kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null kill $slon2_pid 2>/dev/null kill $slon3_pid 2>/dev/null echo -n "**** comparing databases ... " psql $DB1 -o dump.tmp.1.$$ <<_EOF_ select 'accounts:'::text, aid, bid, abalance, filler from accounts order by aid; select 'branches:'::text, bid, bbalance, filler from branches order by bid; select 'tellers:'::text, tid, bid, tbalance, filler from tellers order by tid; select 'history:'::text, tid, bid, aid, delta, mtime, filler, "_Slony-I_T1_rowID" from history order by "_Slony-I_T1_rowID"; _EOF_ psql $DB2 -o dump.tmp.2.$$ <<_EOF_ select 'accounts:'::text, aid, bid, abalance, filler from accounts order by aid; select 'branches:'::text, bid, bbalance, filler from branches order by bid; select 'tellers:'::text, tid, bid, tbalance, filler from tellers order by tid; select 'history:'::text, tid, bid, aid, delta, mtime, filler, "_Slony-I_T1_rowID" from history order by "_Slony-I_T1_rowID"; _EOF_ psql $DB3 -o dump.tmp.3.$$ <<_EOF_ select 'accounts:'::text, aid, bid, abalance, filler from accounts order by aid; select 'branches:'::text, bid, bbalance, filler from branches order by bid; select 'tellers:'::text, tid, bid, tbalance, filler from tellers order by tid; select 'history:'::text, tid, bid, aid, delta, mtime, filler, "_Slony-I_T1_rowID" from history order by "_Slony-I_T1_rowID"; _EOF_ if diff dump.tmp.1.$$ dump.tmp.2.$$ >test_J.1-2.diff ; then echo "success - databases 1 and 2 are equal." rm dump.tmp.2.$$ rm test_J.1-2.diff else echo "FAILED - see test_J.1-2.diff for database differences" fi echo -n "**** comparing databases ... " if diff dump.tmp.1.$$ dump.tmp.3.$$ >test_J.1-3.diff ; then echo "success - databases 1 and 3 are equal." rm dump.tmp.3.$$ rm dump.tmp.1.$$ rm test_J.1-3.diff else echo "FAILED - see test_J.1-3.diff for database differences" fi