Add some checkpoint/restartpoint status to ps display
authorMichael Paquier <michael@paquier.xyz>
Mon, 14 Dec 2020 02:53:58 +0000 (11:53 +0900)
committerMichael Paquier <michael@paquier.xyz>
Mon, 14 Dec 2020 02:53:58 +0000 (11:53 +0900)
This is done for end-of-recovery and shutdown checkpoints/restartpoints
(end-of-recovery restartpoints don't exist) rather than all types of
checkpoints, in cases where it may not be possible to rely on
pg_stat_activity to get a status from the startup or checkpointer
processes.

For example, at the end of a crash recovery, this is useful to know if a
checkpoint is running in the startup process, while previously the ps
display may only show some information about "recovering" something,
that can be confusing while a checkpoint runs.

Author: Justin Pryzby
Reviewed-by: Nathan Bossart, Kirk Jamison, Fujii Masao, Michael Paquier
Discussion: https://postgr.es/m/20200818225238.GP17022@telsasoft.com

src/backend/access/transam/xlog.c

index 7e81ce4f173f9b2968b7df964531d7802e0e8b89..8dd225c2e140ac13273be1337935faf749e0322b 100644 (file)
@@ -8687,6 +8687,39 @@ UpdateCheckPointDistanceEstimate(uint64 nbytes)
                        (0.90 * CheckPointDistanceEstimate + 0.10 * (double) nbytes);
 }
 
+/*
+ * Update the ps display for a process running a checkpoint.  Note that
+ * this routine should not do any allocations so as it can be called
+ * from a critical section.
+ */
+static void
+update_checkpoint_display(int flags, bool restartpoint, bool reset)
+{
+       /*
+        * The status is reported only for end-of-recovery and shutdown
+        * checkpoints or shutdown restartpoints.  Updating the ps display is
+        * useful in those situations as it may not be possible to rely on
+        * pg_stat_activity to see the status of the checkpointer or the startup
+        * process.
+        */
+       if ((flags & (CHECKPOINT_END_OF_RECOVERY | CHECKPOINT_IS_SHUTDOWN)) == 0)
+               return;
+
+       if (reset)
+               set_ps_display("");
+       else
+       {
+               char            activitymsg[128];
+
+               snprintf(activitymsg, sizeof(activitymsg), "performing %s%s%s",
+                                (flags & CHECKPOINT_END_OF_RECOVERY) ? "end-of-recovery " : "",
+                                (flags & CHECKPOINT_IS_SHUTDOWN) ? "shutdown " : "",
+                                restartpoint ? "restartpoint" : "checkpoint");
+               set_ps_display(activitymsg);
+       }
+}
+
+
 /*
  * Perform a checkpoint --- either during shutdown, or on-the-fly
  *
@@ -8905,6 +8938,9 @@ CreateCheckPoint(int flags)
        if (log_checkpoints)
                LogCheckpointStart(flags, false);
 
+       /* Update the process title */
+       update_checkpoint_display(flags, false, false);
+
        TRACE_POSTGRESQL_CHECKPOINT_START(flags);
 
        /*
@@ -9120,6 +9156,9 @@ CreateCheckPoint(int flags)
        /* Real work is done, but log and update stats before releasing lock. */
        LogCheckpointEnd(false);
 
+       /* Reset the process title */
+       update_checkpoint_display(flags, false, true);
+
        TRACE_POSTGRESQL_CHECKPOINT_DONE(CheckpointStats.ckpt_bufs_written,
                                                                         NBuffers,
                                                                         CheckpointStats.ckpt_segs_added,
@@ -9374,6 +9413,9 @@ CreateRestartPoint(int flags)
        if (log_checkpoints)
                LogCheckpointStart(flags, true);
 
+       /* Update the process title */
+       update_checkpoint_display(flags, true, false);
+
        CheckPointGuts(lastCheckPoint.redo, flags);
 
        /*
@@ -9492,6 +9534,9 @@ CreateRestartPoint(int flags)
        /* Real work is done, but log and update before releasing lock. */
        LogCheckpointEnd(true);
 
+       /* Reset the process title */
+       update_checkpoint_display(flags, true, true);
+
        xtime = GetLatestXTime();
        ereport((log_checkpoints ? LOG : DEBUG2),
                        (errmsg("recovery restart point at %X/%X",