Disable STARTUP_PROGRESS_TIMEOUT in standby mode.
authorRobert Haas <rhaas@postgresql.org>
Mon, 6 Feb 2023 15:51:08 +0000 (10:51 -0500)
committerRobert Haas <rhaas@postgresql.org>
Mon, 6 Feb 2023 15:51:08 +0000 (10:51 -0500)
In standby mode, we don't actually report progress of recovery,
but up until now, startup_progress_timeout_handler() nevertheless
got called every log_startup_progress_interval seconds. That's
an unnecessary expense, so avoid it.

Report by Thomas Munro. Patch by Bharath Rupireddy, reviewed by
Simon Riggs, Thomas Munro, and me. Back-patch to v15, where
the problem was introduced.

Discussion: https://www.postgresql.org/message-id/CA%2BhUKGKCHSffAj8zZJKJvNX7ygnQFxVD6wm1d-2j3fVw%2BMafPQ%40mail.gmail.com

src/backend/access/transam/xlogrecovery.c
src/backend/postmaster/startup.c
src/include/postmaster/startup.h

index 2a5352f8793ce7b51443f662867eef6161301a2d..dbe9394762768e1523e4f993020e9b05c56c9805 100644 (file)
@@ -385,6 +385,7 @@ static bool recoveryStopAfter;
 /* prototypes for local functions */
 static void ApplyWalRecord(XLogReaderState *xlogreader, XLogRecord *record, TimeLineID *replayTLI);
 
+static void EnableStandbyMode(void);
 static void readRecoverySignalFile(void);
 static void validateRecoveryParameters(void);
 static bool read_backup_label(XLogRecPtr *checkPointLoc,
@@ -469,6 +470,24 @@ XLogRecoveryShmemInit(void)
    ConditionVariableInit(&XLogRecoveryCtl->recoveryNotPausedCV);
 }
 
+/*
+ * A thin wrapper to enable StandbyMode and do other preparatory work as
+ * needed.
+ */
+static void
+EnableStandbyMode(void)
+{
+   StandbyMode = true;
+
+   /*
+    * To avoid server log bloat, we don't report recovery progress in a
+    * standby as it will always be in recovery unless promoted. We disable
+    * startup progress timeout in standby mode to avoid calling
+    * startup_progress_timeout_handler() unnecessarily.
+    */
+   disable_startup_progress_timeout();
+}
+
 /*
  * Prepare the system for WAL recovery, if needed.
  *
@@ -602,7 +621,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
         */
        InArchiveRecovery = true;
        if (StandbyModeRequested)
-           StandbyMode = true;
+           EnableStandbyMode();
 
        /*
         * When a backup_label file is present, we want to roll forward from
@@ -739,7 +758,7 @@ InitWalRecovery(ControlFileData *ControlFile, bool *wasShutdown_ptr,
        {
            InArchiveRecovery = true;
            if (StandbyModeRequested)
-               StandbyMode = true;
+               EnableStandbyMode();
        }
 
        /* Get the last valid checkpoint record. */
@@ -3117,7 +3136,7 @@ ReadRecord(XLogPrefetcher *xlogprefetcher, int emode,
                        (errmsg_internal("reached end of WAL in pg_wal, entering archive recovery")));
                InArchiveRecovery = true;
                if (StandbyModeRequested)
-                   StandbyMode = true;
+                   EnableStandbyMode();
 
                SwitchIntoArchiveRecovery(xlogreader->EndRecPtr, replayTLI);
                minRecoveryPoint = xlogreader->EndRecPtr;
index bcd23542f1d14b67e1d0dd071935295ffa7a79e5..efc2580536a6686e9b92630a470540e07f9c3165 100644 (file)
@@ -314,11 +314,22 @@ startup_progress_timeout_handler(void)
    startup_progress_timer_expired = true;
 }
 
+void
+disable_startup_progress_timeout(void)
+{
+   /* Feature is disabled. */
+   if (log_startup_progress_interval == 0)
+       return;
+
+   disable_timeout(STARTUP_PROGRESS_TIMEOUT, false);
+   startup_progress_timer_expired = false;
+}
+
 /*
  * Set the start timestamp of the current operation and enable the timeout.
  */
 void
-begin_startup_progress_phase(void)
+enable_startup_progress_timeout(void)
 {
    TimestampTz fin_time;
 
@@ -326,8 +337,6 @@ begin_startup_progress_phase(void)
    if (log_startup_progress_interval == 0)
        return;
 
-   disable_timeout(STARTUP_PROGRESS_TIMEOUT, false);
-   startup_progress_timer_expired = false;
    startup_progress_phase_start_time = GetCurrentTimestamp();
    fin_time = TimestampTzPlusMilliseconds(startup_progress_phase_start_time,
                                           log_startup_progress_interval);
@@ -335,6 +344,21 @@ begin_startup_progress_phase(void)
                         log_startup_progress_interval);
 }
 
+/*
+ * A thin wrapper to first disable and then enable the startup progress
+ * timeout.
+ */
+void
+begin_startup_progress_phase(void)
+{
+   /* Feature is disabled. */
+   if (log_startup_progress_interval == 0)
+       return;
+
+   disable_startup_progress_timeout();
+   enable_startup_progress_timeout();
+}
+
 /*
  * Report whether startup progress timeout has occurred. Reset the timer flag
  * if it did, set the elapsed time to the out parameters and return true,
index dd957f9291f27386cffc2432d8cc1317e1519010..6a2e4c4526be6fb0ffed11df02ad587c198d23de 100644 (file)
@@ -32,6 +32,8 @@ extern void PostRestoreCommand(void);
 extern bool IsPromoteSignaled(void);
 extern void ResetPromoteSignaled(void);
 
+extern void enable_startup_progress_timeout(void);
+extern void disable_startup_progress_timeout(void);
 extern void begin_startup_progress_phase(void);
 extern void startup_progress_timeout_handler(void);
 extern bool has_startup_progress_timeout_expired(long *secs, int *usecs);