diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index de13c7c4761c99c95466e337622776f53ae735fe..6f75d41a48c069deb828f0df37e5be4eadaa9417 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 f3c8a09c2aa4826549a3e06cfc29e495d72c2ceb..d94809ad7ee23d4017ba6d2f475f1f5d39875a2a 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 3328a50faba0064a58a58ad8ff9dfd445f13e5fb..29a0310dcf931503a8baa57951502618946247ab 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 b308e4b5813a6928eda38185e9577f0507679acb..65284f78ca321ad5493d30576a4a207afe9bb319 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 1e097ddbe6c420abcc89409925347fb643d3c152..256f474bb4e8219889108b22b2da363fde388fec 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_ ));