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.
4040shell_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,
10391void
10492shell_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)
114107void
115108shell_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
133133ExecuteRecoveryCommand (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}
0 commit comments