From ccbb7423c10e11deea65f49e8e2d8e997f9bd6d4 Mon Sep 17 00:00:00 2001
From: shihao zhong <zhong950419@gmail.com>
Date: Sun, 4 Oct 2026 23:38:16 -0400
Subject: [PATCH v3 1/2] pg_resetwal: Refuse to run when backup_label exists

A backup_label file means the data directory is a base backup that
still needs WAL replay. Resetting WAL there leaves a corrupt cluster,
so refuse even with --force, and tell the user to set up recovery.

Discussion: https://postgr.es/m/556bef11-938d-45ca-94b3-7143a3cb532d@pgbackrest.org
Discussion: https://postgr.es/m/CAGRkXqTEM51AHwzvs6QVVrJJDXVD9g5QwrfMYp3-BkM9Ph-G8A@mail.gmail.com
---
 doc/src/sgml/ref/pg_resetwal.sgml | 14 +++++++++++++-
 src/bin/pg_resetwal/pg_resetwal.c | 19 +++++++++++++++++++
 2 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml
index d34aa26413c..229cf34f00b 100644
--- a/doc/src/sgml/ref/pg_resetwal.sgml
+++ b/doc/src/sgml/ref/pg_resetwal.sgml
@@ -74,6 +74,17 @@ PostgreSQL documentation
    corrupted control file.
   </para>
 
+  <para>
+   <command>pg_resetwal</command> refuses to run on a data directory that
+   contains a <filename>backup_label</filename> file, even with
+   <option>-f</option> or <option>-n</option>.  Such a data directory is a
+   base backup that needs WAL replay to become consistent, and resetting the
+   WAL would leave it corrupted.  To restore a backup, configure recovery as
+   described in <xref linkend="backup-pitr-recovery"/>.  Remove
+   <filename>backup_label</filename> only if you are sure the data directory
+   is not a backup that still needs recovery.
+  </para>
+
   <para>
    After running this command on a data directory with corrupted WAL or a
    corrupted control file, it should be possible to start the server,
@@ -132,7 +143,8 @@ PostgreSQL documentation
       it could be dangerous, as explained above.  Specifically, this option is
       required to proceed if the server had not been cleanly shut down or if
       <command>pg_resetwal</command> cannot determine valid data for
-      <filename>pg_control</filename>.
+      <filename>pg_control</filename>.  It does not override the check for
+      a <filename>backup_label</filename> file.
      </para>
     </listitem>
    </varlistentry>
diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c
index 634d966da9e..bc81463c180 100644
--- a/src/bin/pg_resetwal/pg_resetwal.c
+++ b/src/bin/pg_resetwal/pg_resetwal.c
@@ -431,6 +431,25 @@ main(int argc, char *argv[])
 		exit(1);
 	}
 
+	/*
+	 * A backup_label file means this is a base backup that needs WAL replay
+	 * to become consistent.  Resetting WAL cannot fix that, so refuse even
+	 * with -f.
+	 */
+	if ((fd = open(BACKUP_LABEL_FILE, O_RDONLY, 0)) < 0)
+	{
+		if (errno != ENOENT)
+			pg_fatal("could not open file \"%s\" for reading: %m",
+					 BACKUP_LABEL_FILE);
+	}
+	else
+	{
+		pg_log_error("backup label file \"%s\" exists", BACKUP_LABEL_FILE);
+		pg_log_error_hint("If you are restoring from a backup, configure recovery instead.  "
+						  "If you are not restoring from a backup, delete the backup label file and try again.");
+		exit(1);
+	}
+
 	/*
 	 * Attempt to read the existing pg_control file
 	 */
-- 
2.37.1 (Apple Git-137.1)

