From 742d9e424a85df8e4be0189193f67a81fdd0b5dd Mon Sep 17 00:00:00 2001
From: Shinya Kato <shinya11.kato@gmail.com>
Date: Tue, 8 Jul 2025 18:08:50 +0900
Subject: [PATCH v1] Add backup_type to pg_stat_progress_basebackup

This commit adds a new column, backup_type, to the
pg_stat_progress_basebackup view. This column displays 'full' for a full
backup and 'incremental' for an incremental backup.

With the introduction of incremental backups in PostgreSQL 17, being
able to distinguish between backup types is useful for monitoring
progress.
---
 doc/src/sgml/monitoring.sgml             | 10 ++++++++++
 src/backend/backup/basebackup.c          |  2 +-
 src/backend/backup/basebackup_progress.c |  6 +++++-
 src/backend/catalog/system_views.sql     |  5 ++++-
 src/include/backup/basebackup_sink.h     |  3 ++-
 src/include/commands/progress.h          |  5 +++++
 src/test/regress/expected/rules.out      |  7 ++++++-
 7 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 823afe1b30b..3f1c72ee255 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -6780,6 +6780,16 @@ FROM pg_stat_get_backend_idset() AS backendid;
        advances when the phase is <literal>streaming database files</literal>.
       </para></entry>
      </row>
+
+     <row>
+      <entry role="catalog_table_entry"><para role="column_definition">
+       <structfield>backup_type</structfield> <type>bigint</type>
+      </para>
+      <para>
+        Backup type. Either <literal>full</literal> or
+        <literal>incremental</literal>.
+      </para></entry>
+     </row>
     </tbody>
    </tgroup>
   </table>
diff --git a/src/backend/backup/basebackup.c b/src/backend/backup/basebackup.c
index f0f88838dc2..bb7d90aa5d9 100644
--- a/src/backend/backup/basebackup.c
+++ b/src/backend/backup/basebackup.c
@@ -1048,7 +1048,7 @@ SendBaseBackup(BaseBackupCmd *cmd, IncrementalBackupInfo *ib)
 		sink = bbsink_zstd_new(sink, &opt.compression_specification);
 
 	/* Set up progress reporting. */
-	sink = bbsink_progress_new(sink, opt.progress);
+	sink = bbsink_progress_new(sink, opt.progress, opt.incremental);
 
 	/*
 	 * Perform the base backup, but make sure we clean up the bbsink even if
diff --git a/src/backend/backup/basebackup_progress.c b/src/backend/backup/basebackup_progress.c
index 1d22b541f89..9e1eccab60c 100644
--- a/src/backend/backup/basebackup_progress.c
+++ b/src/backend/backup/basebackup_progress.c
@@ -56,7 +56,7 @@ static const bbsink_ops bbsink_progress_ops = {
  * forwards data to a successor sink.
  */
 bbsink *
-bbsink_progress_new(bbsink *next, bool estimate_backup_size)
+bbsink_progress_new(bbsink *next, bool estimate_backup_size, bool incremental)
 {
 	bbsink	   *sink;
 
@@ -73,6 +73,10 @@ bbsink_progress_new(bbsink *next, bool estimate_backup_size)
 	 */
 	pgstat_progress_start_command(PROGRESS_COMMAND_BASEBACKUP, InvalidOid);
 	pgstat_progress_update_param(PROGRESS_BASEBACKUP_BACKUP_TOTAL, -1);
+	pgstat_progress_update_param(PROGRESS_BASEBACKUP_BACKUP_TYPE,
+								 incremental
+								 ? PROGRESS_BASEBACKUP_BACKUP_TYPE_INCREMENTAL
+								 : PROGRESS_BASEBACKUP_BACKUP_TYPE_FULL);
 
 	return sink;
 }
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index b2d5332effc..e8f923c485c 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -1327,7 +1327,10 @@ CREATE VIEW pg_stat_progress_basebackup AS
         CASE S.param2 WHEN -1 THEN NULL ELSE S.param2 END AS backup_total,
         S.param3 AS backup_streamed,
         S.param4 AS tablespaces_total,
-        S.param5 AS tablespaces_streamed
+        S.param5 AS tablespaces_streamed,
+        CASE S.param6 WHEN 1 THEN 'full'
+                      WHEN 2 THEN 'incremental'
+                      END AS backup_type
     FROM pg_stat_get_progress_info('BASEBACKUP') AS S;
 
 
diff --git a/src/include/backup/basebackup_sink.h b/src/include/backup/basebackup_sink.h
index 8a5ee996a45..310d92b8b9d 100644
--- a/src/include/backup/basebackup_sink.h
+++ b/src/include/backup/basebackup_sink.h
@@ -287,7 +287,8 @@ extern bbsink *bbsink_copystream_new(bool send_to_client);
 extern bbsink *bbsink_gzip_new(bbsink *next, pg_compress_specification *);
 extern bbsink *bbsink_lz4_new(bbsink *next, pg_compress_specification *);
 extern bbsink *bbsink_zstd_new(bbsink *next, pg_compress_specification *);
-extern bbsink *bbsink_progress_new(bbsink *next, bool estimate_backup_size);
+extern bbsink *bbsink_progress_new(bbsink *next, bool estimate_backup_size,
+								   bool incremental);
 extern bbsink *bbsink_server_new(bbsink *next, char *pathname);
 extern bbsink *bbsink_throttle_new(bbsink *next, uint32 maxrate);
 
diff --git a/src/include/commands/progress.h b/src/include/commands/progress.h
index 7c736e7b03b..1cde4bd9bcf 100644
--- a/src/include/commands/progress.h
+++ b/src/include/commands/progress.h
@@ -130,6 +130,7 @@
 #define PROGRESS_BASEBACKUP_BACKUP_STREAMED			2
 #define PROGRESS_BASEBACKUP_TBLSPC_TOTAL			3
 #define PROGRESS_BASEBACKUP_TBLSPC_STREAMED			4
+#define PROGRESS_BASEBACKUP_BACKUP_TYPE				5
 
 /* Phases of pg_basebackup (as advertised via PROGRESS_BASEBACKUP_PHASE) */
 #define PROGRESS_BASEBACKUP_PHASE_WAIT_CHECKPOINT		1
@@ -138,6 +139,10 @@
 #define PROGRESS_BASEBACKUP_PHASE_WAIT_WAL_ARCHIVE		4
 #define PROGRESS_BASEBACKUP_PHASE_TRANSFER_WAL			5
 
+/* Types of pg_basebackup (as advertised via PROGRESS_BASEBACKUP_BACKUP_TYPE) */
+#define PROGRESS_BASEBACKUP_BACKUP_TYPE_FULL			1
+#define PROGRESS_BASEBACKUP_BACKUP_TYPE_INCREMENTAL		2
+
 /* Progress parameters for PROGRESS_COPY */
 #define PROGRESS_COPY_BYTES_PROCESSED 0
 #define PROGRESS_COPY_BYTES_TOTAL 1
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index dce8c672b40..90f94d33e3c 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1977,7 +1977,12 @@ pg_stat_progress_basebackup| SELECT pid,
         END AS backup_total,
     param3 AS backup_streamed,
     param4 AS tablespaces_total,
-    param5 AS tablespaces_streamed
+    param5 AS tablespaces_streamed,
+        CASE param6
+            WHEN 1 THEN 'full'::text
+            WHEN 2 THEN 'incremental'::text
+            ELSE NULL::text
+        END AS backup_type
    FROM pg_stat_get_progress_info('BASEBACKUP'::text) s(pid, datid, relid, param1, param2, param3, param4, param5, param6, param7, param8, param9, param10, param11, param12, param13, param14, param15, param16, param17, param18, param19, param20);
 pg_stat_progress_cluster| SELECT s.pid,
     s.datid,
-- 
2.47.1

