#!/bin/bash # ********** # test_6_autolisten # # 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 5 other databases to contain this set # - subscribes #2 and #3 directly to #1, then #4 subscribes # to #3, then #5 & #6 subscribe to #4 # - compares the 6 databases. # ********** TERMPROG=xterm WHICHPROG=which PATH=/usr/local/slony1/bin:$PATH export PATH TMPOUT=/tmp/output.$$ ORIGIN=slony_test1 DEBUG_LEVEL=2 PGBENCH_SCALE=1 PGBENCH_CLIENTS=5 PGBENCH_TRANS=`expr 50000 / $PGBENCH_CLIENTS` declare -a PIDS trap ' echo "" echo "**** user abort" if [ ! -z $pgbench_pid ] ; then echo "**** killing pgbench" kill -15 $pgbench_pid fi for node in 1 2 3 4 5 6; do if [ ! -z $PIDS[$node] ] ; then echo "**** killing node daemon $node" kill -15 $PIDS[$node] fi done exit -1 ' 2 15 function initialize_slave_database () { local NODE=$1 echo "**** creating database for Node $node" if ! createdb slony_test$NODE ; then kill $pgbench_pid 2>/dev/null kill $slon1_pid 2>/dev/null exit -1 fi echo "**** creating pgbench tables" ( cat pgbench_schema.sql ) | psql -q slony_test$NODE } function extra_listen () { local ORIGIN=$1 local RECEIVER=$2 local PROVIDER=$3 slonik <'; read line" & PID[$NODE]=$! pid=$PID[$NODE] echo "slon[$pid] on dbname=slony_test$NODE" } function slon_subscribe () { local SUBSCRIBER=$1 local PROVIDER=$2 ###################################################################### # And now comes the moment where the big elephant starts to pee # and the attendants in the first row climb on their chairs ... ###################################################################### slonik <<_EOF_ $PREAMBLE subscribe set ( id = 1, provider = $PROVIDER, receiver = $SUBSCRIBER, forward = yes ); _EOF_ } function check_pgbench () { ##### # 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 } ###################################################################### # 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" for db in 1 2 3 4 5 6; do dropdb slony_test$db || echo "**** ignored" sleep 1 done ##### # Create the "Primary Node" ##### echo "**** creating database for Node 1" createdb $ORIGIN || exit -1 pgbench -i -s $PGBENCH_SCALE $ORIGIN pg_dump -s $ORIGIN >pgbench_schema.sql ##### # Start pgbench in the background and give it rampup time ##### pgbench -n -s $PGBENCH_SCALE -c $PGBENCH_CLIENTS -t $PGBENCH_TRANS $ORIGIN & 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. ###################################################################### PREAMBLE=" cluster name = T1; " for node in 1 2 3 4 5 6; do PREAMBLE="$PREAMBLE node $node admin conninfo= 'dbname=slony_test$node';" done echo "**** initializing $DB1 as Primary Node for Slony-I cluster T1" slonik <<_EOF_ $PREAMBLE 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 slon_start 1 echo "**** creating a replication set containing the 4 pgbench tables ... " slonik <<_EOF_ $PREAMBLE try { table add key (node id = 1, fully qualified name = 'public.history'); } on error { exit -1; } try { create set (id = 1, origin = 1, comment = 'Set 1 - pgbench tables'); set add table (set id = 1, origin = 1, id = 1, fully qualified name = 'public.accounts', comment = 'Table accounts'); set add table (set id = 1, origin = 1, id = 2, fully qualified name = 'public.branches', comment = 'Table branches'); set add table (set id = 1, origin = 1, id = 3, fully qualified name = 'public.tellers', comment = 'Table tellers'); set add table (set id = 1, 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 ##### check_pgbench echo "" echo "**********************************************************************" echo "**** $DB1 is now the Slony-I origin for set 1" echo "**********************************************************************" echo "" ###################################################################### # Setup DB2 and DB3 as subscribers to node 1 ###################################################################### for node in 2 3; do initialize_slave_database $node echo "**** initializing slony_test$node as Node $node of Slony-I cluster T1" slonik_init $node 1 for n2 in 2 3; do if [[ $n2 != $node ]]; then extra_listen $node $n2 1 fi done check_pgbench slon_start $node check_pgbench slon_subscribe $node 1 echo "" echo "**********************************************************************" echo "**** slony_test$node should now be copying data and attempting to catch up." echo "**********************************************************************" echo "" done echo "done with cluster of [1,2,3]" ###################################################################### # Setup DB4 as subscriber to node 3; it only talks to 3, not 1 or 2 ###################################################################### initialize_slave_database 4 echo "**** initializing slony_test4 as Node 4 of Slony-I cluster T1" slonik <<_EOF_ $PREAMBLE try { store node (id = 4, comment = 'Node $node', event node=1); store path (server = 3, client = 4, conninfo = 'dbname=slony_test3'); store path (server = 4, client = 3, conninfo = 'dbname=slony_test4'); store listen (origin = 1, receiver = 4, provider=3); store listen (origin = 4, receiver = 1, provider=3); } on error { exit -1; } echo 'Database slony_test4 added as Node 4'; _EOF_ for node in 1 2; do extra_listen 4 $node 3 extra_listen $node 4 3 done check_pgbench slon_start 4 check_pgbench slon_subscribe 4 3 echo "" echo "**********************************************************************" echo "**** slony_test4 should now be copying data and attempting to catch up." echo "**********************************************************************" echo "" for node in 5 6; do initialize_slave_database $node echo "**** initializing slony_test4 as Node 4 of Slony-I cluster T1" slonik <<_EOF_ $PREAMBLE try { store node (id = $node, comment = 'Node $node', event node=1); store path (server = 4, client = $node, conninfo = 'dbname=slony_test4'); store path (server = $node, client = 4, conninfo = 'dbname=slony_test$node'); } on error { exit -1; } echo 'Database slony_test$node added as Node $node'; _EOF_ for source in 1 2 3 4 5 6; do if [[ $source != $node ]]; then extra_listen $source $node 4 extra_listen $node $source 4 fi done check_pgbench slon_start $node check_pgbench slon_subscribe $node 4 done for node in 1 2 3 4 5 6; do echo "select \"_T1\".rebuildlistenentries();" | psql slony_test$node done 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." for node in 1 2 3 4 5 6; do pid=$PID[$node] wait $pid done kill $pgbench_pid 2>/dev/null for node in 1 2 3 4 5 6; do pid=$PID[$node] kill $pid 2> /dev/null done echo -n "**** comparing databases ... " for node in 1 2 3 4 5 6 ; do psql slony_test$node -o dump.tmp.$node.$$ <<_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_ done for node in 2 3 4 5 6; do if diff dump.tmp.1.$$ dump.tmp.$node.$$ >test_$node.1-$node.diff ; then echo "success - databases 1 and $node are equal." rm dump.tmp.$node.$$ rm test_$node.1-$node.diff else echo "FAILED - see test_$node.1-$node.diff for database differences" fi done