20
20
21
21
#include "access/xlogarchive.h"
22
22
#include "access/xlogrecovery.h"
23
- #include "common/archive.h"
24
23
#include "common/percentrepl.h"
25
24
#include "storage/ipc.h"
26
25
#include "utils/wait_event.h"
27
26
28
- static void ExecuteRecoveryCommand (const char * command ,
27
+ static bool ExecuteRecoveryCommand (const char * command ,
29
28
const char * commandName ,
30
29
bool failOnSignal ,
30
+ bool exitOnSigterm ,
31
31
uint32 wait_event_info ,
32
- const char * lastRestartPointFileName );
32
+ int fail_elevel );
33
33
34
34
/*
35
35
* Attempt to execute a shell-based restore command.
40
40
shell_restore (const char * file , const char * path ,
41
41
const char * lastRestartPointFileName )
42
42
{
43
+ char * nativePath = pstrdup (path );
43
44
char * cmd ;
44
- int rc ;
45
+ bool ret ;
45
46
46
47
/* 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 );
62
54
63
55
/*
64
56
* Remember, we rollforward UNTIL the restore fails so failure here is
@@ -84,17 +76,13 @@ shell_restore(const char *file, const char *path,
84
76
*
85
77
* We treat hard shell errors such as "command not found" as fatal, too.
86
78
*/
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 );
96
84
97
- return ( rc == 0 ) ;
85
+ return ret ;
98
86
}
99
87
100
88
/*
@@ -103,9 +91,14 @@ shell_restore(const char *file, const char *path,
103
91
void
104
92
shell_archive_cleanup (const char * lastRestartPointFileName )
105
93
{
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 );
109
102
}
110
103
111
104
/*
@@ -114,9 +107,14 @@ shell_archive_cleanup(const char *lastRestartPointFileName)
114
107
void
115
108
shell_recovery_end (const char * lastRestartPointFileName )
116
109
{
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 );
120
118
}
121
119
122
120
/*
@@ -125,26 +123,21 @@ shell_recovery_end(const char *lastRestartPointFileName)
125
123
* 'command' is the shell command to be executed, 'commandName' is a
126
124
* human-readable name describing the command emitted in the logs. If
127
125
* '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.
129
129
*
130
- * This is currently used for recovery_end_command and archive_cleanup_command .
130
+ * Returns whether the command succeeded .
131
131
*/
132
- static void
132
+ static bool
133
133
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 )
136
136
{
137
- char * xlogRecoveryCmd ;
138
137
int rc ;
139
138
140
139
Assert (command && commandName );
141
140
142
- /*
143
- * construct the command to be executed
144
- */
145
- xlogRecoveryCmd = replace_percent_placeholders (command , commandName , "r" ,
146
- lastRestartPointFileName );
147
-
148
141
ereport (DEBUG3 ,
149
142
(errmsg_internal ("executing %s \"%s\"" , commandName , command )));
150
143
@@ -153,23 +146,26 @@ ExecuteRecoveryCommand(const char *command, const char *commandName,
153
146
*/
154
147
fflush (NULL );
155
148
pgstat_report_wait_start (wait_event_info );
156
- rc = system (xlogRecoveryCmd );
149
+ rc = system (command );
157
150
pgstat_report_wait_end ();
158
151
159
- pfree (xlogRecoveryCmd );
160
-
161
152
if (rc != 0 )
162
153
{
154
+ if (exitOnSigterm && wait_result_is_signal (rc , SIGTERM ))
155
+ proc_exit (1 );
156
+
163
157
/*
164
158
* If the failure was due to any sort of signal, it's best to punt and
165
159
* abort recovery. See comments in shell_restore().
166
160
*/
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 ,
168
162
/*------
169
163
translator: First %s represents a postgresql.conf parameter name like
170
164
"recovery_end_command", the 2nd is the value of that parameter, the
171
165
third an already translated error message. */
172
166
(errmsg ("%s \"%s\": %s" , commandName ,
173
167
command , wait_result_to_str (rc ))));
174
168
}
169
+
170
+ return (rc == 0 );
175
171
}
0 commit comments