[check_postgres] New action: warm_standby

david.barbion at adeoservices.com david.barbion at adeoservices.com
Wed Jun 29 07:50:38 UTC 2011



Le 28/06/2011 19:33, Greg Sabino Mullane a écrit :
> On Tue, Jun 28, 2011 at 03:29:05PM +0200, david.barbion at adeoservices.com wrote:
>> Hello,
>>
>> I've created a small patch for check_postgres.pl that adds a new action:
>> warm_standby.
>> This action checks that the process pg_standby is running for the
>> current cluster (depending on the PGPORT env var.).
>> This patch needs the perl module Proc::ProcessTable available at CPAN.
> Thanks! Quick thoughts:
>
> Obviously we'll need a require not a 'use' for the module
> (see for example, the way we handle Date::Parse). I'm not sure about
> the name: we are really checking for a pg_standby process, so
> the "warm_standby" check is indirect.
>
> I'm wondering how this is better than the existing check that scans
> pg_controldata? Also compare with the check_standby_mode() argument...
>
Here is my new patch.
This one takes care of the database cluster state (got from 
pg_controldata in check_standby_mode()).

--- a/check_postgres.pl
+++ b/check_postgres.pl
@@ -946,6 +946,7 @@ our $action_info = {
   new_version_cp      => [0, 'Checks if a newer version of 
check_postgres.pl is available.'],
   new_version_pg      => [0, 'Checks if a newer version of Postgres is 
available.'],
   new_version_tnm     => [0, 'Checks if a newer version of tail_n_mail 
is available.'],
+ pg_standby          => [1, 'Check that postgresql is started in warm 
standby mode (pg_standby process)'],
   pgb_pool_cl_active  => [1, 'Check the number of active clients in 
each pgbouncer pool.'],
   pgb_pool_cl_waiting => [1, 'Check the number of waiting clients in 
each pgbouncer pool.'],
   pgb_pool_sv_active  => [1, 'Check the number of active server 
connections in each pgbouncer pool.'],
@@ -1573,6 +1574,9 @@ check_bloat() if $action eq 'bloat';
  ## Simple connection, warning or critical options
  check_connection() if $action eq 'connection';

+## Check pg_standby process
+check_pg_standby() if $action eq 'pg_standby' ;
+
  ## Check the commitratio of one or more databases
  check_commitratio() if $action eq 'commitratio';

@@ -3559,6 +3563,107 @@ sub check_connection {
  } ## end of check_connection


+sub is_parent_process {
+
+       ## Check that a given PID is the child of another PID
+       ## @arg1: current process table
+       ## @arg2: pid of the parent process
+       ## @arg3: pid of the children process
+
+    my $process_table_ref = shift ;
+    my @process_table = @$process_table_ref ;
+    my $parent_pid = shift ;
+    my $child_pid = shift ;
+
+   return(0) if($child_pid == 1) ;
+
+    foreach my $p ( @process_table){
+        if ( $p->pid == $child_pid) {
+            # found !
+            if ($p->ppid == $parent_pid) {
+                return(1) ;
+            }else {
+                if (is_parent_process(\@process_table, $parent_pid, 
$p->ppid) == 1) {
+            return(1) ;
+                }
+            }
+        }
+    }
+    return(0) ;
+} ## end of is_parent_process
+
+sub check_pg_standby {
+
+    ## Check that postgresql is started in warm standby mode
+    ## Look at the process table for pg_standby command
+    ## No comparisons made: warning and critical are not allowed
+    ## Suports: Nagios, MRTG
+
+    my $postmaster_pid = 0;
+    my $pg_standby_pid = 0;
+    my $found = 0 ;
+
+    if ($opt{warning} or $opt{critical}) {
+        ndie msg('range-none');
+    }
+
+    # compute $STANDBY value from pg_controldata output
+    check_standby_mode() ;
+
+    # first check that the cluster is running in standby mode
+    if (!$STANDBY) {
+               add_critical "cluster not in standby mode" ;
+               return;
+       }
+
+    # get current cluster port or default
+    my $port = $ENV{PGPORT} ;
+    $port = $opt{defaultport} if (!$port) ;
+
+    # This function needs the perl module Proc::ProcessTable
+    eval {
+        require Proc::ProcessTable;
+        import DProc::ProcessTable;
+    };
+
+    # retrieve complete process table
+    my $t = new Proc::ProcessTable;
+
+    # First, look for the postmaster process at the specified PGPORT
+    foreach my $p ( @{$t->table} ){
+        if ( $p->cmndline =~ /postmaster.*$port/) {
+            # postmaster process found!
+            $postmaster_pid = $p->pid ;
+        }
+    }
+    if ($postmaster_pid == 0) {
+        add_critical "Postmaster PID not found for port $port" ;
+        return ;
+    }
+
+    # Then, look for the pg_standby
+    foreach my $p ( @{$t->table} ){
+        if ( $p->cmndline =~ /pg_standby/) {
+            # found !
+            $pg_standby_pid = $p->pid ;
+            if (is_parent_process(\@{$t->table}, $postmaster_pid, 
$pg_standby_pid) == 1) {
+        # pg_standby running
+        $found = $pg_standby_pid ;
+        }
+        }
+    }
+    if (!$found) {
+        add_critical "pg_standby not running" ;
+    }else {
+        add_ok "pg_standby($found) running" ;
+    }
+
+    return;
+
+} ## end of check_pg_standby
+
+
+
  sub check_custom_query {

      ## Run a user-supplied query, then parse the results


Ce message et toutes les pièces jointes sont établis à l'attention exclusive de leurs destinataires et sont confidentiels. Si vous recevez ce message par erreur, merci de le détruire et d'en avertir immédiatement l'expéditeur. L'internet ne permettant pas d'assurer l'intégrité de ce message, le contenu de ce message ne représente en aucun cas un engagement de la part de Adeo Services.


More information about the Check_postgres mailing list