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
<cmdsynopsis>
<command>pg_ctl</command>
<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>-D</option> <replaceable>datadir</replaceable></arg>
</cmdsynopsis>
......@@ -361,8 +363,8 @@ PostgreSQL documentation
<term><option>--timeout</option></term>
<listitem>
<para>
The maximum number of seconds to wait when waiting for startup or
shutdown to complete. Defaults to the value of the
The maximum number of seconds to wait when waiting for an operation
to complete (see option <option>-w</option>). Defaults to the value of the
<envar>PGCTLTIMEOUT</> environment variable or, if not set, to 60
seconds.
</para>
......@@ -383,8 +385,23 @@ PostgreSQL documentation
<term><option>-w</option></term>
<listitem>
<para>
Wait for the startup or shutdown to complete.
Waiting is the default option for shutdowns, but not startups.
Wait for an operation to complete. This is supported for the
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
attempts to connect to the server.
When waiting for shutdown, <command>pg_ctl</command> waits for
......@@ -400,8 +417,8 @@ PostgreSQL documentation
<term><option>-W</option></term>
<listitem>
<para>
Do not wait for startup or shutdown to complete. This is the
default for start and restart modes.
Do not wait for an operation to complete. This is the opposite of the
option <option>-w</option>.
</para>
</listitem>
</varlistentry>
......
......@@ -1228,7 +1228,34 @@ do_promote(void)
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)
if (!wait_set)
{
switch (ctl_command)
{
case RESTART_COMMAND:
case START_COMMAND:
do_wait = false;
break;
case STOP_COMMAND:
do_wait = true;
break;
default:
break;
}
if (ctl_command == STOP_COMMAND)
do_wait = true;
else
do_wait = false;
}
if (ctl_command == RELOAD_COMMAND)
......
......@@ -3,7 +3,7 @@ use warnings;
use PostgresNode;
use TestLib;
use Test::More tests => 9;
use Test::More tests => 12;
my $tempdir = TestLib::tempdir;
......@@ -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()'),
'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