From c7a68db8670965d110468e2f2696e60c209c0393 Mon Sep 17 00:00:00 2001 From: glyn Date: Wed, 22 Oct 2014 14:17:15 +0100 Subject: [PATCH] A couple of minor changes: - Added extra configuration parameter 'only_follow_origins' to only repoint pgbouncer configuration if the origin of the monitored sets changes, which is what we usually want. - Only write cluster status information file when cluster status has actually changed. --- README.md | 1 + pgbouncer_follower.pl | 39 +++++++++++++++++++++++++++----------- pgbouncer_follower_rw.conf | 8 ++++++-- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 0b0fee1..33cabba 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ $ sudo invoke-rc.d pgbouncer_follower_rw start | 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 diff --git a/pgbouncer_follower.pl b/pgbouncer_follower.pl index fefe45e..0b88b19 100755 --- a/pgbouncer_follower.pl +++ b/pgbouncer_follower.pl @@ -58,12 +58,17 @@ my ($year, $month, $day, $hour, $min, $sec); 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'"); @@ -235,7 +240,9 @@ sub generateConfig { } 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/; } @@ -270,9 +277,11 @@ sub checkCluster { 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')); + } } } @@ -286,15 +295,20 @@ sub checkCluster { } } - 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; } @@ -456,6 +470,9 @@ sub getConfig { when(/\bpool_all_databases\b/i) { $g_all_databases = checkBoolean($value); } + when(/\bonly_follow_origins\b/i) { + $g_origins_only = checkBoolean($value); + } } } } diff --git a/pgbouncer_follower_rw.conf b/pgbouncer_follower_rw.conf index f0f0d8f..e780cac 100755 --- a/pgbouncer_follower_rw.conf +++ b/pgbouncer_follower_rw.conf @@ -16,11 +16,15 @@ server_conninfo=dbname=TEST host=localhost port=5435 #------------------------------------------------------------------------------ # 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 @@ -34,7 +38,7 @@ log_file=/var/slony/pgbouncer_follower/pgbouncer_follower_%mode.log 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 -- 2.39.5