Commit e7010ce4 authored by Peter Eisentraut's avatar Peter Eisentraut

pg_ctl: Add wait option to promote action

When waiting is selected for the promote action, look into pg_control
until the state changes, then use the PQping-based waiting until the
server is reachable.
Reviewed-by: default avatarMichael Paquier <michael.paquier@gmail.com>
parent ebdf5bf7
...@@ -91,6 +91,8 @@ PostgreSQL documentation ...@@ -91,6 +91,8 @@ PostgreSQL documentation
<cmdsynopsis> <cmdsynopsis>
<command>pg_ctl</command> <command>pg_ctl</command>
<arg choice="plain"><option>promote</option></arg> <arg choice="plain"><option>promote</option></arg>
<arg choice="opt"><option>-w</option></arg>
<arg choice="opt"><option>-t</option> <replaceable>seconds</replaceable></arg>
<arg choice="opt"><option>-s</option></arg> <arg choice="opt"><option>-s</option></arg>
<arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg> <arg choice="opt"><option>-D</option> <replaceable>datadir</replaceable></arg>
</cmdsynopsis> </cmdsynopsis>
...@@ -361,8 +363,8 @@ PostgreSQL documentation ...@@ -361,8 +363,8 @@ PostgreSQL documentation
<term><option>--timeout</option></term> <term><option>--timeout</option></term>
<listitem> <listitem>
<para> <para>
The maximum number of seconds to wait when waiting for startup or The maximum number of seconds to wait when waiting for an operation
shutdown to complete. Defaults to the value of the to complete (see option <option>-w</option>). Defaults to the value of the
<envar>PGCTLTIMEOUT</> environment variable or, if not set, to 60 <envar>PGCTLTIMEOUT</> environment variable or, if not set, to 60
seconds. seconds.
</para> </para>
...@@ -383,8 +385,23 @@ PostgreSQL documentation ...@@ -383,8 +385,23 @@ PostgreSQL documentation
<term><option>-w</option></term> <term><option>-w</option></term>
<listitem> <listitem>
<para> <para>
Wait for the startup or shutdown to complete. Wait for an operation to complete. This is supported for the
Waiting is the default option for shutdowns, but not startups. modes <literal>start</literal>, <literal>stop</literal>,
<literal>restart</literal>, <literal>promote</literal>,
and <literal>register</literal>.
</para>
<para>
Waiting is the default option for shutdowns, but not startups,
restarts, or promotions. This is mainly for historical reasons; the
waiting option is almost always preferable. If waiting is not
selected, the requested action is triggered, but there is no feedback
about its success. In that case, the server log file or an external
monitoring system would have to be used to check the progress and
success of the operation.
</para>
<para>
When waiting for startup, <command>pg_ctl</command> repeatedly When waiting for startup, <command>pg_ctl</command> repeatedly
attempts to connect to the server. attempts to connect to the server.
When waiting for shutdown, <command>pg_ctl</command> waits for When waiting for shutdown, <command>pg_ctl</command> waits for
...@@ -400,8 +417,8 @@ PostgreSQL documentation ...@@ -400,8 +417,8 @@ PostgreSQL documentation
<term><option>-W</option></term> <term><option>-W</option></term>
<listitem> <listitem>
<para> <para>
Do not wait for startup or shutdown to complete. This is the Do not wait for an operation to complete. This is the opposite of the
default for start and restart modes. option <option>-w</option>.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
......
...@@ -1228,7 +1228,34 @@ do_promote(void) ...@@ -1228,7 +1228,34 @@ do_promote(void)
exit(1); exit(1);
} }
print_msg(_("server promoting\n")); if (do_wait)
{
DBState state = DB_STARTUP;
print_msg(_("waiting for server to promote..."));
while (wait_seconds > 0)
{
state = get_control_dbstate();
if (state == DB_IN_PRODUCTION)
break;
print_msg(".");
pg_usleep(1000000); /* 1 sec */
wait_seconds--;
}
if (state == DB_IN_PRODUCTION)
{
print_msg(_(" done\n"));
print_msg(_("server promoted\n"));
}
else
{
print_msg(_(" stopped waiting\n"));
print_msg(_("server is still promoting\n"));
}
}
else
print_msg(_("server promoting\n"));
} }
...@@ -2405,18 +2432,10 @@ main(int argc, char **argv) ...@@ -2405,18 +2432,10 @@ main(int argc, char **argv)
if (!wait_set) if (!wait_set)
{ {
switch (ctl_command) if (ctl_command == STOP_COMMAND)
{ do_wait = true;
case RESTART_COMMAND: else
case START_COMMAND: do_wait = false;
do_wait = false;
break;
case STOP_COMMAND:
do_wait = true;
break;
default:
break;
}
} }
if (ctl_command == RELOAD_COMMAND) if (ctl_command == RELOAD_COMMAND)
......
...@@ -3,7 +3,7 @@ use warnings; ...@@ -3,7 +3,7 @@ use warnings;
use PostgresNode; use PostgresNode;
use TestLib; use TestLib;
use Test::More tests => 9; use Test::More tests => 12;
my $tempdir = TestLib::tempdir; my $tempdir = TestLib::tempdir;
...@@ -37,3 +37,19 @@ command_ok([ 'pg_ctl', '-D', $node_standby->data_dir, 'promote' ], ...@@ -37,3 +37,19 @@ command_ok([ 'pg_ctl', '-D', $node_standby->data_dir, 'promote' ],
ok($node_standby->poll_query_until('postgres', 'SELECT NOT pg_is_in_recovery()'), ok($node_standby->poll_query_until('postgres', 'SELECT NOT pg_is_in_recovery()'),
'promoted standby is not in recovery'); 'promoted standby is not in recovery');
# same again with wait option
$node_standby = get_new_node('standby2');
$node_standby->init_from_backup($node_primary, 'my_backup', has_streaming => 1);
$node_standby->start;
is($node_standby->safe_psql('postgres', 'SELECT pg_is_in_recovery()'),
't', 'standby is in recovery');
command_ok([ 'pg_ctl', '-D', $node_standby->data_dir, '-w', 'promote' ],
'pg_ctl -w promote of standby runs');
# no wait here
is($node_standby->safe_psql('postgres', 'SELECT pg_is_in_recovery()'),
'f', 'promoted standby is not in recovery');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment