mirror of
https://github.com/postgres/postgres.git
synced 2025-04-29 13:56:47 +03:00
Move routine building restore_command to src/common/
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
This commit is contained in:
parent
b8e20d6dab
commit
e09ad07b21
@ -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)
|
||||
{
|
||||
|
@ -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 \
|
||||
|
121
src/common/archive.c
Normal file
121
src/common/archive.c
Normal file
@ -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;
|
||||
}
|
21
src/include/common/archive.h
Normal file
21
src/include/common/archive.h
Normal file
@ -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 */
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user