CVS User Account cvsuser
Tue Nov 14 09:24:22 PST 2006
Log Message:
-----------
Let the watchdog restart the worker process immediately if it
terminated with exit code zero, instead of waiting for 10 seconds.

Added test_J to the ducttape suite. The test is a cascaded 3 node
setup using a separate set for each of the pgbench tables.

Jan

Tags:
----
REL_1_2_STABLE

Modified Files:
--------------
    slony1-engine/src/slon:
        slon.c (r1.66.2.2 -> r1.66.2.3)

Added Files:
-----------
    slony1-engine/src/ducttape:
        test_J_handover_to_2 (r1.1.2.1)
        test_J_pgbench.in (r1.1.2.1)

-------------- next part --------------
--- /dev/null
+++ src/ducttape/test_J_handover_to_2
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# **********
+# test_1_handover_to_2
+#
+#	Script to change the origin of set 1 from node 1 to node 2.
+#	This still requires that node 1 is alive. This is called
+#	handover or move, not failover.
+# **********
+
+export PATH
+TMPOUT=/tmp/output.$$
+DB1=slony_test1
+DB2=slony_test2
+
+######################################################################
+# Move set 1 to node 2
+######################################################################
+
+echo "**** Move sets 100..400 to node 2"
+slonik <<_EOF_
+	cluster name = T1;
+	node 1 admin conninfo = 'dbname=$DB1';
+	node 2 admin conninfo = 'dbname=$DB2';
+
+	lock set (id = 100, origin = 1);
+	lock set (id = 200, origin = 1);
+	lock set (id = 300, origin = 1);
+	lock set (id = 400, origin = 1);
+	move set (id = 100, old origin = 1, new origin = 2);
+	move set (id = 200, old origin = 1, new origin = 2);
+	move set (id = 300, old origin = 1, new origin = 2);
+	move set (id = 400, old origin = 1, new origin = 2);
+_EOF_
+
--- /dev/null
+++ src/ducttape/test_J_pgbench.in
@@ -0,0 +1,430 @@
+#!/bin/sh
+# $Id: test_J_pgbench.in,v 1.1.2.1 2006/11/14 17:24:20 wieck Exp $
+# **********
+# 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');
+		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');
+
+	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
Index: slon.c
===================================================================
RCS file: /usr/local/cvsroot/slony1/slony1-engine/src/slon/slon.c,v
retrieving revision 1.66.2.2
retrieving revision 1.66.2.3
diff -Lsrc/slon/slon.c -Lsrc/slon/slon.c -u -w -r1.66.2.2 -r1.66.2.3
--- src/slon/slon.c
+++ src/slon/slon.c
@@ -861,8 +861,15 @@
 		case SLON_WATCHDOG_NORMAL:
 		case SLON_WATCHDOG_RETRY:
 			watchdog_status = SLON_WATCHDOG_RETRY;
+			if (child_status != 0)
+			{
 			slon_log(SLON_DEBUG1, "slon: restart of worker in 10 seconds\n");
 			sleep(10);
+			}
+			else
+			{
+				slon_log(SLON_DEBUG1, "slon: restart of worker\n");
+			}
 			if (watchdog_status == SLON_WATCHDOG_RETRY)
 			{
 				execvp(main_argv[0], main_argv);



More information about the Slony1-commit mailing list