Hi all,

On Wed, Jan 7, 2026 at 1:37 PM Michael Banck <[email protected]> wrote:
>
> Hi,
>
> On Wed, Jan 07, 2026 at 12:35:08PM +0530, Soumya S Murali wrote:
> > I agree with your point that the checkpoint completion message should
> > use the same terminology as the starting message ( “fast” rather than
> > “immediate”) and I have updated the patch accordingly and have
> > attached herewith for review. This patch aligns the checkpoint
> > completion log wording with the existing checkpoint starting message
> > (using “fast” instead of “immediate”) for consistency.
>
> First off, please send complete and not incremental patches.
>
> From what I can tell, you currently also do not have "wal" as reason?
> Also, you have "timed" vs "time" etc.
>
> I think it would make most sense to factor out the logic for the
> starting checkpoint reason from xlog.c ("(errmsg("checkpoint
> starting:%s%s%s%s%s%s%s%s")") and use that both for starting and
> stopping.
>
>
> Michael

Thank you for the review and feedback.
I have reworked the patch to factor out the checkpoint reason logic to
use the same wording for both checkpoint start and completion log
(including wal, time, fast, force, and wait). The format has been
aligned with existing conventions and has been verified by running
make check and recovery TAP tests including t/019_replslot_limit.pl
successfully.
Kindly review my patch and let me know the feedback.

Regards,
Soumya
From 0204328b225d5641a13e3e6f4c373622df31a398 Mon Sep 17 00:00:00 2001
From: Soumya <[email protected]>
Date: Thu, 8 Jan 2026 11:42:23 +0530
Subject: [PATCH] Expose checkpoint reason in checkpoint completion log
 messages

Signed-off-by: Soumya <[email protected]>
---
 src/backend/access/transam/xlog.c         | 51 ++++++++++++++++++-----
 src/test/recovery/t/019_replslot_limit.pl |  2 +-
 2 files changed, 41 insertions(+), 12 deletions(-)

diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 22d0a2e8c3..9f7439f9a2 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -203,6 +203,8 @@ const struct config_enum_entry archive_mode_options[] = {
 	{NULL, 0, false}
 };
 
+static char checkpoint_reason_str[128];
+
 /*
  * Statistics for current checkpoint are collected in this global struct.
  * Because only the checkpointer or a stand-alone backend can perform
@@ -6714,12 +6716,47 @@ ShutdownXLOG(int code, Datum arg)
 	}
 }
 
+/*
+ * Format checkpoint reason flags consistently for log messages.
+ * The returned string is suitable for inclusion after
+ * "checkpoint starting:" or inside "checkpoint complete (...)".
+ */
+static const char *
+CheckpointReasonString(int flags)
+{
+	static char buf[128];
+
+	buf[0] = '\0';
+
+	if (flags & CHECKPOINT_IS_SHUTDOWN)
+		strcat(buf, " shutdown");
+	if (flags & CHECKPOINT_END_OF_RECOVERY)
+		strcat(buf, " end-of-recovery");
+	if (flags & CHECKPOINT_FAST)
+		strcat(buf, " fast");
+	if (flags & CHECKPOINT_FORCE)
+		strcat(buf, " force");
+	if (flags & CHECKPOINT_WAIT)
+		strcat(buf, " wait");
+	if (flags & CHECKPOINT_CAUSE_XLOG)
+		strcat(buf, " wal");
+	if (flags & CHECKPOINT_CAUSE_TIME)
+		strcat(buf, " time");
+	if (flags & CHECKPOINT_FLUSH_UNLOGGED)
+		strcat(buf, " flush-unlogged");
+
+	return buf;
+}
+
 /*
  * Log start of a checkpoint.
  */
 static void
 LogCheckpointStart(int flags, bool restartpoint)
 {
+	strlcpy(checkpoint_reason_str,
+        	CheckpointReasonString(flags),
+        	sizeof(checkpoint_reason_str));
 	if (restartpoint)
 		ereport(LOG,
 		/* translator: the placeholders show checkpoint options */
@@ -6734,16 +6771,7 @@ LogCheckpointStart(int flags, bool restartpoint)
 						(flags & CHECKPOINT_FLUSH_UNLOGGED) ? " flush-unlogged" : "")));
 	else
 		ereport(LOG,
-		/* translator: the placeholders show checkpoint options */
-				(errmsg("checkpoint starting:%s%s%s%s%s%s%s%s",
-						(flags & CHECKPOINT_IS_SHUTDOWN) ? " shutdown" : "",
-						(flags & CHECKPOINT_END_OF_RECOVERY) ? " end-of-recovery" : "",
-						(flags & CHECKPOINT_FAST) ? " fast" : "",
-						(flags & CHECKPOINT_FORCE) ? " force" : "",
-						(flags & CHECKPOINT_WAIT) ? " wait" : "",
-						(flags & CHECKPOINT_CAUSE_XLOG) ? " wal" : "",
-						(flags & CHECKPOINT_CAUSE_TIME) ? " time" : "",
-						(flags & CHECKPOINT_FLUSH_UNLOGGED) ? " flush-unlogged" : "")));
+        		(errmsg("checkpoint starting:%s", checkpoint_reason_str)));
 }
 
 /*
@@ -6824,12 +6852,13 @@ LogCheckpointEnd(bool restartpoint)
 						LSN_FORMAT_ARGS(ControlFile->checkPointCopy.redo))));
 	else
 		ereport(LOG,
-				(errmsg("checkpoint complete: wrote %d buffers (%.1f%%), "
+				(errmsg("checkpoint complete (%s): wrote %d buffers (%.1f%%), "
 						"wrote %d SLRU buffers; %d WAL file(s) added, "
 						"%d removed, %d recycled; write=%ld.%03d s, "
 						"sync=%ld.%03d s, total=%ld.%03d s; sync files=%d, "
 						"longest=%ld.%03d s, average=%ld.%03d s; distance=%d kB, "
 						"estimate=%d kB; lsn=%X/%08X, redo lsn=%X/%08X",
+						checkpoint_reason_str,
 						CheckpointStats.ckpt_bufs_written,
 						(double) CheckpointStats.ckpt_bufs_written * 100 / NBuffers,
 						CheckpointStats.ckpt_slru_written,
diff --git a/src/test/recovery/t/019_replslot_limit.pl b/src/test/recovery/t/019_replslot_limit.pl
index 6468784b83..ccc363157e 100644
--- a/src/test/recovery/t/019_replslot_limit.pl
+++ b/src/test/recovery/t/019_replslot_limit.pl
@@ -203,7 +203,7 @@ is($result, "rep1|f|t|lost|",
 my $checkpoint_ended = 0;
 for (my $i = 0; $i < 10 * $PostgreSQL::Test::Utils::timeout_default; $i++)
 {
-	if ($node_primary->log_contains("checkpoint complete: ", $logstart))
+	if ($node_primary->log_contains(qr/checkpoint complete(?: \([^)]*\))?:/, $logstart))
 	{
 		$checkpoint_ended = 1;
 		last;
-- 
2.34.1

Reply via email to