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 [EMAIL PROTECTED] http://fetter.org/
phone: +1 415 235 3778
Remember to vote!
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
_______________________________________________
Slony1-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/slony1-general