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_ ));