From 68de499bda40fdf1395b714bb63febad61046700 Mon Sep 17 00:00:00 2001
From: Robert Haas <rhaas@postgresql.org>
Date: Thu, 14 Jun 2012 13:25:43 -0400
Subject: [PATCH] New SQL functons pg_backup_in_progress() and
 pg_backup_start_time()

Darold Gilles, reviewed by Gabriele Bartolini and others, rebased by
Marco Nenciarini.  Stylistic cleanup and OID fixes by me.
---
 doc/src/sgml/func.sgml                 | 20 +++++++
 src/backend/access/transam/xlogfuncs.c | 73 +++++++++++++++++++++++++-
 src/include/access/xlog_internal.h     |  2 +
 src/include/catalog/catversion.h       |  2 +-
 src/include/catalog/pg_proc.h          |  4 ++
 5 files changed, 99 insertions(+), 2 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index de13c7c4761..6f75d41a48c 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -14455,6 +14455,12 @@ SELECT set_config('log_statement_stats', 'off', false);
    <indexterm>
     <primary>pg_stop_backup</primary>
    </indexterm>
+   <indexterm>
+    <primary>pg_is_in_backup</primary>
+   </indexterm>
+   <indexterm>
+    <primary>pg_backup_start_time</primary>
+   </indexterm>
    <indexterm>
     <primary>pg_switch_xlog</primary>
    </indexterm>
@@ -14519,6 +14525,20 @@ SELECT set_config('log_statement_stats', 'off', false);
        <entry><type>text</type></entry>
        <entry>Finish performing on-line backup (restricted to superusers or replication roles)</entry>
       </row>
+      <row>
+       <entry>
+        <literal><function>pg_is_in_backup()</function></literal>
+        </entry>
+       <entry><type>bool</type></entry>
+       <entry>True if an on-line exclusive backup is still in progress.</entry>
+      </row>
+      <row>
+       <entry>
+        <literal><function>pg_backup_start_time()</function></literal>
+        </entry>
+       <entry><type>timestamp with time zone</type></entry>
+       <entry>Get start time of an online exclusive backup in progress.</entry>
+      </row>
       <row>
        <entry>
         <literal><function>pg_switch_xlog()</function></literal>
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index f3c8a09c2aa..d94809ad7ee 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -29,7 +29,7 @@
 #include "utils/numeric.h"
 #include "utils/guc.h"
 #include "utils/timestamp.h"
-
+#include "storage/fd.h"
 
 static void validate_xlog_location(char *str);
 
@@ -563,3 +563,74 @@ pg_xlog_location_diff(PG_FUNCTION_ARGS)
 
 	PG_RETURN_NUMERIC(result);
 }
+
+/*
+ * Returns bool with current on-line backup mode, a global state.
+ */
+Datum
+pg_is_in_backup(PG_FUNCTION_ARGS)
+{
+	PG_RETURN_BOOL(BackupInProgress());
+}
+
+/*
+ * Returns start time of an online exclusive backup.
+ *
+ * When there's no exclusive backup in progress, the function
+ * returns NULL.
+ */
+Datum
+pg_backup_start_time(PG_FUNCTION_ARGS)
+{
+	Datum		xtime;
+	FILE	   *lfp;
+	char		fline[MAXPGPATH];
+	char		backup_start_time[30];
+
+	/*
+	 * See if label file is present
+	 */
+	lfp = AllocateFile(BACKUP_LABEL_FILE, "r");
+	if (lfp == NULL)
+	{
+		if (errno != ENOENT)
+			ereport(ERROR,
+					(errcode_for_file_access(),
+					 errmsg("could not read file \"%s\": %m",
+						BACKUP_LABEL_FILE)));
+		PG_RETURN_NULL();
+	}
+
+	/*
+	 * Parse the file to find the the START TIME line.
+	 */
+	backup_start_time[0] = '\0';
+	while (fgets(fline, sizeof(fline), lfp) != NULL)
+	{
+		if (sscanf(fline, "START TIME: %25[^\n]\n", backup_start_time) == 1)
+			break;
+	}
+
+	/*
+	 * Close the backup label file.
+	 */
+	if (ferror(lfp) || FreeFile(lfp))
+		ereport(ERROR,
+				(errcode_for_file_access(),
+				 errmsg("could not read file \"%s\": %m", BACKUP_LABEL_FILE)));
+
+	if (strlen(backup_start_time) == 0)
+		ereport(ERROR,
+				(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
+				 errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE)));
+
+	/*
+	 * Convert the time string read from file to TimestampTz form.
+	 */
+	xtime = DirectFunctionCall3(timestamptz_in,
+								CStringGetDatum(backup_start_time),
+								ObjectIdGetDatum(InvalidOid),
+								Int32GetDatum(-1));
+
+	PG_RETURN_DATUM(xtime);
+}
diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h
index 3328a50faba..29a0310dcf9 100644
--- a/src/include/access/xlog_internal.h
+++ b/src/include/access/xlog_internal.h
@@ -282,5 +282,7 @@ extern Datum pg_xlog_replay_pause(PG_FUNCTION_ARGS);
 extern Datum pg_xlog_replay_resume(PG_FUNCTION_ARGS);
 extern Datum pg_is_xlog_replay_paused(PG_FUNCTION_ARGS);
 extern Datum pg_xlog_location_diff(PG_FUNCTION_ARGS);
+extern Datum pg_is_in_backup(PG_FUNCTION_ARGS);
+extern Datum pg_backup_start_time(PG_FUNCTION_ARGS);
 
 #endif   /* XLOG_INTERNAL_H */
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index b308e4b5813..65284f78ca3 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	201204301
+#define CATALOG_VERSION_NO	201206141
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 1e097ddbe6c..256f474bb4e 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -2936,6 +2936,10 @@ DATA(insert OID = 2172 ( pg_start_backup		PGNSP PGUID 12 1 0 0 0 f f f f t f v 2
 DESCR("prepare for taking an online backup");
 DATA(insert OID = 2173 ( pg_stop_backup			PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_stop_backup _null_ _null_ _null_ ));
 DESCR("finish taking an online backup");
+DATA(insert OID = 3813 ( pg_is_in_backup		PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 16 "" _null_ _null_ _null_ _null_ pg_is_in_backup _null_ _null_ _null_ ));
+DESCR("true if server is in online backup");
+DATA(insert OID = 3814 ( pg_backup_start_time		PGNSP PGUID 12 1 0 0 0 f f f f t f s 0 0 1184 "" _null_ _null_ _null_ _null_ pg_backup_start_time _null_ _null_ _null_ ));
+DESCR("start time of an online backup");
 DATA(insert OID = 2848 ( pg_switch_xlog			PGNSP PGUID 12 1 0 0 0 f f f f t f v 0 0 25 "" _null_ _null_ _null_ _null_ pg_switch_xlog _null_ _null_ _null_ ));
 DESCR("switch to new xlog file");
 DATA(insert OID = 3098 ( pg_create_restore_point	PGNSP PGUID 12 1 0 0 0 f f f f t f v 1 0 25 "25" _null_ _null_ _null_ _null_ pg_create_restore_point _null_ _null_ _null_ ));
-- 
GitLab