Skip to content

Commit 14bdb3f

Browse files
committed
Refactor code for restoring files via shell commands
Presently, restore_command uses a different code path than archive_cleanup_command and recovery_end_command. These code paths are similar and can be easily combined, as long as it is possible to identify if a command should: - Issue a FATAL on signal. - Exit immediately on SIGTERM. While on it, this removes src/common/archive.c and its associated header. Since the introduction of c96de2c, BuildRestoreCommand() has become a simple wrapper of replace_percent_placeholders() able to call make_native_path(). This simplifies shell_restore.c as long as RestoreArchivedFile() includes a call to make_native_path(). Author: Nathan Bossart Reviewed-by: Andres Freund, Michael Paquier Discussion: https://postgr.es/m/20221227192449.GA3672473@nathanxps13
1 parent 2f31f40 commit 14bdb3f

File tree

8 files changed

+56
-139
lines changed

8 files changed

+56
-139
lines changed

src/backend/access/transam/shell_restore.c

Lines changed: 47 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,16 @@
2020

2121
#include "access/xlogarchive.h"
2222
#include "access/xlogrecovery.h"
23-
#include "common/archive.h"
2423
#include "common/percentrepl.h"
2524
#include "storage/ipc.h"
2625
#include "utils/wait_event.h"
2726

28-
static void ExecuteRecoveryCommand(const char *command,
27+
static bool ExecuteRecoveryCommand(const char *command,
2928
const char *commandName,
3029
bool failOnSignal,
30+
bool exitOnSigterm,
3131
uint32 wait_event_info,
32-
const char *lastRestartPointFileName);
32+
int fail_elevel);
3333

3434
/*
3535
* Attempt to execute a shell-based restore command.
@@ -40,25 +40,17 @@ bool
4040
shell_restore(const char *file, const char *path,
4141
const char *lastRestartPointFileName)
4242
{
43+
char *nativePath = pstrdup(path);
4344
char *cmd;
44-
int rc;
45+
bool ret;
4546

4647
/* Build the restore command to execute */
47-
cmd = BuildRestoreCommand(recoveryRestoreCommand, path, file,
48-
lastRestartPointFileName);
49-
50-
ereport(DEBUG3,
51-
(errmsg_internal("executing restore command \"%s\"", cmd)));
52-
53-
/*
54-
* Copy xlog from archival storage to XLOGDIR
55-
*/
56-
fflush(NULL);
57-
pgstat_report_wait_start(WAIT_EVENT_RESTORE_COMMAND);
58-
rc = system(cmd);
59-
pgstat_report_wait_end();
60-
61-
pfree(cmd);
48+
make_native_path(nativePath);
49+
cmd = replace_percent_placeholders(recoveryRestoreCommand,
50+
"restore_command", "frp", file,
51+
lastRestartPointFileName,
52+
nativePath);
53+
pfree(nativePath);
6254

6355
/*
6456
* Remember, we rollforward UNTIL the restore fails so failure here is
@@ -84,17 +76,13 @@ shell_restore(const char *file, const char *path,
8476
*
8577
* We treat hard shell errors such as "command not found" as fatal, too.
8678
*/
87-
if (rc != 0)
88-
{
89-
if (wait_result_is_signal(rc, SIGTERM))
90-
proc_exit(1);
91-
92-
ereport(wait_result_is_any_signal(rc, true) ? FATAL : DEBUG2,
93-
(errmsg("could not restore file \"%s\" from archive: %s",
94-
file, wait_result_to_str(rc))));
95-
}
79+
ret = ExecuteRecoveryCommand(cmd, "restore_command",
80+
true, /* failOnSignal */
81+
true, /* exitOnSigterm */
82+
WAIT_EVENT_RESTORE_COMMAND, DEBUG2);
83+
pfree(cmd);
9684

97-
return (rc == 0);
85+
return ret;
9886
}
9987

10088
/*
@@ -103,9 +91,14 @@ shell_restore(const char *file, const char *path,
10391
void
10492
shell_archive_cleanup(const char *lastRestartPointFileName)
10593
{
106-
ExecuteRecoveryCommand(archiveCleanupCommand, "archive_cleanup_command",
107-
false, WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND,
108-
lastRestartPointFileName);
94+
char *cmd;
95+
96+
cmd = replace_percent_placeholders(archiveCleanupCommand,
97+
"archive_cleanup_command",
98+
"r", lastRestartPointFileName);
99+
(void) ExecuteRecoveryCommand(cmd, "archive_cleanup_command", false, false,
100+
WAIT_EVENT_ARCHIVE_CLEANUP_COMMAND, WARNING);
101+
pfree(cmd);
109102
}
110103

111104
/*
@@ -114,9 +107,14 @@ shell_archive_cleanup(const char *lastRestartPointFileName)
114107
void
115108
shell_recovery_end(const char *lastRestartPointFileName)
116109
{
117-
ExecuteRecoveryCommand(recoveryEndCommand, "recovery_end_command", true,
118-
WAIT_EVENT_RECOVERY_END_COMMAND,
119-
lastRestartPointFileName);
110+
char *cmd;
111+
112+
cmd = replace_percent_placeholders(recoveryEndCommand,
113+
"recovery_end_command",
114+
"r", lastRestartPointFileName);
115+
(void) ExecuteRecoveryCommand(cmd, "recovery_end_command", true, false,
116+
WAIT_EVENT_RECOVERY_END_COMMAND, WARNING);
117+
pfree(cmd);
120118
}
121119

122120
/*
@@ -125,26 +123,21 @@ shell_recovery_end(const char *lastRestartPointFileName)
125123
* 'command' is the shell command to be executed, 'commandName' is a
126124
* human-readable name describing the command emitted in the logs. If
127125
* 'failOnSignal' is true and the command is killed by a signal, a FATAL
128-
* error is thrown. Otherwise a WARNING is emitted.
126+
* error is thrown. Otherwise, 'fail_elevel' is used for the log message.
127+
* If 'exitOnSigterm' is true and the command is killed by SIGTERM, we exit
128+
* immediately.
129129
*
130-
* This is currently used for recovery_end_command and archive_cleanup_command.
130+
* Returns whether the command succeeded.
131131
*/
132-
static void
132+
static bool
133133
ExecuteRecoveryCommand(const char *command, const char *commandName,
134-
bool failOnSignal, uint32 wait_event_info,
135-
const char *lastRestartPointFileName)
134+
bool failOnSignal, bool exitOnSigterm,
135+
uint32 wait_event_info, int fail_elevel)
136136
{
137-
char *xlogRecoveryCmd;
138137
int rc;
139138

140139
Assert(command && commandName);
141140

142-
/*
143-
* construct the command to be executed
144-
*/
145-
xlogRecoveryCmd = replace_percent_placeholders(command, commandName, "r",
146-
lastRestartPointFileName);
147-
148141
ereport(DEBUG3,
149142
(errmsg_internal("executing %s \"%s\"", commandName, command)));
150143

@@ -153,23 +146,26 @@ ExecuteRecoveryCommand(const char *command, const char *commandName,
153146
*/
154147
fflush(NULL);
155148
pgstat_report_wait_start(wait_event_info);
156-
rc = system(xlogRecoveryCmd);
149+
rc = system(command);
157150
pgstat_report_wait_end();
158151

159-
pfree(xlogRecoveryCmd);
160-
161152
if (rc != 0)
162153
{
154+
if (exitOnSigterm && wait_result_is_signal(rc, SIGTERM))
155+
proc_exit(1);
156+
163157
/*
164158
* If the failure was due to any sort of signal, it's best to punt and
165159
* abort recovery. See comments in shell_restore().
166160
*/
167-
ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : WARNING,
161+
ereport((failOnSignal && wait_result_is_any_signal(rc, true)) ? FATAL : fail_elevel,
168162
/*------
169163
translator: First %s represents a postgresql.conf parameter name like
170164
"recovery_end_command", the 2nd is the value of that parameter, the
171165
third an already translated error message. */
172166
(errmsg("%s \"%s\": %s", commandName,
173167
command, wait_result_to_str(rc))));
174168
}
169+
170+
return (rc == 0);
175171
}

src/backend/access/transam/xlogarchive.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
#include "access/xlog.h"
2323
#include "access/xlog_internal.h"
2424
#include "access/xlogarchive.h"
25-
#include "common/archive.h"
2625
#include "miscadmin.h"
2726
#include "pgstat.h"
2827
#include "postmaster/startup.h"

src/common/Makefile

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

4848
OBJS_COMMON = \
49-
archive.o \
5049
base64.o \
5150
checksum_helper.o \
5251
compression.o \

src/common/archive.c

Lines changed: 0 additions & 60 deletions
This file was deleted.

src/common/meson.build

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# Copyright (c) 2022-2023, PostgreSQL Global Development Group
22

33
common_sources = files(
4-
'archive.c',
54
'base64.c',
65
'checksum_helper.c',
76
'compression.c',

src/fe_utils/archive.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
#include <sys/stat.h>
2020

2121
#include "access/xlog_internal.h"
22-
#include "common/archive.h"
2322
#include "common/logging.h"
23+
#include "common/percentrepl.h"
2424
#include "fe_utils/archive.h"
2525

2626

@@ -41,13 +41,18 @@ RestoreArchivedFile(const char *path, const char *xlogfname,
4141
{
4242
char xlogpath[MAXPGPATH];
4343
char *xlogRestoreCmd;
44+
char *nativePath;
4445
int rc;
4546
struct stat stat_buf;
4647

4748
snprintf(xlogpath, MAXPGPATH, "%s/" XLOGDIR "/%s", path, xlogfname);
4849

49-
xlogRestoreCmd = BuildRestoreCommand(restoreCommand, xlogpath,
50-
xlogfname, NULL);
50+
nativePath = pstrdup(xlogpath);
51+
make_native_path(nativePath);
52+
xlogRestoreCmd = replace_percent_placeholders(restoreCommand,
53+
"restore_command", "fp",
54+
xlogfname, nativePath);
55+
pfree(nativePath);
5156

5257
/*
5358
* Execute restore_command, which should copy the missing file from

src/include/common/archive.h

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/tools/msvc/Mkvcbuild.pm

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ sub mkvcbuild
133133
}
134134

135135
our @pgcommonallfiles = qw(
136-
archive.c base64.c checksum_helper.c compression.c
136+
base64.c checksum_helper.c compression.c
137137
config_info.c controldata_utils.c d2s.c encnames.c exec.c
138138
f2s.c file_perm.c file_utils.c hashfn.c ip.c jsonapi.c
139139
keywords.c kwlookup.c link-canary.c md5_common.c percentrepl.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