diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index de13c7c476..6f75d41a48 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);
pg_stop_backup
+
+ pg_is_in_backup
+
+
+ pg_backup_start_time
+
pg_switch_xlog
@@ -14519,6 +14525,20 @@ SELECT set_config('log_statement_stats', 'off', false);
text
Finish performing on-line backup (restricted to superusers or replication roles)
+
+
+ pg_is_in_backup()
+
+ bool
+ True if an on-line exclusive backup is still in progress.
+
+
+
+ pg_backup_start_time()
+
+ timestamp with time zone
+ Get start time of an online exclusive backup in progress.
+
pg_switch_xlog()
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index f3c8a09c2a..d94809ad7e 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 3328a50fab..29a0310dcf 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 b308e4b581..65284f78ca 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 1e097ddbe6..256f474bb4 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_ ));