Hi,
Since an exclusive backup method was dropped in v15, in v15 or later, we need to create
backup_label and tablespace_map files from the result of pg_backup_stop() when taking a base backup
using low level backup API. One issue when doing this is that; there is no simple way to create
those files from two columns "labelfile" and "spcmapfile" that pg_backup_stop()
returns if we execute it via psql. Probaby we need to store those columns in a temporary file and
run some OS commands or script to separate that file into backup_label and tablespace_map. This is
not simple way, and which would prevent users from migrating their backup scripts using psql from
an exclusive backup method to non-exclusive one, I'm afraid.
To enable us to do that more easily, how about adding the pg_backup_label()
function that returns backup_label and tablespace_map? I'm thinking to make
this function available just after pg_backup_start() finishes, also even after
pg_backup_stop() finishes. For example, this function allows us to take a
backup using the following psql script file.
------------------------------
SELECT * FROM pg_backup_start('test');
\! cp -a $PGDATA /backup
SELECT * FROM pg_backup_stop();
\pset tuples_only on
\pset format unaligned
\o /backup/data/backup_label
SELECT labelfile FROM pg_backup_label();
\o /backup/data/tablespace_map
SELECT spcmapfile FROM pg_backup_label();
------------------------------
Attached is the WIP patch to add pg_backup_label function. No tests nor docs
have been added yet, but if we can successfully reach the consensus for adding
the function, I will update the patch.
Thought?
Regards,
--
Fujii Masao
Advanced Computing Technology Center
Research and Development Headquarters
NTT DATA CORPORATION
diff --git a/src/backend/access/transam/xlogfuncs.c
b/src/backend/access/transam/xlogfuncs.c
index 02bd919ff6..946b119e41 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -41,8 +41,8 @@
/*
* Store label file and tablespace map during backups.
*/
-static StringInfo label_file;
-static StringInfo tblspc_map_file;
+static StringInfo label_file = NULL;
+static StringInfo tblspc_map_file = NULL;
/*
* pg_backup_start: set up for taking an on-line backup dump
@@ -77,10 +77,18 @@ pg_backup_start(PG_FUNCTION_ARGS)
* Label file and tablespace map file need to be long-lived, since they
* are read in pg_backup_stop.
*/
- oldcontext = MemoryContextSwitchTo(TopMemoryContext);
- label_file = makeStringInfo();
- tblspc_map_file = makeStringInfo();
- MemoryContextSwitchTo(oldcontext);
+ if (label_file == NULL)
+ {
+ oldcontext = MemoryContextSwitchTo(TopMemoryContext);
+ label_file = makeStringInfo();
+ tblspc_map_file = makeStringInfo();
+ MemoryContextSwitchTo(oldcontext);
+ }
+ else
+ {
+ resetStringInfo(label_file);
+ resetStringInfo(tblspc_map_file);
+ }
register_persistent_abort_backup_handler();
@@ -136,13 +144,36 @@ pg_backup_stop(PG_FUNCTION_ARGS)
values[1] = CStringGetTextDatum(label_file->data);
values[2] = CStringGetTextDatum(tblspc_map_file->data);
- /* Free structures allocated in TopMemoryContext */
- pfree(label_file->data);
- pfree(label_file);
- label_file = NULL;
- pfree(tblspc_map_file->data);
- pfree(tblspc_map_file);
- tblspc_map_file = NULL;
+ /* Returns the record as Datum */
+ PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values,
nulls)));
+}
+
+/*
+ * pg_backup_label: return backup_label and tablespace_map
+ */
+Datum
+pg_backup_label(PG_FUNCTION_ARGS)
+{
+ TupleDesc tupdesc;
+ Datum values[2];
+ bool nulls[2];
+
+ /* Initialize attributes information in the tuple descriptor */
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
+
+ MemSet(values, 0, sizeof(values));
+ MemSet(nulls, 0, sizeof(nulls));
+
+ if (label_file != NULL)
+ values[0] = CStringGetTextDatum(label_file->data);
+ else
+ nulls[0] = true;
+
+ if (tblspc_map_file != NULL)
+ values[1] = CStringGetTextDatum(tblspc_map_file->data);
+ else
+ nulls[1] = true;
/* Returns the record as Datum */
PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values,
nulls)));
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 2e41f4d9e8..2f9b0b65f1 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -6300,6 +6300,12 @@
proallargtypes => '{bool,pg_lsn,text,text}', proargmodes => '{i,o,o,o}',
proargnames => '{wait_for_archive,lsn,labelfile,spcmapfile}',
prosrc => 'pg_backup_stop' },
+{ oid => '2173', descr => 'return backup label and tablespace map',
+ proname => 'pg_backup_label', provolatile => 'v', proparallel => 'r',
+ prorettype => 'record', proargtypes => '',
+ proallargtypes => '{text,text}', proargmodes => '{o,o}',
+ proargnames => '{labelfile,spcmapfile}',
+ prosrc => 'pg_backup_label' },
{ oid => '3436', descr => 'promote standby server',
proname => 'pg_promote', provolatile => 'v', prorettype => 'bool',
proargtypes => 'bool int4', proargnames => '{wait,wait_seconds}',