| pgBouncer | sets_to_follow | text | *1* | Comma separated list of sets to follow or 'all' to follow all sets
| pgBouncer | pool_mode | 'ro/rw' | *'rw'* | Select a read-only subscriber or the origin for read-write
| pgBouncer | pool_all_databases | boolean | *'false'* | If true uses wildcard for database name in pgbouncer.ini, false uses slony database
+| pgBouncer | only_follow_origins | boolean | *'false'* | If true pgbouncer will only be reconfigured and reloaded when sets move origin
| pgBouncer | status_file | text | *'/tmp/pgbouncer_follower_%mode.status'* | File used to store a hash depicting the state of the cluster
| pgBouncer | log_file | text | *'/tmp/pgbouncer_follower_%mode.log'* | Log file for the script
| pgBouncer | pid_file | text | *'/tmp/pgbouncer_follower_%mode.log'* | PID file for the script when run as a daemon
my $change_time;
my $g_host = hostname;
my ($g_addr)=inet_ntoa((gethostbyname(hostname))[4]);
+my $g_origins_only = false;
die $g_usage unless GetOptions(\%opt, 'config_file|f=s', 'daemon|D',) and keys %opt and ! @ARGV;
unless (getConfig($opt{config_file})){
print ("There was a problem reading the configuration.\n");
}
+if (!defined($g_status_file)) {
+ $g_status_file = "/tmp/$g_clname.status";
+}
+
if ($g_debug) {
printLogLn($g_logfile, "DEBUG: Logging to my '$g_logfile'");
}
if (defined($target_host)) {
$_ = "# Configuration for " . ($target_is_origin ? "origin" : "subscriber") . " of sets $target_sets node #$target_node_id $target_host:$target_port\n" . $_;
- printLogLn ($g_logfile, "DEBUG: Configuration for " . ($target_is_origin ? "origin" : "subscriber") . " of sets $target_sets node #$target_node_id $target_host:$target_port");
+ if ($g_debug) {
+ printLogLn ($g_logfile, "DEBUG: Configuration for " . ($target_is_origin ? "origin" : "subscriber") . " of sets $target_sets node #$target_node_id $target_host:$target_port");
+ }
if ($all_databases) {
$_ =~ s/(\[databases\])/$1\n\* = host=$target_host port=$target_port/;
}
my $current_cluster;
my $previous_cluster;
foreach (@g_cluster) {
- $current_cluster = md5_hex(($current_cluster // "") . $_->[0] . $_->[2] . (defined($_->[3]) ? 't' : 'f'));
- if ($g_debug) {
- printLogLn($g_logfile, "DEBUG: Node " . $_->[0] . " detail = " . $_->[2] . (defined($_->[3]) ? 't' : 'f'));
+ if (!$g_origins_only || defined($_->[3])) {
+ $current_cluster = md5_hex(($current_cluster // "") . $_->[0] . $_->[2] . (defined($_->[3]) ? 't' : 'f'));
+ if ($g_debug) {
+ printLogLn($g_logfile, "DEBUG: Node " . $_->[0] . " detail = " . $_->[2] . (defined($_->[3]) ? 't' : 'f'));
+ }
}
}
}
}
- if (open(CLUSTERFILE, ">", $infile)) {
- print CLUSTERFILE $current_cluster;
- close(CLUSTERFILE);
- }
- else {
- printLogLn ($g_logfile, "ERROR: Can't open file $infile for writing");
+ unless (-f $infile && ($current_cluster eq $previous_cluster)) {
+ if ($g_debug) {
+ printLogLn($g_logfile, "DEBUG: Writing to status file");
+ }
+ if (open(CLUSTERFILE, ">", $infile)) {
+ print CLUSTERFILE $current_cluster;
+ close(CLUSTERFILE);
+ }
+ else {
+ printLogLn ($g_logfile, "ERROR: Can't open file $infile for writing");
+ }
}
- if ((($previous_cluster // "")ne "") && (($current_cluster // "") ne "") && ($current_cluster ne $previous_cluster)){
+ if ((($previous_cluster // "") ne "") && (($current_cluster // "") ne "") && ($current_cluster ne $previous_cluster)){
$changed = true;
}
when(/\bpool_all_databases\b/i) {
$g_all_databases = checkBoolean($value);
}
+ when(/\bonly_follow_origins\b/i) {
+ $g_origins_only = checkBoolean($value);
+ }
}
}
}
#------------------------------------------------------------------------------
# PgBouncer follower information
#------------------------------------------------------------------------------
-debug = true
+debug = false
follower_poll_interval=5000 # Cluster state poll interval (milliseconds)
slony_sets_to_follow=all # Comma separated list of set id's to follow E.g. "1,2,3,4" or "all"
+only_follow_origins=true # If true pgbouncer will only be reconfigured and reloaded
+ # when the origin of a set moves. If false any changes to origins,
+ # providers or subscribers will initiate a reconfigure and reload.
+
pool_mode=rw # Values are rw/ro. "rw" follows the origin node
# whereas "ro" will follow a subscriber of the sets
# specified in slony_sets_to_follow
pid_file=/var/run/pgbouncer_follower_%mode.pid # Pidfile for poll mode
pool_conf_template=/etc/pgbouncer/pgbouncer_%mode.template # Template configuration file
pool_conf_target=/etc/pgbouncer/pgbouncer_%mode.ini # Target configuration file to be modified
-pool_reload_command=invoke-rc.d pgbouncer_%mode reload # Command used to action configuration changes
+pool_reload_command=/etc/init.d/pgbouncer_%mode reload # Command used to action configuration changes
# Sepcial values for status_file, log_file, pool_conf_template
# pool_conf_target and pool_reload_command parameters:
# %mode - Pool Mode