Thu Dec 15 17:36:49 PST 2005
- Previous message: [Slony1-general] Slony 1.1.5 RC packaging issues
- Next message: [Slony1-general] japanese translation of slony manual
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Folks, Gavin and I are patching up the altperl scripts for a little better usability. Although the whole bunch should (eventually) be "strict clean" and other niceties, this is a fairly decent start. Changed files in this patch are: tools/altperl/slon_kill.pl tools/altperl/slon_start.pl tools/altperl/slon_watchdog.pl tools/altperl/slon_watchdog2.pl tools/altperl/slonik_store_node.pl tools/altperl/slonik_subscribe_set.pl tools/altperl/slonik_uninstall_nodes.pl tools/altperl/slonik_unsubscribe_set.pl tools/altperl/slonik_update_nodes.pl tools/altperl/slony_show_configuration.pl Is it possible to test these in a "not installed yet" setup? Cheers, D -- David Fetter david at fetter.org http://fetter.org/ phone: +1 415 235 3778 Remember to vote! -------------- next part -------------- Index: tools/altperl/slon_kill.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slon_kill.pl,v retrieving revision 1.12 diff -c -r1.12 slon_kill.pl *** tools/altperl/slon_kill.pl 16 Mar 2005 20:37:54 -0000 1.12 --- tools/altperl/slon_kill.pl 15 Dec 2005 16:56:39 -0000 *************** *** 4,9 **** --- 4,10 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults *************** *** 13,38 **** # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE, "w|watchdog" => \$WATCHDOG_ONLY); ! my $USAGE = ! "Usage: slon_kill [--config file] [-w|--watchdog] ! ! --config file Location of the slon_tools.conf file ! ! -w ! --watchdog Only kill the watchdog process(es) ! ! Kills all running slon and slon_watchdog on this machine for every ! node in the cluster. ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; --- 14,23 ---- # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE, "w|watchdog" => \$WATCHDOG_ONLY); ! pod2usage(1) if $SHOW_USAGE; require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; *************** *** 65,76 **** $found="n"; while ($pid = <PSOUT>) { chomp $pid; ! if (!($pid)) { ! print "No slon_watchdog is running for the cluster $CLUSTER_NAME!\n"; ! } else { ! $found="y"; ! kill 9, $pid; ! print "slon_watchdog for cluster $CLUSTER_NAME killed - PID [$pid]\n"; ! } } } --- 50,80 ---- $found="n"; while ($pid = <PSOUT>) { chomp $pid; ! if (!($pid)) { ! print "No slon_watchdog is running for the cluster $CLUSTER_NAME!\n"; ! } else { ! $found="y"; ! kill 9, $pid; ! print "slon_watchdog for cluster $CLUSTER_NAME killed - PID [$pid]\n"; ! } } } + __END__ + + =head1 NAME + + slon_kill + + =head1 SYNOPSIS + + Usage: slon_kill [--config file] [-w|--watchdog] + + --config file Location of the slon_tools.conf file + + -w + --watchdog Only kill the watchdog process(es) + + Kills all running slon and slon_watchdog on this machine for every + node in the cluster. + + =cut Index: tools/altperl/slon_start.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slon_start.pl,v retrieving revision 1.14 diff -c -r1.14 slon_start.pl *** tools/altperl/slon_start.pl 22 Feb 2005 17:11:18 -0000 1.14 --- tools/altperl/slon_start.pl 15 Dec 2005 16:56:39 -0000 *************** *** 3,41 **** # Author: Christopher Browne # Copyright 2004 Afilias Canada use Getopt::Long; # Defaults ! $START_WATCHDOG = 1; ! $SLEEP_TIME = 30; ! $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; ! $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, "watchdog!" => \$START_WATCHDOG, "sleep=i" => \$SLEEP_TIME, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: slon_start [--config file] [--watchdog|--nowatchdog] ! [--sleep seconds] node# ! ! --config file Location of the slon_tools.conf file ! ! --watchdog Start a watchdog process after starting the slon ! daemon (default) ! ! --nowatchdog Do not start a watchdog process ! ! --sleep seconds Number of seconds for the watchdog process to sleep ! between checks (default 30) ! ! "; ! ! if ($SHOW_USAGE or scalar(@ARGV) != 1) { ! die $USAGE; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; --- 3,24 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults ! my $START_WATCHDOG = 1; ! my $SLEEP_TIME = 30; ! my $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; ! my $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, "watchdog!" => \$START_WATCHDOG, "sleep=i" => \$SLEEP_TIME, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if ($SHOW_USAGE or scalar(@ARGV) != 1); require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; *************** *** 44,58 **** # Node can be passed either as "node1" or just "1" if ($node =~ /^(?:node)?(\d+)$/) { ! $node = "node$1"; ! $nodenum = $1; } else { ! die $USAGE; } $pid = get_pid($node); if ($pid) { ! die "Slon is already running for the '$CLUSTER_NAME' cluster.\n"; } my $dsn = $DSN[$nodenum]; --- 27,41 ---- # Node can be passed either as "node1" or just "1" if ($node =~ /^(?:node)?(\d+)$/) { ! $node = "node$1"; ! $nodenum = $1; } else { ! pod2usage(1); } $pid = get_pid($node); if ($pid) { ! die "Slon is already running for the '$CLUSTER_NAME' cluster.\n"; } my $dsn = $DSN[$nodenum]; *************** *** 61,72 **** $pid = get_pid($node); unless ($pid) { ! print "Slon failed to start for cluster $CLUSTER_NAME, node $node\n"; } else { ! print "Slon successfully started for cluster $CLUSTER_NAME, node $node\n"; ! print "PID [$pid]\n"; ! if ($START_WATCHDOG) { ! print "Start the watchdog process as well...\n"; ! system "@@TOOLSBIN@@/slon_watchdog --config=$CONFIG_FILE $node $SLEEP_TIME &"; ! } } --- 44,78 ---- $pid = get_pid($node); unless ($pid) { ! print "Slon failed to start for cluster $CLUSTER_NAME, node $node\n"; } else { ! print "Slon successfully started for cluster $CLUSTER_NAME, node $node\n"; ! print "PID [$pid]\n"; ! if ($START_WATCHDOG) { ! print "Start the watchdog process as well...\n"; ! system "@@TOOLSBIN@@/slon_watchdog --config=$CONFIG_FILE $node $SLEEP_TIME &"; ! } } + + __END__ + + =head1 NAME + + sample - Using GetOpt::Long and Pod::Usage + + =head1 SYNOPSIS + + Usage: slon_start [--config file] [--watchdog|--nowatchdog] + [--sleep seconds] node# + + --config file Location of the slon_tools.conf file + + --watchdog Start a watchdog process after starting the slon + daemon (default) + + --nowatchdog Do not start a watchdog process + + --sleep seconds Number of seconds for the watchdog process to sleep + between checks (default 30) + + =cut Index: tools/altperl/slon_watchdog.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slon_watchdog.pl,v retrieving revision 1.11.2.1 diff -c -r1.11.2.1 slon_watchdog.pl *** tools/altperl/slon_watchdog.pl 25 Jul 2005 21:37:02 -0000 1.11.2.1 --- tools/altperl/slon_watchdog.pl 15 Dec 2005 16:56:39 -0000 *************** *** 3,31 **** # Author: Christopher Browne # Copyright 2004 Afilias Canada use Getopt::Long; # Defaults $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! ! my $USAGE = ! "Usage: slon_watchdog [--config file] node# sleep_seconds ! ! --config file Location of the slon_tools.conf file ! ! sleep_seconds Number of seconds for the watchdog process to sleep ! between checks ! "; ! ! if ($SHOW_USAGE or scalar(@ARGV) != 2) { ! die $USAGE; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; --- 3,21 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults + $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if ($SHOW_USAGE or scalar(@ARGV) != 2); require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; *************** *** 34,66 **** $sleep = $ARGV[1]; if ($node =~/^(?:node)?(\d+)$/) { ! $nodenum = $1; } else { ! die $USAGE; } while (1) { - $pid = get_pid($node); - if (!($pid)) { - my ($dsn, $dbname) = ($DSN[$nodenum], $DBNAME[$nodenum]); - open (SLONLOG, ">>$LOGDIR/slon-$dbname-$node.err"); - print SLONLOG "WATCHDOG: No Slon is running for node $node!\n"; - print SLONLOG "WATCHDOG: You ought to check the postmaster and slon for evidence of a crash!\n"; - print SLONLOG "WATCHDOG: I'm going to restart slon for $node...\n"; - # First, restart the node using slonik - system "@@TOOLSBIN@@/slonik_restart_node $node | @@PGBINDIR@@/slonik"; - # Next, restart the slon process to service the node - start_slon($nodenum); $pid = get_pid($node); ! print SLONLOG "WATCHDOG: Restarted slon for the $CLUSTER_NAME cluster, PID $pid\n"; ! } else { ! open(LOG, ">>$LOGDIR/slon_watchdog.log"); ! print LOG "\n"; ! system "date >> $LOGDIR/slon_watchdog.log"; ! print LOG "Found slon daemon running for the $CLUSTER_NAME cluster, PID $pid\n"; ! print LOG "Looks Ok\n"; ! print LOG "Sleeping for $sleep +/- " . int($sleep/2) . " seconds\n"; ! } ! close(PSOUT); ! sleep $sleep + (rand($sleep) - $sleep/2); } --- 24,72 ---- $sleep = $ARGV[1]; if ($node =~/^(?:node)?(\d+)$/) { ! $nodenum = $1; } else { ! pod2usage(1); } while (1) { $pid = get_pid($node); ! if (!($pid)) { ! my ($dsn, $dbname) = ($DSN[$nodenum], $DBNAME[$nodenum]); ! open (SLONLOG, ">>$LOGDIR/slon-$dbname-$node.err"); ! print SLONLOG "WATCHDOG: No Slon is running for node $node!\n"; ! print SLONLOG "WATCHDOG: You ought to check the postmaster and slon for evidence of a crash!\n"; ! print SLONLOG "WATCHDOG: I'm going to restart slon for $node...\n"; ! # First, restart the node using slonik ! system "@@TOOLSBIN@@/slonik_restart_node $node | @@PGBINDIR@@/slonik"; ! # Next, restart the slon process to service the node ! start_slon($nodenum); ! $pid = get_pid($node); ! print SLONLOG "WATCHDOG: Restarted slon for the $CLUSTER_NAME cluster, PID $pid\n"; ! } else { ! open(LOG, ">>$LOGDIR/slon_watchdog.log"); ! print LOG "\n"; ! system "date >> $LOGDIR/slon_watchdog.log"; ! print LOG "Found slon daemon running for the $CLUSTER_NAME cluster, PID $pid\n"; ! print LOG "Looks Ok\n"; ! print LOG "Sleeping for $sleep +/- " . int($sleep/2) . " seconds\n"; ! } ! close(PSOUT); ! sleep $sleep + (rand($sleep) - $sleep/2); } + + __END__ + =head1 NAME + + slon_watchdog + + =head1 SYNOPSIS + + Usage: slon_watchdog [--config file] node# sleep_seconds + + --config file Location of the slon_tools.conf file + + sleep_seconds Number of seconds for the watchdog process to sleep + between checks + + =cut Index: tools/altperl/slon_watchdog2.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slon_watchdog2.pl,v retrieving revision 1.9 diff -c -r1.9 slon_watchdog2.pl *** tools/altperl/slon_watchdog2.pl 22 Feb 2005 20:50:28 -0000 1.9 --- tools/altperl/slon_watchdog2.pl 15 Dec 2005 16:56:39 -0000 *************** *** 3,86 **** # Author: Christopher Browne # Copyright 2004 Afilias Canada require '@@PGLIBDIR@@/slon-tools.pm'; require '@@SYSCONFDIR@@/slon_tools.conf'; $node =$ARGV[0]; $sleep =$ARGV[1]; ! if ( scalar(@ARGV) < 2 ) { ! die "Usage: ./slon_watchdog node sleep-time\n"; ! } if ($node =~/^node(\d+)$/) { ! $nodenum = $1; } log_to_watchdog_log("Invoking watchdog for $CLUSTER_NAME node $nodenum"); while (1) { ! my $res = query_slony_status($nodenum); # See where the node stands ! my $eventsOK; ! if ($res =~ /^\s*t\s*\|/) { ! $eventsOK = "YES"; ! } else { ! $res = node_is_subscribing(); ! if ($res =~ /SUBSCRIBE_SET/) { ! $eventsOK = "YES"; } else { ! $eventsOK = "NO"; } ! } ! my $pid = get_pid($node); # See if the slon process is alive ! my ($restart, $kick); ! $kick = "NO"; # Initially, assume we don't need to submit a "restart node" command ! if ($pid) { # PID is alive... ! if ($eventsOK eq "YES") { ! # All is well - do nothing! ! $restart = "NO"; } else { ! $restart = "YES"; ! } ! } else { ! $restart = "YES"; ! # See if the slon log ends with "FATAL localListenThread: Another slon daemon is serving this node already" ! my $lastlog=`/bin/ls -t $LOGDIR/slony1/node$nodenum/$dbname*log | head -1`; ! my $lastline=`tail -1 $lastlog`; ! if ($lastline =~ /Another slon daemon is serving this node already/) { ! $kick = "YES"; # Yup, need to tell slonik to reset this node } - } ! # If the node needs a swift kick in the "RESTART", then submit that to slonik ! if ($kick eq "YES") { ! log_to_watchdog_log("submit slonik to restart $CLUSTER_NAME node $nodenum"); ! open(SLONIK, "|@@PGBINDIR@@/slonik"); ! print SLONIK genheader(); ! print SLONIK "restart node $node\n"; ! close SLONIK; ! } ! if ($restart eq "YES") { ! if ($pid) { ! log_to_watchdog_log("terminate slon daemon for $CLUSTER_NAME node $nodenum"); ! # Kill slon until dead... ! kill 2, $pid; ! sleep 3; ! kill 15, $pid; ! sleep 3; ! kill 9, $pid; } ! log_to_watchdog_log("restart slon for $nodenum"); ! start_slon($nodenum); ! } ! sleep $sleep; } sub log_to_watchdog_log { ! my ($message) = @_; ! chomp $message; ! my $date = `date`; ! chomp $date; ! open (SLONLOG, ">>$LOGDIR/slony-watchdog.log"); ! print SLONLOG $date, "|", $message, "\n"; ! close SLONLOG; } --- 3,101 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; + require '@@PGLIBDIR@@/slon-tools.pm'; require '@@SYSCONFDIR@@/slon_tools.conf'; $node =$ARGV[0]; $sleep =$ARGV[1]; ! pod2usage(1) if ( scalar(@ARGV) < 2 ); if ($node =~/^node(\d+)$/) { ! $nodenum = $1; ! } else { ! print STDERR "Must supply a node!"; ! pod2usage(1); } log_to_watchdog_log("Invoking watchdog for $CLUSTER_NAME node $nodenum"); while (1) { ! my $res = query_slony_status($nodenum); # See where the node stands ! my $eventsOK; ! if ($res =~ /^\s*t\s*\|/) { ! $eventsOK = "YES"; } else { ! $res = node_is_subscribing(); ! if ($res =~ /SUBSCRIBE_SET/) { ! $eventsOK = "YES"; ! } else { ! $eventsOK = "NO"; ! } } ! my $pid = get_pid($node); # See if the slon process is alive ! my ($restart, $kick); ! $kick = "NO"; # Initially, assume we don't need to submit a "restart node" command ! if ($pid) { # PID is alive... ! if ($eventsOK eq "YES") { ! # All is well - do nothing! ! $restart = "NO"; ! } else { ! $restart = "YES"; ! } } else { ! $restart = "YES"; ! # See if the slon log ends with "FATAL localListenThread: Another slon daemon is serving this node already" ! my $lastlog=`/bin/ls -t $LOGDIR/slony1/node$nodenum/$dbname*log | head -1`; ! my $lastline=`tail -1 $lastlog`; ! if ($lastline =~ /Another slon daemon is serving this node already/) { ! $kick = "YES"; # Yup, need to tell slonik to reset this node ! } } ! # If the node needs a swift kick in the "RESTART", then submit that to slonik ! if ($kick eq "YES") { ! log_to_watchdog_log("submit slonik to restart $CLUSTER_NAME node $nodenum"); ! open(SLONIK, "|@@PGBINDIR@@/slonik"); ! print SLONIK genheader(); ! print SLONIK "restart node $node\n"; ! close SLONIK; } ! if ($restart eq "YES") { ! if ($pid) { ! log_to_watchdog_log("terminate slon daemon for $CLUSTER_NAME node $nodenum"); ! # Kill slon until dead... ! kill 2, $pid; ! sleep 3; ! kill 15, $pid; ! sleep 3; ! kill 9, $pid; ! } ! log_to_watchdog_log("restart slon for $nodenum"); ! start_slon($nodenum); ! } ! sleep $sleep; } sub log_to_watchdog_log { ! my ($message) = @_; ! chomp $message; ! my $date = `date`; ! chomp $date; ! open (SLONLOG, ">>$LOGDIR/slony-watchdog.log"); ! print SLONLOG $date, "|", $message, "\n"; ! close SLONLOG; } + + __END__ + + =head1 NAME + + slon_watchdog + + =head1 SYNOPSIS + + Usage: slon_watchdog node sleep-time + + =cut Index: tools/altperl/slonik_store_node.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slonik_store_node.pl,v retrieving revision 1.1 diff -c -r1.1 slonik_store_node.pl *** tools/altperl/slonik_store_node.pl 31 May 2005 16:11:05 -0000 1.1 --- tools/altperl/slonik_store_node.pl 15 Dec 2005 16:56:40 -0000 *************** *** 3,8 **** --- 3,9 ---- # Author: Steve Simms # Copyright 2005 PostgreSQL Global Development Group + use Pod::Usage; use Getopt::Long; # Defaults *************** *** 10,42 **** my $SHOW_USAGE = 0; # Read command-line options ! GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: store_node [--config file] node# ! ! Generates the slonik commands necessary to add a node to a ! cluster. Also displays a report showing the relationships between ! the various nodes. ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } ! ! require '@@PGLIBDIR@@/slon-tools.pm'; ! require $CONFIG_FILE; $node = $ARGV[0]; # Node can be passed either as "node1" or just "1" if ($node =~ /^(?:node)?(\d+)$/) { ! $node = $1; } else { ! die $USAGE; } my $FILE="/tmp/store_node.$$"; --- 11,30 ---- my $SHOW_USAGE = 0; # Read command-line options ! GetOptions( ! "config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE ! ); ! pod2usage(1) pod2usage(1) if $SHOW_USAGE; $node = $ARGV[0]; # Node can be passed either as "node1" or just "1" if ($node =~ /^(?:node)?(\d+)$/) { ! $node = $1; } else { ! pod2usage(1); } my $FILE="/tmp/store_node.$$"; *************** *** 62,81 **** foreach my $nodea (@NODES) { my $dsna = $DSN[$nodea]; foreach my $nodeb (@NODES) { ! if ($nodea != $nodeb) { ! next unless ($node == $nodea or $node == $nodeb); ! my $dsnb = $DSN[$nodeb]; ! my $providerba = $VIA[$nodea][$nodeb]; ! my $providerab = $VIA[$nodeb][$nodea]; ! if (!$printed[$nodea][$nodeb] and $providerab == $nodea) { ! print SLONIK " store path (server = $nodea, client = $nodeb, conninfo = '$dsna');\n"; ! $printed[$nodea][$nodeb] = "done"; ! } ! if (!$printed[$nodeb][$nodea] and $providerba == $nodea) { ! print SLONIK " store path (server = $nodeb, client = $nodea, conninfo = '$dsnb');\n"; ! $printed[$nodeb][$nodea] = "done"; ! } ! } } } --- 50,69 ---- foreach my $nodea (@NODES) { my $dsna = $DSN[$nodea]; foreach my $nodeb (@NODES) { ! if ($nodea != $nodeb) { ! next unless ($node == $nodea or $node == $nodeb); ! my $dsnb = $DSN[$nodeb]; ! my $providerba = $VIA[$nodea][$nodeb]; ! my $providerab = $VIA[$nodeb][$nodea]; ! if (!$printed[$nodea][$nodeb] and $providerab == $nodea) { ! print SLONIK " store path (server = $nodea, client = $nodeb, conninfo = '$dsna');\n"; ! $printed[$nodea][$nodeb] = "done"; ! } ! if (!$printed[$nodeb][$nodea] and $providerba == $nodea) { ! print SLONIK " store path (server = $nodeb, client = $nodea, conninfo = '$dsnb');\n"; ! $printed[$nodeb][$nodea] = "done"; ! } ! } } } *************** *** 84,96 **** foreach my $origin (@NODES) { my $dsna = $DSN[$origin]; foreach my $receiver (@NODES) { ! if ($origin != $receiver) { ! my $provider = $VIA[$origin][$receiver]; ! next unless ($node == $origin or ! $node == $receiver or ! $node == $provider); ! print SLONIK " store listen (origin = $origin, receiver = $receiver, provider = $provider);\n"; ! } } } print SLONIK " echo 'Replication nodes prepared';\n"; --- 72,84 ---- foreach my $origin (@NODES) { my $dsna = $DSN[$origin]; foreach my $receiver (@NODES) { ! if ($origin != $receiver) { ! my $provider = $VIA[$origin][$receiver]; ! next unless ($node == $origin or ! $node == $receiver or ! $node == $provider); ! print SLONIK " store listen (origin = $origin, receiver = $receiver, provider = $provider);\n"; ! } } } print SLONIK " echo 'Replication nodes prepared';\n"; *************** *** 100,233 **** report_on_paths(); sub generate_listen_paths { ! my $infinity = 10000000; # Initial costs are all infinite ! foreach my $node1 (@NODES) { ! foreach my $node2 (@NODES) { ! $COST[$node1][$node2] = $infinity; } - } ! # Initialize paths between parents and children, and based on them, ! # generate initial seeding of listener paths, @VIA ! foreach my $node1 (@NODES) { ! $COST[$node1][$node1] = 0; ! $VIA[$node1][$node1] = 0; ! foreach my $node2 (@NODES) { ! if ($node2 != $node1) { if ((not ($PARENT[$node1] or $PARENT[$node2])) or ! ($PARENT[$node1] and $PARENT[$node1] == $node2) or ! ($PARENT[$node2] and $PARENT[$node2] == $node1)) { ! $PATH[$node1][$node2] = 1; ! $PATH[$node2][$node1] = 1; ! # Set up a cost 1 path between them ! # Parent to child ! $COST[$node1][$node2] = 1; ! $VIA[$node1][$node2] = $node1; ! ! # Child to parent ! $COST[$node2][$node1] = 1; ! $VIA[$node2][$node1] = $node2; } ! } } - } ! # Now, update the listener paths... ! # 4 level nested iteration: ! # 1 while not done, do ! # 2 for each node, node1 ! # 3 for each node, node2, where node2 <> node1, where we don't ! # yet have a listener path ! # 4 for each node node3 (<> node1 or node2), ! # consider introducing the listener path: ! # node1 to node2 then node2 to node3 ! # In concept, it's an O(n^4) algorithm; since the number of nodes, n, ! # is not likely to get particularly large, it's not worth tuning ! # further. ! $didwork = "yes"; ! while ($didwork eq "yes") { ! $didwork = "no"; ! foreach my $node1 (@NODES) { ! foreach my $node3 (@NODES) { ! if (($VIA[$node3][$node1] == 0) && ($node3 != $node1)) { ! foreach my $node2 (@NODES) { ! if ($PATH[$node1][$node2] && ($VIA[$node2][$node3] != 0) && ($node2 != $node3) && ($node2 != $node1)) { ! # Consider introducing a path from n1 to n2 then n2 to n3 ! # as a cheaper alternative to going direct from n1 to n3 ! my $oldcost = $COST[$node3][$node1]; ! my $newcost = $COST[$node1][$node2] + $COST[$node2][$node3]; ! if ($newcost < $oldcost) { ! $didwork = "yes"; ! # So we go via node 2 ! $VIA[$node3][$node1] = $node2; ! $COST[$node3][$node1] = $newcost; ! ! $VIA[$node1][$node3] = $node2; ! $COST[$node1][$node3] = $newcost; ! } ! } ! } ! } ! } } - } } sub report_on_paths { ! print "# Configuration Summary:\n"; ! print "#\n"; ! print "# COST\n"; ! print "# "; ! foreach my $node2 (@NODES) { ! printf "| %3d ", $node2; ! } ! print "|\n# "; ! print ("-----+" x (scalar(@NODES) + 1)); ! print "\n"; ! foreach my $node1 (@NODES) { ! printf "# %3d ", $node1; foreach my $node2 (@NODES) { ! if ($COST[$node2][$node1] == $infinity) { ! printf "| inf "; ! } else { ! printf "|%4d ", $COST[$node2][$node1]; ! } ! } ! print "|\n"; ! } ! print "# \n"; ! print "# VIA\n"; ! print "# "; ! foreach my $node2 (@NODES) { ! printf "| %3d ", $node2; ! } ! print "|\n# "; ! print ("-----+" x (scalar(@NODES) + 1)); ! print "\n"; ! foreach my $node1 (@NODES) { ! printf "# %3d ", $node1; foreach my $node2 (@NODES) { ! printf "|%4d ", $VIA[$node2][$node1]; } - print "|\n"; - } ! print "# \n"; ! print "# PATHS\n"; ! print "# "; ! foreach my $node2 (@NODES) { ! printf "| %3d ", $node2; ! } ! print "|\n# "; ! print ("-----+" x (scalar(@NODES) + 1)); ! print "\n"; ! foreach my $node1 (@NODES) { ! printf "# %3d ", $node1; foreach my $node2 (@NODES) { ! printf "|%4d ", $PATH[$node2][$node1]; } ! print "|\n"; ! } ! print "\n"; } --- 88,239 ---- report_on_paths(); sub generate_listen_paths { ! my $infinity = 10000000; # Initial costs are all infinite ! foreach my $node1 (@NODES) { ! foreach my $node2 (@NODES) { ! $COST[$node1][$node2] = $infinity; ! } } ! # Initialize paths between parents and children, and based on them, ! # generate initial seeding of listener paths, @VIA ! foreach my $node1 (@NODES) { ! $COST[$node1][$node1] = 0; ! $VIA[$node1][$node1] = 0; ! foreach my $node2 (@NODES) { ! if ($node2 != $node1) { if ((not ($PARENT[$node1] or $PARENT[$node2])) or ! ($PARENT[$node1] and $PARENT[$node1] == $node2) or ! ($PARENT[$node2] and $PARENT[$node2] == $node1)) { ! $PATH[$node1][$node2] = 1; ! $PATH[$node2][$node1] = 1; ! # Set up a cost 1 path between them ! # Parent to child ! $COST[$node1][$node2] = 1; ! $VIA[$node1][$node2] = $node1; ! ! # Child to parent ! $COST[$node2][$node1] = 1; ! $VIA[$node2][$node1] = $node2; } ! } ! } } ! # Now, update the listener paths... ! # 4 level nested iteration: ! # 1 while not done, do ! # 2 for each node, node1 ! # 3 for each node, node2, where node2 <> node1, where we don't ! # yet have a listener path ! # 4 for each node node3 (<> node1 or node2), ! # consider introducing the listener path: ! # node1 to node2 then node2 to node3 ! # In concept, it's an O(n^4) algorithm; since the number of nodes, n, ! # is not likely to get particularly large, it's not worth tuning ! # further. ! $didwork = "yes"; ! while ($didwork eq "yes") { ! $didwork = "no"; ! foreach my $node1 (@NODES) { ! foreach my $node3 (@NODES) { ! if (($VIA[$node3][$node1] == 0) && ($node3 != $node1)) { ! foreach my $node2 (@NODES) { ! if ($PATH[$node1][$node2] && ! ($VIA[$node2][$node3] != 0) && ! ($node2 != $node3) && ! ($node2 != $node1)) { ! # Consider introducing a path from n1 to n2 then n2 to n3 ! # as a cheaper alternative to going direct from n1 to n3 ! my $oldcost = $COST[$node3][$node1]; ! my $newcost = $COST[$node1][$node2] + $COST[$node2][$node3]; ! if ($newcost < $oldcost) { ! $didwork = "yes"; ! # So we go via node 2 ! $VIA[$node3][$node1] = $node2; ! $COST[$node3][$node1] = $newcost; ! ! $VIA[$node1][$node3] = $node2; ! $COST[$node1][$node3] = $newcost; ! } ! } ! } ! } ! } ! } } } sub report_on_paths { ! print "# Configuration Summary:\n"; ! print "#\n"; ! print "# COST\n"; ! print "# "; foreach my $node2 (@NODES) { ! printf "| %3d ", $node2; ! } ! print "|\n# "; ! print ("-----+" x (scalar(@NODES) + 1)); ! print "\n"; ! foreach my $node1 (@NODES) { ! printf "# %3d ", $node1; ! foreach my $node2 (@NODES) { ! if ($COST[$node2][$node1] == $infinity) { ! printf "| inf "; ! } else { ! printf "|%4d ", $COST[$node2][$node1]; ! } ! } ! print "|\n"; ! } ! print "# \n"; ! print "# VIA\n"; ! print "# "; foreach my $node2 (@NODES) { ! printf "| %3d ", $node2; ! } ! print "|\n# "; ! print ("-----+" x (scalar(@NODES) + 1)); ! print "\n"; ! foreach my $node1 (@NODES) { ! printf "# %3d ", $node1; ! foreach my $node2 (@NODES) { ! printf "|%4d ", $VIA[$node2][$node1]; ! } ! print "|\n"; } ! print "# \n"; ! print "# PATHS\n"; ! print "# "; foreach my $node2 (@NODES) { ! printf "| %3d ", $node2; ! } ! print "|\n# "; ! print ("-----+" x (scalar(@NODES) + 1)); ! print "\n"; ! foreach my $node1 (@NODES) { ! printf "# %3d ", $node1; ! foreach my $node2 (@NODES) { ! printf "|%4d ", $PATH[$node2][$node1]; ! } ! print "|\n"; } ! print "\n"; } + __END__ + + =head1 NAME + + slonik_store_node.pl + + =head1 SYNOPSIS + + Usage: store_node [--config file] node# + + =head1 OPTIONS + + Generates the slonik commands necessary to add a node to a + cluster. Also displays a report showing the relationships between + the various nodes. Index: tools/altperl/slonik_subscribe_set.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slonik_subscribe_set.pl,v retrieving revision 1.1 diff -c -r1.1 slonik_subscribe_set.pl *** tools/altperl/slonik_subscribe_set.pl 31 May 2005 16:11:05 -0000 1.1 --- tools/altperl/slonik_subscribe_set.pl 15 Dec 2005 16:56:40 -0000 *************** *** 3,8 **** --- 3,9 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults *************** *** 11,46 **** # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: subscribe_set [--config file] set# node# ! ! Begins replicating a set to the specified node. ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; my ($set, $node) = @ARGV; if ($node =~ /^(?:node)?(\d+)$/) { ! $node = $1; } else { ! print "Need to specify node!\n"; ! die $USAGE; } if ($set =~ /^(?:set)?(\d+)$/) { ! $set = $1; } else { ! print "Need to specify set!\n"; ! die $USAGE; } get_set($set) or die "Non-existent set specified.\n"; --- 12,37 ---- # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if $SHOW_USAGE; require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; my ($set, $node) = @ARGV; if ($node =~ /^(?:node)?(\d+)$/) { ! $node = $1; } else { ! print "Need to specify node!\n"; ! pod2usage(1); } if ($set =~ /^(?:set)?(\d+)$/) { ! $set = $1; } else { ! print "Need to specify set!\n"; ! pod2usage(1); } get_set($set) or die "Non-existent set specified.\n"; *************** *** 51,69 **** print SLONIK " try {\n"; if ($DSN[$node]) { ! my $provider = $SET_ORIGIN; ! my $forward; ! if ($PARENT[$node]) { ! $provider = $PARENT[$node]; ! } ! if ($NOFORWARD[$node] eq "yes") { ! $forward = "no"; ! } else { ! $forward = "yes"; ! } ! print SLONIK " subscribe set (id = $set, provider = $provider, receiver = $node, forward = $forward);\n"; } else { ! die "Node $node not found\n"; } print SLONIK " }\n"; --- 42,60 ---- print SLONIK " try {\n"; if ($DSN[$node]) { ! my $provider = $SET_ORIGIN; ! my $forward; ! if ($PARENT[$node]) { ! $provider = $PARENT[$node]; ! } ! if ($NOFORWARD[$node] eq "yes") { ! $forward = "no"; ! } else { ! $forward = "yes"; ! } ! print SLONIK " subscribe set (id = $set, provider = $provider, receiver = $node, forward = $forward);\n"; } else { ! die "Node $node not found\n"; } print SLONIK " }\n"; *************** *** 73,75 **** --- 64,78 ---- print SLONIK " echo 'Subscribed nodes to set $set';\n"; close SLONIK; run_slonik_script($FILE); + __END__ + =head1 NAME + + slonik_subscribe_set.pl + + =head1 SYNOPSIS + + Usage: subscribe_set [--config file] set# node# + + Begins replicating a set to the specified node. + + =cut Index: tools/altperl/slonik_uninstall_nodes.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slonik_uninstall_nodes.pl,v retrieving revision 1.1 diff -c -r1.1 slonik_uninstall_nodes.pl *** tools/altperl/slonik_uninstall_nodes.pl 31 May 2005 16:11:05 -0000 1.1 --- tools/altperl/slonik_uninstall_nodes.pl 15 Dec 2005 16:56:40 -0000 *************** *** 3,8 **** --- 3,9 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults *************** *** 11,29 **** # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: uninstall_nodes [--config file] ! ! Removes Slony configuration from all nodes in a cluster. ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; --- 12,20 ---- # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if $SHOW_USAGE; require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; *************** *** 38,40 **** --- 29,44 ---- print SLONIK " uninstall node (id=$MASTERNODE);\n"; close SLONIK; run_slonik_script($FILE); + + __END__ + =head1 NAME + + slonik_uninstall_nodes + + =head1 SYNOPSIS + + Usage: uninstall_nodes [--config file] + + Removes Slony configuration from all nodes in a cluster. + + =cut Index: tools/altperl/slonik_unsubscribe_set.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slonik_unsubscribe_set.pl,v retrieving revision 1.1 diff -c -r1.1 slonik_unsubscribe_set.pl *** tools/altperl/slonik_unsubscribe_set.pl 31 May 2005 16:11:05 -0000 1.1 --- tools/altperl/slonik_unsubscribe_set.pl 15 Dec 2005 16:56:40 -0000 *************** *** 3,8 **** --- 3,9 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults *************** *** 11,57 **** # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: unsubscribe_set [--config file] set# node# ! ! Stops replicating a set on the specified node. ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; my ($set, $node) = @ARGV; if ($node =~ /^(?:node)?(\d+)$/) { ! $node = $1; } else { ! print "Need to specify node!\n\n"; ! die $USAGE; } if ($set =~ /^(?:set)?(\d+)$/) { ! $set = $1; } else { ! print "Need to specify set!\n\n"; ! die $USAGE; } open(SLONIK, ">", "/tmp/slonik-unsubscribe.$$"); print SLONIK genheader(); ! print SLONIK " try {\n"; ! print SLONIK " unsubscribe set (id = $set, receiver = $node);\n"; ! print SLONIK " }\n"; ! print SLONIK " on error {\n"; ! print SLONIK " echo 'Failed to unsubscribe node $node from set $set';\n"; ! print SLONIK " exit 1;\n"; ! print SLONIK " }\n"; ! print SLONIK " echo 'unsubscribed node $node from set $set';\n"; close SLONIK; run_slonik_script("/tmp/slonik-unsubscribe.$$"); --- 12,65 ---- # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if $SHOW_USAGE; require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; my ($set, $node) = @ARGV; if ($node =~ /^(?:node)?(\d+)$/) { ! $node = $1; } else { ! print "Need to specify node!\n\n"; ! pod2usage(1); } if ($set =~ /^(?:set)?(\d+)$/) { ! $set = $1; } else { ! print "Need to specify set!\n\n"; ! pod2usage(1); } open(SLONIK, ">", "/tmp/slonik-unsubscribe.$$"); print SLONIK genheader(); ! print SLONIK <<END; ! try { ! unsubscribe set (id = $set, receiver = $node); ! } ! on error { ! echo 'Failed to unsubscribe node $node from set $set'; ! exit 1; ! } ! echo 'unsubscribed node $node from set $set'; ! END ! close SLONIK; + run_slonik_script("/tmp/slonik-unsubscribe.$$"); + __END__ + + =head1 NAME + + unsubscribe_set + + =head1 SYNOPSIS + + Usage: unsubscribe_set [--config file] set# node# + + Stops replicating a set on the specified node. + + =cut Index: tools/altperl/slonik_update_nodes.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slonik_update_nodes.pl,v retrieving revision 1.1 diff -c -r1.1 slonik_update_nodes.pl *** tools/altperl/slonik_update_nodes.pl 31 May 2005 16:11:05 -0000 1.1 --- tools/altperl/slonik_update_nodes.pl 15 Dec 2005 16:56:40 -0000 *************** *** 3,29 **** # Author: Christopher Browne # Copyright 2004 Afilias Canada use Getopt::Long; # Defaults ! $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; ! $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: update_nodes [--config file] ! ! Updates the functions on all nodes. ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; --- 3,20 ---- # Author: Christopher Browne # Copyright 2004 Afilias Canada + use Pod::Usage; use Getopt::Long; # Defaults ! my $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; ! my $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if $SHOW_USAGE; require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; *************** *** 31,37 **** open(SLONIK, ">", "/tmp/update_nodes.$$"); print SLONIK genheader(); foreach my $node (@NODES) { ! print SLONIK " update functions (id = $node);\n"; }; close SLONIK; run_slonik_script("/tmp/update_nodes.$$"); --- 22,41 ---- open(SLONIK, ">", "/tmp/update_nodes.$$"); print SLONIK genheader(); foreach my $node (@NODES) { ! print SLONIK " update functions (id = $node);\n"; }; close SLONIK; run_slonik_script("/tmp/update_nodes.$$"); + __END__ + + =head1 NAME + + update_nodes + + =head1 SYNOPSIS + + Usage: update_nodes [--config file] + + Updates the functions on all nodes. + + =cut Index: tools/altperl/slony_show_configuration.pl =================================================================== RCS file: /usr/local/cvsroot/slony1/slony1-engine/tools/altperl/slony_show_configuration.pl,v retrieving revision 1.1 diff -c -r1.1 slony_show_configuration.pl *** tools/altperl/slony_show_configuration.pl 31 May 2005 16:11:05 -0000 1.1 --- tools/altperl/slony_show_configuration.pl 15 Dec 2005 16:56:40 -0000 *************** *** 6,56 **** # This script simply displays an overview of node configuration # for a given SLONY node set use Getopt::Long; # Defaults ! $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; ! $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help" => \$SHOW_USAGE); ! my $USAGE = ! "Usage: show_configuration [--config file] ! ! "; ! ! if ($SHOW_USAGE) { ! print $USAGE; ! exit 0; ! } require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; print "Slony Configuration\n-------------------------------------\n"; if ($ENV{"SLONYNODES"}) { ! print "With node configuration from ", $ENV{"SLONYNODES"}, "\n"; } if ($ENV{"SLONYSET"}) { ! print "With set configuration from ", $ENV{"SLONYSET"}, "\n"; } ! print qq{ Slony-I Cluster: $CLUSTER_NAME Logs stored under $LOGDIR Slony Binaries in: @@PGBINDIR@@ ! }; if ($APACHE_ROTATOR) { print "Rotating logs using Apache Rotator: $APACHE_ROTATOR\n"; } ! print qq{ Node information -------------------------------- ! }; foreach $node (@NODES) { printf("Node: %2d Host: %15s User: %8s Port: %4d Forwarding? %4s Parent: %2d Database: %10s\n DSN: %s\n", $node, $HOST[$node], $USER[$node], $PORT[$node], $NOFORWARD[$node], $PARENT[$node], $DBNAME[$node], $DSN[$node]); } --- 6,62 ---- # This script simply displays an overview of node configuration # for a given SLONY node set + use Pod::Usage; use Getopt::Long; # Defaults ! my $CONFIG_FILE = '@@SYSCONFDIR@@/slon_tools.conf'; ! my $SHOW_USAGE = 0; # Read command-line options GetOptions("config=s" => \$CONFIG_FILE, ! "help|?" => \$SHOW_USAGE); ! pod2usage(1) if $SHOW_USAGE; require '@@PGLIBDIR@@/slon-tools.pm'; require $CONFIG_FILE; print "Slony Configuration\n-------------------------------------\n"; if ($ENV{"SLONYNODES"}) { ! print "With node configuration from ", $ENV{"SLONYNODES"}, "\n"; } if ($ENV{"SLONYSET"}) { ! print "With set configuration from ", $ENV{"SLONYSET"}, "\n"; } ! print <<END; Slony-I Cluster: $CLUSTER_NAME Logs stored under $LOGDIR Slony Binaries in: @@PGBINDIR@@ ! ! END if ($APACHE_ROTATOR) { print "Rotating logs using Apache Rotator: $APACHE_ROTATOR\n"; } ! print <<END; Node information -------------------------------- ! ! END foreach $node (@NODES) { printf("Node: %2d Host: %15s User: %8s Port: %4d Forwarding? %4s Parent: %2d Database: %10s\n DSN: %s\n", $node, $HOST[$node], $USER[$node], $PORT[$node], $NOFORWARD[$node], $PARENT[$node], $DBNAME[$node], $DSN[$node]); } + __END__ + + =head1 NAME + + show_configuration + + =head1 SYNOPSIS + + Usage: show_configuration [--config file] + + =cut
- Previous message: [Slony1-general] Slony 1.1.5 RC packaging issues
- Next message: [Slony1-general] japanese translation of slony manual
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Slony1-general mailing list