git.postgresql.org Git - postgresql.git/commitdiff

git projects / postgresql.git / commitdiff
? search:
summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: b8e20d6)
Move routine building restore_command to src/common/
2020年3月24日 03:13:36 +0000 (12:13 +0900)
2020年3月24日 03:13:36 +0000 (12:13 +0900)
restore_command has only been used until now by the backend, but there
is a pending patch for pg_rewind to make use of that in the frontend.

Author: Alexey Kondratov
Reviewed-by: Andrey Borodin, Andres Freund, Alvaro Herrera, Alexander
Korotkov, Michael Paquier
Discussion: https://postgr.es/m/a3acff50-5a0d-9a2c-b3b2-ee36168955c1@postgrespro.ru

src/common/archive.c [new file with mode: 0644] patch | blob
src/include/common/archive.h [new file with mode: 0644] patch | blob

diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index 188b73e75269897c01b03fa0685f7696bc0198aa..914ad340eae664ede12d513c79c2e69c1f7652b3 100644 (file)
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -21,6 +21,7 @@
#include "access/xlog.h"
#include "access/xlog_internal.h"
+#include "common/archive.h"
#include "miscadmin.h"
#include "postmaster/startup.h"
#include "replication/walsender.h"
@@ -53,11 +54,8 @@ RestoreArchivedFile(char *path, const char *xlogfname,
bool cleanupEnabled)
{
char xlogpath[MAXPGPATH];
- char xlogRestoreCmd[MAXPGPATH];
+ char *xlogRestoreCmd;
char lastRestartPointFname[MAXPGPATH];
- char *dp;
- char *endp;
- const char *sp;
int rc;
struct stat stat_buf;
XLogSegNo restartSegNo;
@@ -149,58 +147,13 @@ RestoreArchivedFile(char *path, const char *xlogfname,
else
XLogFileName(lastRestartPointFname, 0, 0L, wal_segment_size);
- /*
- * construct the command to be executed
- */
- dp = xlogRestoreCmd;
- endp = xlogRestoreCmd + MAXPGPATH - 1;
- *endp = '0円';
-
- for (sp = recoveryRestoreCommand; *sp; sp++)
- {
- if (*sp == '%')
- {
- switch (sp[1])
- {
- case 'p':
- /* %p: relative path of target file */
- sp++;
- StrNCpy(dp, xlogpath, endp - dp);
- make_native_path(dp);
- dp += strlen(dp);
- break;
- case 'f':
- /* %f: filename of desired file */
- sp++;
- StrNCpy(dp, xlogfname, endp - dp);
- dp += strlen(dp);
- break;
- case 'r':
- /* %r: filename of last restartpoint */
- sp++;
- StrNCpy(dp, lastRestartPointFname, endp - dp);
- dp += strlen(dp);
- break;
- case '%':
- /* convert %% to a single % */
- sp++;
- if (dp < endp)
- *dp++ = *sp;
- break;
- default:
- /* otherwise treat the % as not special */
- if (dp < endp)
- *dp++ = *sp;
- break;
- }
- }
- else
- {
- if (dp < endp)
- *dp++ = *sp;
- }
- }
- *dp = '0円';
+ /* Build the restore command to execute */
+ xlogRestoreCmd = BuildRestoreCommand(recoveryRestoreCommand,
+ xlogpath, xlogfname,
+ lastRestartPointFname);
+ if (xlogRestoreCmd == NULL)
+ elog(ERROR, "could not build restore command \"%s\"",
+ recoveryRestoreCommand);
ereport(DEBUG3,
(errmsg_internal("executing restore command \"%s\"",
@@ -217,6 +170,7 @@ RestoreArchivedFile(char *path, const char *xlogfname,
rc = system(xlogRestoreCmd);
PostRestoreCommand();
+ pfree(xlogRestoreCmd);
if (rc == 0)
{
diff --git a/src/common/Makefile b/src/common/Makefile
index ce01df68b975ec3ba4d4e2e29d235c2663774c9f..6939b9d08742685715da827ba1a4fdb9454c9bf1 100644 (file)
--- a/src/common/Makefile
+++ b/src/common/Makefile
@@ -46,6 +46,7 @@ LIBS += $(PTHREAD_LIBS)
# If you add objects here, see also src/tools/msvc/Mkvcbuild.pm
OBJS_COMMON = \
+ archive.o \
base64.o \
config_info.o \
controldata_utils.o \
diff --git a/src/common/archive.c b/src/common/archive.c
new file mode 100644 (file)
index 0000000..a94e4d0
--- /dev/null
+++ b/src/common/archive.c
@@ -0,0 +1,121 @@
+/*-------------------------------------------------------------------------
+ *
+ * archive.c
+ * Common WAL archive routines
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * src/common/archive.c
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef FRONTEND
+#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
+
+#include "common/archive.h"
+#include "lib/stringinfo.h"
+
+/*
+ * BuildRestoreCommand
+ *
+ * Builds a restore command to retrieve a file from WAL archives, replacing
+ * the supported aliases with values supplied by the caller as defined by
+ * the GUC parameter restore_command: xlogpath for %p, xlogfname for %f and
+ * lastRestartPointFname for %r.
+ *
+ * The result is a palloc'd string for the restore command built. The
+ * caller is responsible for freeing it. If any of the required arguments
+ * is NULL and that the corresponding alias is found in the command given
+ * by the caller, then NULL is returned.
+ */
+char *
+BuildRestoreCommand(const char *restoreCommand,
+ const char *xlogpath,
+ const char *xlogfname,
+ const char *lastRestartPointFname)
+{
+ StringInfoData result;
+ const char *sp;
+
+ /*
+ * Build the command to be executed.
+ */
+ initStringInfo(&result);
+
+ for (sp = restoreCommand; *sp; sp++)
+ {
+ if (*sp == '%')
+ {
+ switch (sp[1])
+ {
+ case 'p':
+ {
+ char *nativePath;
+
+ /* %p: relative path of target file */
+ if (xlogpath == NULL)
+ {
+ pfree(result.data);
+ return NULL;
+ }
+ sp++;
+
+ /*
+ * This needs to use a placeholder to not modify the
+ * input with the conversion done via
+ * make_native_path().
+ */
+ nativePath = pstrdup(xlogpath);
+ make_native_path(nativePath);
+ appendStringInfoString(&result,
+ nativePath);
+ pfree(nativePath);
+ break;
+ }
+ case 'f':
+ /* %f: filename of desired file */
+ if (xlogfname == NULL)
+ {
+ pfree(result.data);
+ return NULL;
+ }
+ sp++;
+ appendStringInfoString(&result, xlogfname);
+ break;
+ case 'r':
+ /* %r: filename of last restartpoint */
+ if (lastRestartPointFname == NULL)
+ {
+ pfree(result.data);
+ return NULL;
+ }
+ sp++;
+ appendStringInfoString(&result,
+ lastRestartPointFname);
+ break;
+ case '%':
+ /* convert %% to a single % */
+ sp++;
+ appendStringInfoChar(&result, *sp);
+ break;
+ default:
+ /* otherwise treat the % as not special */
+ appendStringInfoChar(&result, *sp);
+ break;
+ }
+ }
+ else
+ {
+ appendStringInfoChar(&result, *sp);
+ }
+ }
+
+ return result.data;
+}
diff --git a/src/include/common/archive.h b/src/include/common/archive.h
new file mode 100644 (file)
index 0000000..b269910
--- /dev/null
+++ b/src/include/common/archive.h
@@ -0,0 +1,21 @@
+/*-------------------------------------------------------------------------
+ *
+ * archive.h
+ * Common WAL archive routines
+ *
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/common/archive.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef ARCHIVE_H
+#define ARCHIVE_H
+
+extern char *BuildRestoreCommand(const char *restoreCommand,
+ const char *xlogpath, /* %p */
+ const char *xlogfname, /* %f */
+ const char *lastRestartPointFname); /* %r */
+
+#endif /* ARCHIVE_H */
diff --git a/src/tools/msvc/Mkvcbuild.pm b/src/tools/msvc/Mkvcbuild.pm
index f89a8a4fdb711afe2689e233ee365905ea9ad3fb..636428b04482c3214d586838d25d2b65ee2a405f 100644 (file)
--- a/src/tools/msvc/Mkvcbuild.pm
+++ b/src/tools/msvc/Mkvcbuild.pm
@@ -120,6 +120,7 @@ sub mkvcbuild
}
our @pgcommonallfiles = qw(
+ archive.c
base64.c config_info.c controldata_utils.c d2s.c encnames.c exec.c
f2s.c file_perm.c hashfn.c ip.c jsonapi.c
keywords.c kwlookup.c link-canary.c md5.c
This is the main PostgreSQL git repository.
RSS Atom

AltStyle によって変換されたページ (->オリジナル) /