New SQL functons pg_backup_in_progress() and pg_backup_start_time()
authorRobert Haas <rhaas@postgresql.org>
Thu, 14 Jun 2012 17:25:43 +0000 (13:25 -0400)
committerRobert Haas <rhaas@postgresql.org>
Thu, 14 Jun 2012 17:25:43 +0000 (13:25 -0400)
Darold Gilles, reviewed by Gabriele Bartolini and others, rebased by
Marco Nenciarini.  Stylistic cleanup and OID fixes by me.

doc/src/sgml/func.sgml
src/backend/access/transam/xlogfuncs.c
src/include/access/xlog_internal.h
src/include/catalog/catversion.h
src/include/catalog/pg_proc.h

index de13c7c4761c99c95466e337622776f53ae735fe..6f75d41a48c069deb828f0df37e5be4eadaa9417 100644 (file)
@@ -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>
index f3c8a09c2aa4826549a3e06cfc29e495d72c2ceb..d94809ad7ee23d4017ba6d2f475f1f5d39875a2a 100644 (file)
@@ -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);
+}
index 3328a50faba0064a58a58ad8ff9dfd445f13e5fb..29a0310dcf931503a8baa57951502618946247ab 100644 (file)
@@ -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 */
index b308e4b5813a6928eda38185e9577f0507679acb..65284f78ca321ad5493d30576a4a207afe9bb319 100644 (file)
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 201204301
+#define CATALOG_VERSION_NO 201206141
 
 #endif
index 1e097ddbe6c420abcc89409925347fb643d3c152..256f474bb4e8219889108b22b2da363fde388fec 100644 (file)
@@ -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_ ));