Skip to content

Commit e09ad07

Browse files
committed
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
1 parent b8e20d6 commit e09ad07

File tree

5 files changed

+154
-56
lines changed

5 files changed

+154
-56
lines changed

src/backend/access/transam/xlogarchive.c

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include "access/xlog.h"
2323
#include "access/xlog_internal.h"
24+
#include "common/archive.h"
2425
#include "miscadmin.h"
2526
#include "postmaster/startup.h"
2627
#include "replication/walsender.h"
@@ -53,11 +54,8 @@ RestoreArchivedFile(char *path, const char *xlogfname,
5354
bool cleanupEnabled)
5455
{
5556
char xlogpath[MAXPGPATH];
56-
char xlogRestoreCmd[MAXPGPATH];
57+
char *xlogRestoreCmd;
5758
char lastRestartPointFname[MAXPGPATH];
58-
char *dp;
59-
char *endp;
60-
const char *sp;
6159
int rc;
6260
struct stat stat_buf;
6361
XLogSegNo restartSegNo;
@@ -149,58 +147,13 @@ RestoreArchivedFile(char *path, const char *xlogfname,
149147
else
150148
XLogFileName(lastRestartPointFname, 0, 0L, wal_segment_size);
151149

152-
/*
153-
* construct the command to be executed
154-
*/
155-
dp = xlogRestoreCmd;
156-
endp = xlogRestoreCmd + MAXPGPATH - 1;
157-
*endp = '\0';
158-
159-
for (sp = recoveryRestoreCommand; *sp; sp++)
160-
{
161-
if (*sp == '%')
162-
{
163-
switch (sp[1])
164-
{
165-
case 'p':
166-
/* %p: relative path of target file */
167-
sp++;
168-
StrNCpy(dp, xlogpath, endp - dp);
169-
make_native_path(dp);
170-
dp += strlen(dp);
171-
break;
172-
case 'f':
173-
/* %f: filename of desired file */
174-
sp++;
175-
StrNCpy(dp, xlogfname, endp - dp);
176-
dp += strlen(dp);
177-
break;
178-
case 'r':
179-
/* %r: filename of last restartpoint */
180-
sp++;
181-
StrNCpy(dp, lastRestartPointFname, endp - dp);
182-
dp += strlen(dp);
183-
break;
184-
case '%':
185-
/* convert %% to a single % */
186-
sp++;
187-
if (dp < endp)
188-
*dp++ = *sp;
189-
break;
190-
default:
191-
/* otherwise treat the % as not special */
192-
if (dp < endp)
193-
*dp++ = *sp;
194-
break;
195-
}
196-
}
197-
else
198-
{
199-
if (dp < endp)
200-
*dp++ = *sp;
201-
}
202-
}
203-
*dp = '\0';
150+
/* Build the restore command to execute */
151+
xlogRestoreCmd = BuildRestoreCommand(recoveryRestoreCommand,
152+
xlogpath, xlogfname,
153+
lastRestartPointFname);
154+
if (xlogRestoreCmd == NULL)
155+
elog(ERROR, "could not build restore command \"%s\"",
156+
recoveryRestoreCommand);
204157

205158
ereport(DEBUG3,
206159
(errmsg_internal("executing restore command \"%s\"",
@@ -217,6 +170,7 @@ RestoreArchivedFile(char *path, const char *xlogfname,
217170
rc = system(xlogRestoreCmd);
218171

219172
PostRestoreCommand();
173+
pfree(xlogRestoreCmd);
220174

221175
if (rc == 0)
222176
{

src/common/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ LIBS += $(PTHREAD_LIBS)
4646
# If you add objects here, see also src/tools/msvc/Mkvcbuild.pm
4747

4848
OBJS_COMMON = \
49+
archive.o \
4950
base64.o \
5051
config_info.o \
5152
controldata_utils.o \

src/common/archive.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* archive.c
4+
* Common WAL archive routines
5+
*
6+
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
*
10+
* IDENTIFICATION
11+
* src/common/archive.c
12+
*
13+
*-------------------------------------------------------------------------
14+
*/
15+
16+
#ifndef FRONTEND
17+
#include "postgres.h"
18+
#else
19+
#include "postgres_fe.h"
20+
#endif
21+
22+
#include "common/archive.h"
23+
#include "lib/stringinfo.h"
24+
25+
/*
26+
* BuildRestoreCommand
27+
*
28+
* Builds a restore command to retrieve a file from WAL archives, replacing
29+
* the supported aliases with values supplied by the caller as defined by
30+
* the GUC parameter restore_command: xlogpath for %p, xlogfname for %f and
31+
* lastRestartPointFname for %r.
32+
*
33+
* The result is a palloc'd string for the restore command built. The
34+
* caller is responsible for freeing it. If any of the required arguments
35+
* is NULL and that the corresponding alias is found in the command given
36+
* by the caller, then NULL is returned.
37+
*/
38+
char *
39+
BuildRestoreCommand(const char *restoreCommand,
40+
const char *xlogpath,
41+
const char *xlogfname,
42+
const char *lastRestartPointFname)
43+
{
44+
StringInfoData result;
45+
const char *sp;
46+
47+
/*
48+
* Build the command to be executed.
49+
*/
50+
initStringInfo(&result);
51+
52+
for (sp = restoreCommand; *sp; sp++)
53+
{
54+
if (*sp == '%')
55+
{
56+
switch (sp[1])
57+
{
58+
case 'p':
59+
{
60+
char *nativePath;
61+
62+
/* %p: relative path of target file */
63+
if (xlogpath == NULL)
64+
{
65+
pfree(result.data);
66+
return NULL;
67+
}
68+
sp++;
69+
70+
/*
71+
* This needs to use a placeholder to not modify the
72+
* input with the conversion done via
73+
* make_native_path().
74+
*/
75+
nativePath = pstrdup(xlogpath);
76+
make_native_path(nativePath);
77+
appendStringInfoString(&result,
78+
nativePath);
79+
pfree(nativePath);
80+
break;
81+
}
82+
case 'f':
83+
/* %f: filename of desired file */
84+
if (xlogfname == NULL)
85+
{
86+
pfree(result.data);
87+
return NULL;
88+
}
89+
sp++;
90+
appendStringInfoString(&result, xlogfname);
91+
break;
92+
case 'r':
93+
/* %r: filename of last restartpoint */
94+
if (lastRestartPointFname == NULL)
95+
{
96+
pfree(result.data);
97+
return NULL;
98+
}
99+
sp++;
100+
appendStringInfoString(&result,
101+
lastRestartPointFname);
102+
break;
103+
case '%':
104+
/* convert %% to a single % */
105+
sp++;
106+
appendStringInfoChar(&result, *sp);
107+
break;
108+
default:
109+
/* otherwise treat the % as not special */
110+
appendStringInfoChar(&result, *sp);
111+
break;
112+
}
113+
}
114+
else
115+
{
116+
appendStringInfoChar(&result, *sp);
117+
}
118+
}
119+
120+
return result.data;
121+
}

src/include/common/archive.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* archive.h
4+
* Common WAL archive routines
5+
*
6+
* Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
7+
* Portions Copyright (c) 1994, Regents of the University of California
8+
*
9+
* src/include/common/archive.h
10+
*
11+
*-------------------------------------------------------------------------
12+
*/
13+
#ifndef ARCHIVE_H
14+
#define ARCHIVE_H
15+
16+
extern char *BuildRestoreCommand(const char *restoreCommand,
17+
const char *xlogpath, /* %p */
18+
const char *xlogfname, /* %f */
19+
const char *lastRestartPointFname); /* %r */
20+
21+
#endif /* ARCHIVE_H */

src/tools/msvc/Mkvcbuild.pm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ sub mkvcbuild
120120
}
121121

122122
our @pgcommonallfiles = qw(
123+
archive.c
123124
base64.c config_info.c controldata_utils.c d2s.c encnames.c exec.c
124125
f2s.c file_perm.c hashfn.c ip.c jsonapi.c
125126
keywords.c kwlookup.c link-canary.c md5.c

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy