PostgreSQL Source Code git master
Loading...
Searching...
No Matches
shell_archive.c
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * shell_archive.c
4 *
5 * This archiving function uses a user-specified shell command (the
6 * archive_command GUC) to copy write-ahead log files. It is used as the
7 * default, but other modules may define their own custom archiving logic.
8 *
9 * Copyright (c) 2022-2026, PostgreSQL Global Development Group
10 *
11 * IDENTIFICATION
12 * src/backend/archive/shell_archive.c
13 *
14 *-------------------------------------------------------------------------
15 */
16#include "postgres.h"
17
18#include <sys/wait.h>
19
20#include "access/xlog.h"
23#include "common/percentrepl.h"
24#include "pgstat.h"
25#include "utils/wait_event.h"
26
29 const char *file,
30 const char *path);
32
35 .check_configured_cb = shell_archive_configured,
36 .archive_file_cb = shell_archive_file,
37 .shutdown_cb = shell_archive_shutdown
38};
39
45
46static bool
48{
49 if (XLogArchiveCommand[0] != '\0')
50 return true;
51
52 arch_module_check_errdetail("\"%s\" is not set.",
53 "archive_command");
54 return false;
55}
56
57static bool
59 const char *path)
60{
61 char *xlogarchcmd;
62 char *nativePath = NULL;
63 int rc;
64
65 if (path)
66 {
67 nativePath = pstrdup(path);
69 }
70
72 "archive_command", "fp",
73 file, nativePath);
74
76 (errmsg_internal("executing archive command \"%s\"",
77 xlogarchcmd)));
78
79 fflush(NULL);
81 rc = system(xlogarchcmd);
83
84 if (rc != 0)
85 {
86 /*
87 * If either the shell itself, or a called command, died on a signal,
88 * abort the archiver. We do this because system() ignores SIGINT and
89 * SIGQUIT while waiting; so a signal is very likely something that
90 * should have interrupted us too. Also die if the shell got a hard
91 * "command not found" type of error. If we overreact it's no big
92 * deal, the postmaster will just start the archiver again.
93 */
94 int lev = wait_result_is_any_signal(rc, true) ? FATAL : LOG;
95
96 if (WIFEXITED(rc))
97 {
99 (errmsg("archive command failed with exit code %d",
100 WEXITSTATUS(rc)),
101 errdetail("The failed archive command was: %s",
102 xlogarchcmd)));
103 }
104 else if (WIFSIGNALED(rc))
105 {
106#if defined(WIN32)
107 ereport(lev,
108 (errmsg("archive command was terminated by exception 0x%X",
109 WTERMSIG(rc)),
110 errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
111 errdetail("The failed archive command was: %s",
112 xlogarchcmd)));
113#else
114 ereport(lev,
115 (errmsg("archive command was terminated by signal %d: %s",
116 WTERMSIG(rc), pg_strsignal(WTERMSIG(rc))),
117 errdetail("The failed archive command was: %s",
118 xlogarchcmd)));
119#endif
120 }
121 else
122 {
123 ereport(lev,
124 (errmsg("archive command exited with unrecognized status %d",
125 rc),
126 errdetail("The failed archive command was: %s",
127 xlogarchcmd)));
128 }
130
131 return false;
132 }
134
135 elog(DEBUG1, "archived write-ahead log file \"%s\"", file);
136 return true;
137}
138
139static void
141{
142 elog(DEBUG1, "archiver process shutting down");
143}
#define arch_module_check_errdetail
#define LOG
Definition elog.h:31
int errhint(const char *fmt,...) pg_attribute_printf(1
#define DEBUG3
Definition elog.h:28
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:41
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
#define DEBUG1
Definition elog.h:30
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
char * pstrdup(const char *in)
Definition mcxt.c:1781
void pfree(void *pointer)
Definition mcxt.c:1616
static char * errmsg
char * replace_percent_placeholders(const char *instr, const char *param_name, const char *letters,...)
Definition percentrepl.c:59
const char * pg_strsignal(int signum)
Definition pgstrsignal.c:39
void make_native_path(char *filename)
Definition path.c:236
static int fb(int x)
static void shell_archive_shutdown(ArchiveModuleState *state)
static const ArchiveModuleCallbacks shell_archive_callbacks
const ArchiveModuleCallbacks * shell_archive_init(void)
static bool shell_archive_configured(ArchiveModuleState *state)
static bool shell_archive_file(ArchiveModuleState *state, const char *file, const char *path)
ArchiveStartupCB startup_cb
bool wait_result_is_any_signal(int exit_status, bool include_command_not_found)
Definition wait_error.c:121
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition wait_event.h:69
static void pgstat_report_wait_end(void)
Definition wait_event.h:85
#define WIFEXITED(w)
Definition win32_port.h:150
#define WIFSIGNALED(w)
Definition win32_port.h:151
#define WTERMSIG(w)
Definition win32_port.h:153
#define WEXITSTATUS(w)
Definition win32_port.h:152
char * XLogArchiveCommand
Definition xlog.c:124