pg_createsubscriber: Only --recovery-timeout controls the end of recovery process
authorPeter Eisentraut <[email protected]>
Mon, 17 Jun 2024 07:42:51 +0000 (09:42 +0200)
committerPeter Eisentraut <[email protected]>
Mon, 17 Jun 2024 07:42:51 +0000 (09:42 +0200)
It used to check if the target server is connected to the primary
server (send required WAL) to rapidly react when the process won't
succeed.  This code is not enough to guarantee that the recovery
process will complete.  There is a window between the walreceiver
shutdown and the pg_is_in_recovery() returns false that can reach
NUM_CONN_ATTEMPTS attempts and fails.

Instead, rely only on the --recovery-timeout option to give up the
process after the specified number of seconds.

This should help with buildfarm failures on slow machines.

Author: Euler Taveira <[email protected]>
Reviewed-by: Hayato Kuroda <[email protected]>
Discussion: https://www.postgresql.org/message-id/776c5cac-5ef5-4001-b1bc-5b698bc0c62a%40app.fastmail.com

doc/src/sgml/ref/pg_createsubscriber.sgml
src/bin/pg_basebackup/pg_createsubscriber.c
src/bin/pg_basebackup/t/040_pg_createsubscriber.pl

index 142bffff0234c173e605a2c64a3ff88ebf9343c4..a700697f887c5b0c4db75b9900d60a723ba3a6e8 100644 (file)
@@ -325,13 +325,6 @@ PostgreSQL documentation
     connections to the target server should fail.
    </para>
 
-   <para>
-    During the recovery process, if the target server disconnects from the
-    source server, <application>pg_createsubscriber</application> will check a
-    few times if the connection has been reestablished to stream the required
-    WAL.  After a few attempts, it terminates with an error.
-   </para>
-
    <para>
     Since DDL commands are not replicated by logical replication, avoid
     executing DDL commands that change the database schema while running
index 90cc580811dfe0c97e2b7ad6191d0e1dbbee0eeb..f62f34b1a765ce89869f5c0a9ac3e9e14209feb1 100644 (file)
@@ -1360,6 +1360,9 @@ stop_standby_server(const char *datadir)
  *
  * If recovery_timeout option is set, terminate abnormally without finishing
  * the recovery process. By default, it waits forever.
+ *
+ * XXX Is the recovery process still in progress? When recovery process has a
+ * better progress reporting mechanism, it should be added here.
  */
 static void
 wait_for_end_recovery(const char *conninfo, const struct CreateSubscriberOptions *opt)
@@ -1367,9 +1370,6 @@ wait_for_end_recovery(const char *conninfo, const struct CreateSubscriberOptions
    PGconn     *conn;
    int         status = POSTMASTER_STILL_STARTING;
    int         timer = 0;
-   int         count = 0;      /* number of consecutive connection attempts */
-
-#define NUM_CONN_ATTEMPTS  10
 
    pg_log_info("waiting for the target server to reach the consistent state");
 
@@ -1377,7 +1377,6 @@ wait_for_end_recovery(const char *conninfo, const struct CreateSubscriberOptions
 
    for (;;)
    {
-       PGresult   *res;
        bool        in_recovery = server_is_in_recovery(conn);
 
        /*
@@ -1391,28 +1390,6 @@ wait_for_end_recovery(const char *conninfo, const struct CreateSubscriberOptions
            break;
        }
 
-       /*
-        * If it is still in recovery, make sure the target server is
-        * connected to the primary so it can receive the required WAL to
-        * finish the recovery process. If it is disconnected try
-        * NUM_CONN_ATTEMPTS in a row and bail out if not succeed.
-        */
-       res = PQexec(conn,
-                    "SELECT 1 FROM pg_catalog.pg_stat_wal_receiver");
-       if (PQntuples(res) == 0)
-       {
-           if (++count > NUM_CONN_ATTEMPTS)
-           {
-               stop_standby_server(subscriber_dir);
-               pg_log_error("standby server disconnected from the primary");
-               break;
-           }
-       }
-       else
-           count = 0;          /* reset counter if it connects again */
-
-       PQclear(res);
-
        /* Bail out after recovery_timeout seconds if this option is set */
        if (opt->recovery_timeout > 0 && timer >= opt->recovery_timeout)
        {
index 2b883e6910491a56cf4d2eb426e3c5a93a10373b..a677fefa94f430424420054870ed6d42c419cb9d 100644 (file)
@@ -264,6 +264,7 @@ $node_p->restart;
 command_ok(
    [
        'pg_createsubscriber', '--verbose',
+       '--recovery-timeout', "$PostgreSQL::Test::Utils::timeout_default",
        '--dry-run', '--pgdata',
        $node_s->data_dir, '--publisher-server',
        $node_p->connstr('pg1'), '--socket-directory',
@@ -301,6 +302,7 @@ command_ok(
 command_ok(
    [
        'pg_createsubscriber', '--verbose',
+       '--recovery-timeout', "$PostgreSQL::Test::Utils::timeout_default",
        '--verbose', '--pgdata',
        $node_s->data_dir, '--publisher-server',
        $node_p->connstr('pg1'), '--socket-directory',