diff --git a/script/pgsqlms b/script/pgsqlms index 5ddd67a..889580c 100755 --- a/script/pgsqlms +++ b/script/pgsqlms @@ -46,6 +46,8 @@ my %OCF_NOTIFY_ENV = ocf_notify_env() if $__OCF_ACTION eq 'notify'; # Default parameters values my $system_user_default = "postgres"; +my $monitor_user_default = ""; +my $monitor_password_default = ""; my $bindir_default = "/usr/bin"; my $pgdata_default = "/var/lib/pgsql/data"; my $pghost_default = "/tmp"; @@ -55,6 +57,8 @@ my $maxlag_default = "0"; # Set default values if not found in environment my $system_user = $ENV{'OCF_RESKEY_system_user'} || $system_user_default; +my $monitor_user = $ENV{'OCF_RESKEY_monitor_user'} || $monitor_user_default; +my $monitor_password = $ENV{'OCF_RESKEY_monitor_password'} || $monitor_password_default; my $bindir = $ENV{'OCF_RESKEY_bindir'} || $bindir_default; my $pgdata = $ENV{'OCF_RESKEY_pgdata'} || $pgdata_default; my $datadir = $ENV{'OCF_RESKEY_datadir'} || $pgdata; @@ -95,6 +99,7 @@ my $PGVER_12 = 120000; # the result as second one. # sub _query { + my $user = shift if @_ == 3; my $query = shift; my $res = shift; my $connstr = "dbname=postgres"; @@ -107,6 +112,7 @@ sub _query { my $ans; my $pid; my $rc; + my @psql_args; unless ( defined $res and defined $query and $query ne '' ) { ocf_log( 'debug', '_query: wrong parameters!' ); @@ -135,9 +141,19 @@ sub _query { $pid = open(my $KID, "-|"); if ( $pid == 0 ) { # child - exec $PGPSQL, '--set', 'ON_ERROR_STOP=1', '-qXAtf', $tmpfile, - '-R', $RS, '-F', $FS, '--port', $pgport, '--host', $pghost, - $connstr; + # Build psql arguments + @psql_args = ('--set', 'ON_ERROR_STOP=1', '-qXAtf', $tmpfile, + '-R', $RS, '-F', $FS, '--port', $pgport, '--host', $pghost); + + # Add username and password for non-system user + if ( $user ) { + push @psql_args, '-U', $user; + $ENV{'PGPASSWORD'} = $monitor_password if $monitor_password ne ''; + } + + push @psql_args, $connstr; + + exec $PGPSQL, @psql_args; } # parent @@ -259,7 +275,7 @@ sub _get_lag_scores { ORDER BY priority DESC }; - $rc = _query( $query, \@rs ); + $rc = _query( $monitor_user, $query, \@rs ); if ( $rc != 0 ) { ocf_exit_reason( 'Query to get standby locations failed (%d)', $rc ); @@ -898,7 +914,7 @@ sub _confirm_role { my $rc; my @rs; - $rc = _query( "SELECT pg_is_in_recovery()", \@rs ); + $rc = _query( $monitor_user, "SELECT pg_is_in_recovery()", \@rs ); $is_in_recovery = $rs[0][0]; @@ -1051,6 +1067,18 @@ The system owner of your instance's process (optional, string, default "postgres") +=item B + +PostgreSQL user for monitor operations + +(optional, string, default "") + +=item B + +PostgreSQL password for monitor user + +(optional, string, default "") + =item B B for PostgreSQL 11 and bellow. @@ -1118,6 +1146,22 @@ sub ocf_meta_data { + + + PostgreSQL user that pgsql RA will use for monitor operations + + PostgreSQL monitor User + + + + + + PostgreSQL password for monitor user + + PostgreSQL monitor Password + + + Path to the directory storing the PostgreSQL binaries. The agent @@ -1535,6 +1579,7 @@ sub pgsql_stop { my $rc; my $state; my $pidfile = "$datadir/postmaster.pid"; + my $pgisready_rc; # Add 60s to the timeout or use a 24h timeout fallback to make sure # Pacemaker will give up before us and take decisions my $timeout = ( _get_action_timeout() || 60*60*24 ) + 60; @@ -1548,9 +1593,22 @@ sub pgsql_stop { return $OCF_SUCCESS; } elsif ( $rc != $OCF_SUCCESS and $rc != $OCF_RUNNING_MASTER ) { - ocf_exit_reason( 'Unexpected state for instance "%s" (returned %d)', - $OCF_RESOURCE_INSTANCE, $rc ); - return $OCF_ERR_GENERIC; + ocf_log( 'debug', 'pgsql_stop: monitor failed (rc=%d), checking with pg_isready', $rc ); + + $pgisready_rc = _pg_isready(); + if ( $pgisready_rc == 0 or $pgisready_rc == 1 ) { + ocf_log( 'info', 'Instance "%s" is running (pg_isready=%d), proceeding with stop despite monitor failure', + $OCF_RESOURCE_INSTANCE, $pgisready_rc ); + } + elsif ( $pgisready_rc == 2 ) { + ocf_log( 'debug', 'pgsql_stop: pg_isready indicates instance is not listening' ); + return _confirm_stopped(); + } + else { + ocf_exit_reason( 'Unexpected state for instance "%s" (monitor returned %d, pg_isready returned %d)', + $OCF_RESOURCE_INSTANCE, $rc, $pgisready_rc ); + return $OCF_ERR_GENERIC; + } } #