Consistently use "superuser" instead of "super user"
[pgsql.git] / src / bin / pg_basebackup / pg_basebackup.c
blob7296eb97d01c1b94db51cc9949b8c7fa9c0d6f5c
1 /*-------------------------------------------------------------------------
3 * pg_basebackup.c - receive a base backup using streaming replication protocol
5 * Author: Magnus Hagander <magnus@hagander.net>
7 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
9 * IDENTIFICATION
10 * src/bin/pg_basebackup/pg_basebackup.c
11 *-------------------------------------------------------------------------
14 #include "postgres_fe.h"
16 #include <unistd.h>
17 #include <dirent.h>
18 #include <limits.h>
19 #include <sys/stat.h>
20 #include <sys/wait.h>
21 #include <signal.h>
22 #include <time.h>
23 #ifdef HAVE_SYS_SELECT_H
24 #include <sys/select.h>
25 #endif
26 #ifdef HAVE_LIBZ
27 #include <zlib.h>
28 #endif
30 #include "access/xlog_internal.h"
31 #include "common/file_perm.h"
32 #include "common/file_utils.h"
33 #include "common/logging.h"
34 #include "common/string.h"
35 #include "fe_utils/option_utils.h"
36 #include "fe_utils/recovery_gen.h"
37 #include "fe_utils/string_utils.h"
38 #include "getopt_long.h"
39 #include "libpq-fe.h"
40 #include "pgtar.h"
41 #include "pgtime.h"
42 #include "pqexpbuffer.h"
43 #include "receivelog.h"
44 #include "replication/basebackup.h"
45 #include "streamutil.h"
47 #define ERRCODE_DATA_CORRUPTED "XX001"
49 typedef struct TablespaceListCell
51 struct TablespaceListCell *next;
52 char old_dir[MAXPGPATH];
53 char new_dir[MAXPGPATH];
54 } TablespaceListCell;
56 typedef struct TablespaceList
58 TablespaceListCell *head;
59 TablespaceListCell *tail;
60 } TablespaceList;
62 typedef struct WriteTarState
64 int tablespacenum;
65 char filename[MAXPGPATH];
66 FILE *tarfile;
67 char tarhdr[TAR_BLOCK_SIZE];
68 bool basetablespace;
69 bool in_tarhdr;
70 bool skip_file;
71 bool is_recovery_guc_supported;
72 bool is_postgresql_auto_conf;
73 bool found_postgresql_auto_conf;
74 int file_padding_len;
75 size_t tarhdrsz;
76 pgoff_t filesz;
77 #ifdef HAVE_LIBZ
78 gzFile ztarfile;
79 #endif
80 } WriteTarState;
82 typedef struct UnpackTarState
84 int tablespacenum;
85 char current_path[MAXPGPATH];
86 char filename[MAXPGPATH];
87 const char *mapped_tblspc_path;
88 pgoff_t current_len_left;
89 int current_padding;
90 FILE *file;
91 } UnpackTarState;
93 typedef struct WriteManifestState
95 char filename[MAXPGPATH];
96 FILE *file;
97 } WriteManifestState;
99 typedef void (*WriteDataCallback) (size_t nbytes, char *buf,
100 void *callback_data);
103 * pg_xlog has been renamed to pg_wal in version 10. This version number
104 * should be compared with PQserverVersion().
106 #define MINIMUM_VERSION_FOR_PG_WAL 100000
109 * Temporary replication slots are supported from version 10.
111 #define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
114 * Backup manifests are supported from version 13.
116 #define MINIMUM_VERSION_FOR_MANIFESTS 130000
119 * Different ways to include WAL
121 typedef enum
123 NO_WAL,
124 FETCH_WAL,
125 STREAM_WAL
126 } IncludeWal;
128 /* Global options */
129 static char *basedir = NULL;
130 static TablespaceList tablespace_dirs = {NULL, NULL};
131 static char *xlog_dir = NULL;
132 static char format = 'p'; /* p(lain)/t(ar) */
133 static char *label = "pg_basebackup base backup";
134 static bool noclean = false;
135 static bool checksum_failure = false;
136 static bool showprogress = false;
137 static bool estimatesize = true;
138 static int verbose = 0;
139 static int compresslevel = 0;
140 static IncludeWal includewal = STREAM_WAL;
141 static bool fastcheckpoint = false;
142 static bool writerecoveryconf = false;
143 static bool do_sync = true;
144 static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
145 static pg_time_t last_progress_report = 0;
146 static int32 maxrate = 0; /* no limit by default */
147 static char *replication_slot = NULL;
148 static bool temp_replication_slot = true;
149 static bool create_slot = false;
150 static bool no_slot = false;
151 static bool verify_checksums = true;
152 static bool manifest = true;
153 static bool manifest_force_encode = false;
154 static char *manifest_checksums = NULL;
156 static bool success = false;
157 static bool made_new_pgdata = false;
158 static bool found_existing_pgdata = false;
159 static bool made_new_xlogdir = false;
160 static bool found_existing_xlogdir = false;
161 static bool made_tablespace_dirs = false;
162 static bool found_tablespace_dirs = false;
164 /* Progress counters */
165 static uint64 totalsize_kb;
166 static uint64 totaldone;
167 static int tablespacecount;
169 /* Pipe to communicate with background wal receiver process */
170 #ifndef WIN32
171 static int bgpipe[2] = {-1, -1};
172 #endif
174 /* Handle to child process */
175 static pid_t bgchild = -1;
176 static bool in_log_streamer = false;
178 /* End position for xlog streaming, empty string if unknown yet */
179 static XLogRecPtr xlogendptr;
181 #ifndef WIN32
182 static int has_xlogendptr = 0;
183 #else
184 static volatile LONG has_xlogendptr = 0;
185 #endif
187 /* Contents of configuration file to be generated */
188 static PQExpBuffer recoveryconfcontents = NULL;
190 /* Function headers */
191 static void usage(void);
192 static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
193 static void progress_report(int tablespacenum, const char *filename, bool force,
194 bool finished);
196 static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum);
197 static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data);
198 static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum);
199 static void ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf,
200 void *callback_data);
201 static void ReceiveBackupManifest(PGconn *conn);
202 static void ReceiveBackupManifestChunk(size_t r, char *copybuf,
203 void *callback_data);
204 static void ReceiveBackupManifestInMemory(PGconn *conn, PQExpBuffer buf);
205 static void ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf,
206 void *callback_data);
207 static void BaseBackup(void);
209 static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline,
210 bool segment_finished);
212 static const char *get_tablespace_mapping(const char *dir);
213 static void tablespace_list_append(const char *arg);
216 static void
217 cleanup_directories_atexit(void)
219 if (success || in_log_streamer)
220 return;
222 if (!noclean && !checksum_failure)
224 if (made_new_pgdata)
226 pg_log_info("removing data directory \"%s\"", basedir);
227 if (!rmtree(basedir, true))
228 pg_log_error("failed to remove data directory");
230 else if (found_existing_pgdata)
232 pg_log_info("removing contents of data directory \"%s\"", basedir);
233 if (!rmtree(basedir, false))
234 pg_log_error("failed to remove contents of data directory");
237 if (made_new_xlogdir)
239 pg_log_info("removing WAL directory \"%s\"", xlog_dir);
240 if (!rmtree(xlog_dir, true))
241 pg_log_error("failed to remove WAL directory");
243 else if (found_existing_xlogdir)
245 pg_log_info("removing contents of WAL directory \"%s\"", xlog_dir);
246 if (!rmtree(xlog_dir, false))
247 pg_log_error("failed to remove contents of WAL directory");
250 else
252 if ((made_new_pgdata || found_existing_pgdata) && !checksum_failure)
253 pg_log_info("data directory \"%s\" not removed at user's request", basedir);
255 if (made_new_xlogdir || found_existing_xlogdir)
256 pg_log_info("WAL directory \"%s\" not removed at user's request", xlog_dir);
259 if ((made_tablespace_dirs || found_tablespace_dirs) && !checksum_failure)
260 pg_log_info("changes to tablespace directories will not be undone");
263 static void
264 disconnect_atexit(void)
266 if (conn != NULL)
267 PQfinish(conn);
270 #ifndef WIN32
272 * On windows, our background thread dies along with the process. But on
273 * Unix, if we have started a subprocess, we want to kill it off so it
274 * doesn't remain running trying to stream data.
276 static void
277 kill_bgchild_atexit(void)
279 if (bgchild > 0)
280 kill(bgchild, SIGTERM);
282 #endif
285 * Split argument into old_dir and new_dir and append to tablespace mapping
286 * list.
288 static void
289 tablespace_list_append(const char *arg)
291 TablespaceListCell *cell = (TablespaceListCell *) pg_malloc0(sizeof(TablespaceListCell));
292 char *dst;
293 char *dst_ptr;
294 const char *arg_ptr;
296 dst_ptr = dst = cell->old_dir;
297 for (arg_ptr = arg; *arg_ptr; arg_ptr++)
299 if (dst_ptr - dst >= MAXPGPATH)
301 pg_log_error("directory name too long");
302 exit(1);
305 if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
306 ; /* skip backslash escaping = */
307 else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
309 if (*cell->new_dir)
311 pg_log_error("multiple \"=\" signs in tablespace mapping");
312 exit(1);
314 else
315 dst = dst_ptr = cell->new_dir;
317 else
318 *dst_ptr++ = *arg_ptr;
321 if (!*cell->old_dir || !*cell->new_dir)
323 pg_log_error("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"", arg);
324 exit(1);
328 * This check isn't absolutely necessary. But all tablespaces are created
329 * with absolute directories, so specifying a non-absolute path here would
330 * just never match, possibly confusing users. It's also good to be
331 * consistent with the new_dir check.
333 if (!is_absolute_path(cell->old_dir))
335 pg_log_error("old directory is not an absolute path in tablespace mapping: %s",
336 cell->old_dir);
337 exit(1);
340 if (!is_absolute_path(cell->new_dir))
342 pg_log_error("new directory is not an absolute path in tablespace mapping: %s",
343 cell->new_dir);
344 exit(1);
348 * Comparisons done with these values should involve similarly
349 * canonicalized path values. This is particularly sensitive on Windows
350 * where path values may not necessarily use Unix slashes.
352 canonicalize_path(cell->old_dir);
353 canonicalize_path(cell->new_dir);
355 if (tablespace_dirs.tail)
356 tablespace_dirs.tail->next = cell;
357 else
358 tablespace_dirs.head = cell;
359 tablespace_dirs.tail = cell;
363 #ifdef HAVE_LIBZ
364 static const char *
365 get_gz_error(gzFile gzf)
367 int errnum;
368 const char *errmsg;
370 errmsg = gzerror(gzf, &errnum);
371 if (errnum == Z_ERRNO)
372 return strerror(errno);
373 else
374 return errmsg;
376 #endif
378 static void
379 usage(void)
381 printf(_("%s takes a base backup of a running PostgreSQL server.\n\n"),
382 progname);
383 printf(_("Usage:\n"));
384 printf(_(" %s [OPTION]...\n"), progname);
385 printf(_("\nOptions controlling the output:\n"));
386 printf(_(" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
387 printf(_(" -F, --format=p|t output format (plain (default), tar)\n"));
388 printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
389 " (in kB/s, or use suffix \"k\" or \"M\")\n"));
390 printf(_(" -R, --write-recovery-conf\n"
391 " write configuration for replication\n"));
392 printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
393 " relocate tablespace in OLDDIR to NEWDIR\n"));
394 printf(_(" --waldir=WALDIR location for the write-ahead log directory\n"));
395 printf(_(" -X, --wal-method=none|fetch|stream\n"
396 " include required WAL files with specified method\n"));
397 printf(_(" -z, --gzip compress tar output\n"));
398 printf(_(" -Z, --compress=0-9 compress tar output with given compression level\n"));
399 printf(_("\nGeneral options:\n"));
400 printf(_(" -c, --checkpoint=fast|spread\n"
401 " set fast or spread checkpointing\n"));
402 printf(_(" -C, --create-slot create replication slot\n"));
403 printf(_(" -l, --label=LABEL set backup label\n"));
404 printf(_(" -n, --no-clean do not clean up after errors\n"));
405 printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
406 printf(_(" -P, --progress show progress information\n"));
407 printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
408 printf(_(" -v, --verbose output verbose messages\n"));
409 printf(_(" -V, --version output version information, then exit\n"));
410 printf(_(" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
411 " use algorithm for manifest checksums\n"));
412 printf(_(" --manifest-force-encode\n"
413 " hex encode all file names in manifest\n"));
414 printf(_(" --no-estimate-size do not estimate backup size in server side\n"));
415 printf(_(" --no-manifest suppress generation of backup manifest\n"));
416 printf(_(" --no-slot prevent creation of temporary replication slot\n"));
417 printf(_(" --no-verify-checksums\n"
418 " do not verify checksums\n"));
419 printf(_(" -?, --help show this help, then exit\n"));
420 printf(_("\nConnection options:\n"));
421 printf(_(" -d, --dbname=CONNSTR connection string\n"));
422 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
423 printf(_(" -p, --port=PORT database server port number\n"));
424 printf(_(" -s, --status-interval=INTERVAL\n"
425 " time between status packets sent to server (in seconds)\n"));
426 printf(_(" -U, --username=NAME connect as specified database user\n"));
427 printf(_(" -w, --no-password never prompt for password\n"));
428 printf(_(" -W, --password force password prompt (should happen automatically)\n"));
429 printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
430 printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
435 * Called in the background process every time data is received.
436 * On Unix, we check to see if there is any data on our pipe
437 * (which would mean we have a stop position), and if it is, check if
438 * it is time to stop.
439 * On Windows, we are in a single process, so we can just check if it's
440 * time to stop.
442 static bool
443 reached_end_position(XLogRecPtr segendpos, uint32 timeline,
444 bool segment_finished)
446 if (!has_xlogendptr)
448 #ifndef WIN32
449 fd_set fds;
450 struct timeval tv;
451 int r;
454 * Don't have the end pointer yet - check our pipe to see if it has
455 * been sent yet.
457 FD_ZERO(&fds);
458 FD_SET(bgpipe[0], &fds);
460 MemSet(&tv, 0, sizeof(tv));
462 r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv);
463 if (r == 1)
465 char xlogend[64];
466 uint32 hi,
469 MemSet(xlogend, 0, sizeof(xlogend));
470 r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
471 if (r < 0)
473 pg_log_error("could not read from ready pipe: %m");
474 exit(1);
477 if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
479 pg_log_error("could not parse write-ahead log location \"%s\"",
480 xlogend);
481 exit(1);
483 xlogendptr = ((uint64) hi) << 32 | lo;
484 has_xlogendptr = 1;
487 * Fall through to check if we've reached the point further
488 * already.
491 else
494 * No data received on the pipe means we don't know the end
495 * position yet - so just say it's not time to stop yet.
497 return false;
499 #else
502 * On win32, has_xlogendptr is set by the main thread, so if it's not
503 * set here, we just go back and wait until it shows up.
505 return false;
506 #endif
510 * At this point we have an end pointer, so compare it to the current
511 * position to figure out if it's time to stop.
513 if (segendpos >= xlogendptr)
514 return true;
517 * Have end pointer, but haven't reached it yet - so tell the caller to
518 * keep streaming.
520 return false;
523 typedef struct
525 PGconn *bgconn;
526 XLogRecPtr startptr;
527 char xlog[MAXPGPATH]; /* directory or tarfile depending on mode */
528 char *sysidentifier;
529 int timeline;
530 } logstreamer_param;
532 static int
533 LogStreamerMain(logstreamer_param *param)
535 StreamCtl stream;
537 in_log_streamer = true;
539 MemSet(&stream, 0, sizeof(stream));
540 stream.startpos = param->startptr;
541 stream.timeline = param->timeline;
542 stream.sysidentifier = param->sysidentifier;
543 stream.stream_stop = reached_end_position;
544 #ifndef WIN32
545 stream.stop_socket = bgpipe[0];
546 #else
547 stream.stop_socket = PGINVALID_SOCKET;
548 #endif
549 stream.standby_message_timeout = standby_message_timeout;
550 stream.synchronous = false;
551 /* fsync happens at the end of pg_basebackup for all data */
552 stream.do_sync = false;
553 stream.mark_done = true;
554 stream.partial_suffix = NULL;
555 stream.replication_slot = replication_slot;
557 if (format == 'p')
558 stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0,
559 stream.do_sync);
560 else
561 stream.walmethod = CreateWalTarMethod(param->xlog, compresslevel,
562 stream.do_sync);
564 if (!ReceiveXlogStream(param->bgconn, &stream))
567 * Any errors will already have been reported in the function process,
568 * but we need to tell the parent that we didn't shutdown in a nice
569 * way.
571 return 1;
573 if (!stream.walmethod->finish())
575 pg_log_error("could not finish writing WAL files: %m");
576 return 1;
579 PQfinish(param->bgconn);
581 if (format == 'p')
582 FreeWalDirectoryMethod();
583 else
584 FreeWalTarMethod();
585 pg_free(stream.walmethod);
587 return 0;
591 * Initiate background process for receiving xlog during the backup.
592 * The background stream will use its own database connection so we can
593 * stream the logfile in parallel with the backups.
595 static void
596 StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
598 logstreamer_param *param;
599 uint32 hi,
601 char statusdir[MAXPGPATH];
603 param = pg_malloc0(sizeof(logstreamer_param));
604 param->timeline = timeline;
605 param->sysidentifier = sysidentifier;
607 /* Convert the starting position */
608 if (sscanf(startpos, "%X/%X", &hi, &lo) != 2)
610 pg_log_error("could not parse write-ahead log location \"%s\"",
611 startpos);
612 exit(1);
614 param->startptr = ((uint64) hi) << 32 | lo;
615 /* Round off to even segment position */
616 param->startptr -= XLogSegmentOffset(param->startptr, WalSegSz);
618 #ifndef WIN32
619 /* Create our background pipe */
620 if (pipe(bgpipe) < 0)
622 pg_log_error("could not create pipe for background process: %m");
623 exit(1);
625 #endif
627 /* Get a second connection */
628 param->bgconn = GetConnection();
629 if (!param->bgconn)
630 /* Error message already written in GetConnection() */
631 exit(1);
633 /* In post-10 cluster, pg_xlog has been renamed to pg_wal */
634 snprintf(param->xlog, sizeof(param->xlog), "%s/%s",
635 basedir,
636 PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
637 "pg_xlog" : "pg_wal");
639 /* Temporary replication slots are only supported in 10 and newer */
640 if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_TEMP_SLOTS)
641 temp_replication_slot = false;
644 * Create replication slot if requested
646 if (temp_replication_slot && !replication_slot)
647 replication_slot = psprintf("pg_basebackup_%d", (int) PQbackendPID(param->bgconn));
648 if (temp_replication_slot || create_slot)
650 if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL,
651 temp_replication_slot, true, true, false, false))
652 exit(1);
654 if (verbose)
656 if (temp_replication_slot)
657 pg_log_info("created temporary replication slot \"%s\"",
658 replication_slot);
659 else
660 pg_log_info("created replication slot \"%s\"",
661 replication_slot);
665 if (format == 'p')
668 * Create pg_wal/archive_status or pg_xlog/archive_status (and thus
669 * pg_wal or pg_xlog) depending on the target server so we can write
670 * to basedir/pg_wal or basedir/pg_xlog as the directory entry in the
671 * tar file may arrive later.
673 snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status",
674 basedir,
675 PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
676 "pg_xlog" : "pg_wal");
678 if (pg_mkdir_p(statusdir, pg_dir_create_mode) != 0 && errno != EEXIST)
680 pg_log_error("could not create directory \"%s\": %m", statusdir);
681 exit(1);
686 * Start a child process and tell it to start streaming. On Unix, this is
687 * a fork(). On Windows, we create a thread.
689 #ifndef WIN32
690 bgchild = fork();
691 if (bgchild == 0)
693 /* in child process */
694 exit(LogStreamerMain(param));
696 else if (bgchild < 0)
698 pg_log_error("could not create background process: %m");
699 exit(1);
703 * Else we are in the parent process and all is well.
705 atexit(kill_bgchild_atexit);
706 #else /* WIN32 */
707 bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
708 if (bgchild == 0)
710 pg_log_error("could not create background thread: %m");
711 exit(1);
713 #endif
717 * Verify that the given directory exists and is empty. If it does not
718 * exist, it is created. If it exists but is not empty, an error will
719 * be given and the process ended.
721 static void
722 verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
724 switch (pg_check_dir(dirname))
726 case 0:
729 * Does not exist, so create
731 if (pg_mkdir_p(dirname, pg_dir_create_mode) == -1)
733 pg_log_error("could not create directory \"%s\": %m", dirname);
734 exit(1);
736 if (created)
737 *created = true;
738 return;
739 case 1:
742 * Exists, empty
744 if (found)
745 *found = true;
746 return;
747 case 2:
748 case 3:
749 case 4:
752 * Exists, not empty
754 pg_log_error("directory \"%s\" exists but is not empty", dirname);
755 exit(1);
756 case -1:
759 * Access problem
761 pg_log_error("could not access directory \"%s\": %m", dirname);
762 exit(1);
768 * Print a progress report based on the global variables. If verbose output
769 * is enabled, also print the current file name.
771 * Progress report is written at maximum once per second, unless the force
772 * parameter is set to true.
774 * If finished is set to true, this is the last progress report. The cursor
775 * is moved to the next line.
777 static void
778 progress_report(int tablespacenum, const char *filename,
779 bool force, bool finished)
781 int percent;
782 char totaldone_str[32];
783 char totalsize_str[32];
784 pg_time_t now;
786 if (!showprogress)
787 return;
789 now = time(NULL);
790 if (now == last_progress_report && !force && !finished)
791 return; /* Max once per second */
793 last_progress_report = now;
794 percent = totalsize_kb ? (int) ((totaldone / 1024) * 100 / totalsize_kb) : 0;
797 * Avoid overflowing past 100% or the full size. This may make the total
798 * size number change as we approach the end of the backup (the estimate
799 * will always be wrong if WAL is included), but that's better than having
800 * the done column be bigger than the total.
802 if (percent > 100)
803 percent = 100;
804 if (totaldone / 1024 > totalsize_kb)
805 totalsize_kb = totaldone / 1024;
808 * Separate step to keep platform-dependent format code out of
809 * translatable strings. And we only test for INT64_FORMAT availability
810 * in snprintf, not fprintf.
812 snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT,
813 totaldone / 1024);
814 snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize_kb);
816 #define VERBOSE_FILENAME_LENGTH 35
817 if (verbose)
819 if (!filename)
822 * No filename given, so clear the status line (used for last
823 * call)
825 fprintf(stderr,
826 ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
827 "%*s/%s kB (100%%), %d/%d tablespaces %*s",
828 tablespacecount),
829 (int) strlen(totalsize_str),
830 totaldone_str, totalsize_str,
831 tablespacenum, tablespacecount,
832 VERBOSE_FILENAME_LENGTH + 5, "");
833 else
835 bool truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH);
837 fprintf(stderr,
838 ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
839 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
840 tablespacecount),
841 (int) strlen(totalsize_str),
842 totaldone_str, totalsize_str, percent,
843 tablespacenum, tablespacecount,
844 /* Prefix with "..." if we do leading truncation */
845 truncate ? "..." : "",
846 truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH,
847 truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH,
848 /* Truncate filename at beginning if it's too long */
849 truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename);
852 else
853 fprintf(stderr,
854 ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
855 "%*s/%s kB (%d%%), %d/%d tablespaces",
856 tablespacecount),
857 (int) strlen(totalsize_str),
858 totaldone_str, totalsize_str, percent,
859 tablespacenum, tablespacecount);
862 * Stay on the same line if reporting to a terminal and we're not done
863 * yet.
865 fputc((!finished && isatty(fileno(stderr))) ? '\r' : '\n', stderr);
868 static int32
869 parse_max_rate(char *src)
871 double result;
872 char *after_num;
873 char *suffix = NULL;
875 errno = 0;
876 result = strtod(src, &after_num);
877 if (src == after_num)
879 pg_log_error("transfer rate \"%s\" is not a valid value", src);
880 exit(1);
882 if (errno != 0)
884 pg_log_error("invalid transfer rate \"%s\": %m", src);
885 exit(1);
888 if (result <= 0)
891 * Reject obviously wrong values here.
893 pg_log_error("transfer rate must be greater than zero");
894 exit(1);
898 * Evaluate suffix, after skipping over possible whitespace. Lack of
899 * suffix means kilobytes.
901 while (*after_num != '\0' && isspace((unsigned char) *after_num))
902 after_num++;
904 if (*after_num != '\0')
906 suffix = after_num;
907 if (*after_num == 'k')
909 /* kilobyte is the expected unit. */
910 after_num++;
912 else if (*after_num == 'M')
914 after_num++;
915 result *= 1024.0;
919 /* The rest can only consist of white space. */
920 while (*after_num != '\0' && isspace((unsigned char) *after_num))
921 after_num++;
923 if (*after_num != '\0')
925 pg_log_error("invalid --max-rate unit: \"%s\"", suffix);
926 exit(1);
929 /* Valid integer? */
930 if ((uint64) result != (uint64) ((uint32) result))
932 pg_log_error("transfer rate \"%s\" exceeds integer range", src);
933 exit(1);
937 * The range is checked on the server side too, but avoid the server
938 * connection if a nonsensical value was passed.
940 if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
942 pg_log_error("transfer rate \"%s\" is out of range", src);
943 exit(1);
946 return (int32) result;
950 * Read a stream of COPY data and invoke the provided callback for each
951 * chunk.
953 static void
954 ReceiveCopyData(PGconn *conn, WriteDataCallback callback,
955 void *callback_data)
957 PGresult *res;
959 /* Get the COPY data stream. */
960 res = PQgetResult(conn);
961 if (PQresultStatus(res) != PGRES_COPY_OUT)
963 pg_log_error("could not get COPY data stream: %s",
964 PQerrorMessage(conn));
965 exit(1);
967 PQclear(res);
969 /* Loop over chunks until done. */
970 while (1)
972 int r;
973 char *copybuf;
975 r = PQgetCopyData(conn, &copybuf, 0);
976 if (r == -1)
978 /* End of chunk. */
979 break;
981 else if (r == -2)
983 pg_log_error("could not read COPY data: %s",
984 PQerrorMessage(conn));
985 exit(1);
988 (*callback) (r, copybuf, callback_data);
990 PQfreemem(copybuf);
995 * Write a piece of tar data
997 static void
998 writeTarData(WriteTarState *state, char *buf, int r)
1000 #ifdef HAVE_LIBZ
1001 if (state->ztarfile != NULL)
1003 errno = 0;
1004 if (gzwrite(state->ztarfile, buf, r) != r)
1006 /* if write didn't set errno, assume problem is no disk space */
1007 if (errno == 0)
1008 errno = ENOSPC;
1009 pg_log_error("could not write to compressed file \"%s\": %s",
1010 state->filename, get_gz_error(state->ztarfile));
1011 exit(1);
1014 else
1015 #endif
1017 errno = 0;
1018 if (fwrite(buf, r, 1, state->tarfile) != 1)
1020 /* if write didn't set errno, assume problem is no disk space */
1021 if (errno == 0)
1022 errno = ENOSPC;
1023 pg_log_error("could not write to file \"%s\": %m",
1024 state->filename);
1025 exit(1);
1031 * Receive a tar format file from the connection to the server, and write
1032 * the data from this file directly into a tar file. If compression is
1033 * enabled, the data will be compressed while written to the file.
1035 * The file will be named base.tar[.gz] if it's for the main data directory
1036 * or <tablespaceoid>.tar[.gz] if it's for another tablespace.
1038 * No attempt to inspect or validate the contents of the file is done.
1040 static void
1041 ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
1043 char zerobuf[TAR_BLOCK_SIZE * 2];
1044 WriteTarState state;
1046 memset(&state, 0, sizeof(state));
1047 state.tablespacenum = rownum;
1048 state.basetablespace = PQgetisnull(res, rownum, 0);
1049 state.in_tarhdr = true;
1051 /* recovery.conf is integrated into postgresql.conf in 12 and newer */
1052 if (PQserverVersion(conn) >= MINIMUM_VERSION_FOR_RECOVERY_GUC)
1053 state.is_recovery_guc_supported = true;
1055 if (state.basetablespace)
1058 * Base tablespaces
1060 if (strcmp(basedir, "-") == 0)
1062 #ifdef WIN32
1063 _setmode(fileno(stdout), _O_BINARY);
1064 #endif
1066 #ifdef HAVE_LIBZ
1067 if (compresslevel != 0)
1069 int fd = dup(fileno(stdout));
1071 if (fd < 0)
1073 pg_log_error("could not duplicate stdout: %m");
1074 exit(1);
1077 state.ztarfile = gzdopen(fd, "wb");
1078 if (state.ztarfile == NULL)
1080 pg_log_error("could not open output file: %m");
1081 exit(1);
1084 if (gzsetparams(state.ztarfile, compresslevel,
1085 Z_DEFAULT_STRATEGY) != Z_OK)
1087 pg_log_error("could not set compression level %d: %s",
1088 compresslevel, get_gz_error(state.ztarfile));
1089 exit(1);
1092 else
1093 #endif
1094 state.tarfile = stdout;
1095 strcpy(state.filename, "-");
1097 else
1099 #ifdef HAVE_LIBZ
1100 if (compresslevel != 0)
1102 snprintf(state.filename, sizeof(state.filename),
1103 "%s/base.tar.gz", basedir);
1104 state.ztarfile = gzopen(state.filename, "wb");
1105 if (gzsetparams(state.ztarfile, compresslevel,
1106 Z_DEFAULT_STRATEGY) != Z_OK)
1108 pg_log_error("could not set compression level %d: %s",
1109 compresslevel, get_gz_error(state.ztarfile));
1110 exit(1);
1113 else
1114 #endif
1116 snprintf(state.filename, sizeof(state.filename),
1117 "%s/base.tar", basedir);
1118 state.tarfile = fopen(state.filename, "wb");
1122 else
1125 * Specific tablespace
1127 #ifdef HAVE_LIBZ
1128 if (compresslevel != 0)
1130 snprintf(state.filename, sizeof(state.filename),
1131 "%s/%s.tar.gz",
1132 basedir, PQgetvalue(res, rownum, 0));
1133 state.ztarfile = gzopen(state.filename, "wb");
1134 if (gzsetparams(state.ztarfile, compresslevel,
1135 Z_DEFAULT_STRATEGY) != Z_OK)
1137 pg_log_error("could not set compression level %d: %s",
1138 compresslevel, get_gz_error(state.ztarfile));
1139 exit(1);
1142 else
1143 #endif
1145 snprintf(state.filename, sizeof(state.filename), "%s/%s.tar",
1146 basedir, PQgetvalue(res, rownum, 0));
1147 state.tarfile = fopen(state.filename, "wb");
1151 #ifdef HAVE_LIBZ
1152 if (compresslevel != 0)
1154 if (!state.ztarfile)
1156 /* Compression is in use */
1157 pg_log_error("could not create compressed file \"%s\": %s",
1158 state.filename, get_gz_error(state.ztarfile));
1159 exit(1);
1162 else
1163 #endif
1165 /* Either no zlib support, or zlib support but compresslevel = 0 */
1166 if (!state.tarfile)
1168 pg_log_error("could not create file \"%s\": %m", state.filename);
1169 exit(1);
1173 ReceiveCopyData(conn, ReceiveTarCopyChunk, &state);
1176 * End of copy data. If requested, and this is the base tablespace, write
1177 * configuration file into the tarfile. When done, close the file (but not
1178 * stdout).
1180 * Also, write two completely empty blocks at the end of the tar file, as
1181 * required by some tar programs.
1184 MemSet(zerobuf, 0, sizeof(zerobuf));
1186 if (state.basetablespace && writerecoveryconf)
1188 char header[TAR_BLOCK_SIZE];
1191 * If postgresql.auto.conf has not been found in the streamed data,
1192 * add recovery configuration to postgresql.auto.conf if recovery
1193 * parameters are GUCs. If the instance connected to is older than
1194 * 12, create recovery.conf with this data otherwise.
1196 if (!state.found_postgresql_auto_conf || !state.is_recovery_guc_supported)
1198 int padding;
1200 tarCreateHeader(header,
1201 state.is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf",
1202 NULL,
1203 recoveryconfcontents->len,
1204 pg_file_create_mode, 04000, 02000,
1205 time(NULL));
1207 padding = tarPaddingBytesRequired(recoveryconfcontents->len);
1209 writeTarData(&state, header, sizeof(header));
1210 writeTarData(&state, recoveryconfcontents->data,
1211 recoveryconfcontents->len);
1212 if (padding)
1213 writeTarData(&state, zerobuf, padding);
1217 * standby.signal is supported only if recovery parameters are GUCs.
1219 if (state.is_recovery_guc_supported)
1221 tarCreateHeader(header, "standby.signal", NULL,
1222 0, /* zero-length file */
1223 pg_file_create_mode, 04000, 02000,
1224 time(NULL));
1226 writeTarData(&state, header, sizeof(header));
1229 * we don't need to pad out to a multiple of the tar block size
1230 * here, because the file is zero length, which is a multiple of
1231 * any block size.
1237 * Normally, we emit the backup manifest as a separate file, but when
1238 * we're writing a tarfile to stdout, we don't have that option, so
1239 * include it in the one tarfile we've got.
1241 if (strcmp(basedir, "-") == 0 && manifest)
1243 char header[TAR_BLOCK_SIZE];
1244 PQExpBufferData buf;
1246 initPQExpBuffer(&buf);
1247 ReceiveBackupManifestInMemory(conn, &buf);
1248 if (PQExpBufferDataBroken(buf))
1250 pg_log_error("out of memory");
1251 exit(1);
1253 tarCreateHeader(header, "backup_manifest", NULL, buf.len,
1254 pg_file_create_mode, 04000, 02000,
1255 time(NULL));
1256 writeTarData(&state, header, sizeof(header));
1257 writeTarData(&state, buf.data, buf.len);
1258 termPQExpBuffer(&buf);
1261 /* 2 * TAR_BLOCK_SIZE bytes empty data at end of file */
1262 writeTarData(&state, zerobuf, sizeof(zerobuf));
1264 #ifdef HAVE_LIBZ
1265 if (state.ztarfile != NULL)
1267 if (gzclose(state.ztarfile) != 0)
1269 pg_log_error("could not close compressed file \"%s\": %s",
1270 state.filename, get_gz_error(state.ztarfile));
1271 exit(1);
1274 else
1275 #endif
1277 if (strcmp(basedir, "-") != 0)
1279 if (fclose(state.tarfile) != 0)
1281 pg_log_error("could not close file \"%s\": %m",
1282 state.filename);
1283 exit(1);
1288 progress_report(rownum, state.filename, true, false);
1291 * Do not sync the resulting tar file yet, all files are synced once at
1292 * the end.
1297 * Receive one chunk of tar-format data from the server.
1299 static void
1300 ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
1302 WriteTarState *state = callback_data;
1304 if (!writerecoveryconf || !state->basetablespace)
1307 * When not writing config file, or when not working on the base
1308 * tablespace, we never have to look for an existing configuration
1309 * file in the stream.
1311 writeTarData(state, copybuf, r);
1313 else
1316 * Look for a config file in the existing tar stream. If it's there,
1317 * we must skip it so we can later overwrite it with our own version
1318 * of the file.
1320 * To do this, we have to process the individual files inside the TAR
1321 * stream. The stream consists of a header and zero or more chunks,
1322 * each with a length equal to TAR_BLOCK_SIZE. The stream from the
1323 * server is broken up into smaller pieces, so we have to track the
1324 * size of the files to find the next header structure.
1326 int rr = r;
1327 int pos = 0;
1329 while (rr > 0)
1331 if (state->in_tarhdr)
1334 * We're currently reading a header structure inside the TAR
1335 * stream, i.e. the file metadata.
1337 if (state->tarhdrsz < TAR_BLOCK_SIZE)
1340 * Copy the header structure into tarhdr in case the
1341 * header is not aligned properly or it's not returned in
1342 * whole by the last PQgetCopyData call.
1344 int hdrleft;
1345 int bytes2copy;
1347 hdrleft = TAR_BLOCK_SIZE - state->tarhdrsz;
1348 bytes2copy = (rr > hdrleft ? hdrleft : rr);
1350 memcpy(&state->tarhdr[state->tarhdrsz], copybuf + pos,
1351 bytes2copy);
1353 rr -= bytes2copy;
1354 pos += bytes2copy;
1355 state->tarhdrsz += bytes2copy;
1357 else
1360 * We have the complete header structure in tarhdr, look
1361 * at the file metadata: we may want append recovery info
1362 * into postgresql.auto.conf and skip standby.signal file
1363 * if recovery parameters are integrated as GUCs, and
1364 * recovery.conf otherwise. In both cases we must
1365 * calculate tar padding.
1367 if (state->is_recovery_guc_supported)
1369 state->skip_file =
1370 (strcmp(&state->tarhdr[0], "standby.signal") == 0);
1371 state->is_postgresql_auto_conf =
1372 (strcmp(&state->tarhdr[0], "postgresql.auto.conf") == 0);
1374 else
1375 state->skip_file =
1376 (strcmp(&state->tarhdr[0], "recovery.conf") == 0);
1378 state->filesz = read_tar_number(&state->tarhdr[124], 12);
1379 state->file_padding_len =
1380 tarPaddingBytesRequired(state->filesz);
1382 if (state->is_recovery_guc_supported &&
1383 state->is_postgresql_auto_conf &&
1384 writerecoveryconf)
1386 /* replace tar header */
1387 char header[TAR_BLOCK_SIZE];
1389 tarCreateHeader(header, "postgresql.auto.conf", NULL,
1390 state->filesz + recoveryconfcontents->len,
1391 pg_file_create_mode, 04000, 02000,
1392 time(NULL));
1394 writeTarData(state, header, sizeof(header));
1396 else
1398 /* copy stream with padding */
1399 state->filesz += state->file_padding_len;
1401 if (!state->skip_file)
1404 * If we're not skipping the file, write the tar
1405 * header unmodified.
1407 writeTarData(state, state->tarhdr, TAR_BLOCK_SIZE);
1411 /* Next part is the file, not the header */
1412 state->in_tarhdr = false;
1415 else
1418 * We're processing a file's contents.
1420 if (state->filesz > 0)
1423 * We still have data to read (and possibly write).
1425 int bytes2write;
1427 bytes2write = (state->filesz > rr ? rr : state->filesz);
1429 if (!state->skip_file)
1430 writeTarData(state, copybuf + pos, bytes2write);
1432 rr -= bytes2write;
1433 pos += bytes2write;
1434 state->filesz -= bytes2write;
1436 else if (state->is_recovery_guc_supported &&
1437 state->is_postgresql_auto_conf &&
1438 writerecoveryconf)
1440 /* append recovery config to postgresql.auto.conf */
1441 int padding;
1442 int tailsize;
1444 tailsize = (TAR_BLOCK_SIZE - state->file_padding_len) + recoveryconfcontents->len;
1445 padding = tarPaddingBytesRequired(tailsize);
1447 writeTarData(state, recoveryconfcontents->data,
1448 recoveryconfcontents->len);
1450 if (padding)
1452 char zerobuf[TAR_BLOCK_SIZE];
1454 MemSet(zerobuf, 0, sizeof(zerobuf));
1455 writeTarData(state, zerobuf, padding);
1458 /* skip original file padding */
1459 state->is_postgresql_auto_conf = false;
1460 state->skip_file = true;
1461 state->filesz += state->file_padding_len;
1463 state->found_postgresql_auto_conf = true;
1465 else
1468 * No more data in the current file, the next piece of
1469 * data (if any) will be a new file header structure.
1471 state->in_tarhdr = true;
1472 state->skip_file = false;
1473 state->is_postgresql_auto_conf = false;
1474 state->tarhdrsz = 0;
1475 state->filesz = 0;
1480 totaldone += r;
1481 progress_report(state->tablespacenum, state->filename, false, false);
1486 * Retrieve tablespace path, either relocated or original depending on whether
1487 * -T was passed or not.
1489 static const char *
1490 get_tablespace_mapping(const char *dir)
1492 TablespaceListCell *cell;
1493 char canon_dir[MAXPGPATH];
1495 /* Canonicalize path for comparison consistency */
1496 strlcpy(canon_dir, dir, sizeof(canon_dir));
1497 canonicalize_path(canon_dir);
1499 for (cell = tablespace_dirs.head; cell; cell = cell->next)
1500 if (strcmp(canon_dir, cell->old_dir) == 0)
1501 return cell->new_dir;
1503 return dir;
1508 * Receive a tar format stream from the connection to the server, and unpack
1509 * the contents of it into a directory. Only files, directories and
1510 * symlinks are supported, no other kinds of special files.
1512 * If the data is for the main data directory, it will be restored in the
1513 * specified directory. If it's for another tablespace, it will be restored
1514 * in the original or mapped directory.
1516 static void
1517 ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
1519 UnpackTarState state;
1520 bool basetablespace;
1522 memset(&state, 0, sizeof(state));
1523 state.tablespacenum = rownum;
1525 basetablespace = PQgetisnull(res, rownum, 0);
1526 if (basetablespace)
1527 strlcpy(state.current_path, basedir, sizeof(state.current_path));
1528 else
1529 strlcpy(state.current_path,
1530 get_tablespace_mapping(PQgetvalue(res, rownum, 1)),
1531 sizeof(state.current_path));
1533 ReceiveCopyData(conn, ReceiveTarAndUnpackCopyChunk, &state);
1536 if (state.file)
1537 fclose(state.file);
1539 progress_report(rownum, state.filename, true, false);
1541 if (state.file != NULL)
1543 pg_log_error("COPY stream ended before last file was finished");
1544 exit(1);
1547 if (basetablespace && writerecoveryconf)
1548 WriteRecoveryConfig(conn, basedir, recoveryconfcontents);
1551 * No data is synced here, everything is done for all tablespaces at the
1552 * end.
1556 static void
1557 ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
1559 UnpackTarState *state = callback_data;
1561 if (state->file == NULL)
1563 #ifndef WIN32
1564 int filemode;
1565 #endif
1568 * No current file, so this must be the header for a new file
1570 if (r != TAR_BLOCK_SIZE)
1572 pg_log_error("invalid tar block header size: %zu", r);
1573 exit(1);
1575 totaldone += TAR_BLOCK_SIZE;
1577 state->current_len_left = read_tar_number(&copybuf[124], 12);
1579 #ifndef WIN32
1580 /* Set permissions on the file */
1581 filemode = read_tar_number(&copybuf[100], 8);
1582 #endif
1585 * All files are padded up to a multiple of TAR_BLOCK_SIZE
1587 state->current_padding =
1588 tarPaddingBytesRequired(state->current_len_left);
1591 * First part of header is zero terminated filename
1593 snprintf(state->filename, sizeof(state->filename),
1594 "%s/%s", state->current_path, copybuf);
1595 if (state->filename[strlen(state->filename) - 1] == '/')
1598 * Ends in a slash means directory or symlink to directory
1600 if (copybuf[156] == '5')
1603 * Directory. Remove trailing slash first.
1605 state->filename[strlen(state->filename) - 1] = '\0';
1606 if (mkdir(state->filename, pg_dir_create_mode) != 0)
1609 * When streaming WAL, pg_wal (or pg_xlog for pre-9.6
1610 * clusters) will have been created by the wal receiver
1611 * process. Also, when the WAL directory location was
1612 * specified, pg_wal (or pg_xlog) has already been created
1613 * as a symbolic link before starting the actual backup.
1614 * So just ignore creation failures on related
1615 * directories.
1617 if (!((pg_str_endswith(state->filename, "/pg_wal") ||
1618 pg_str_endswith(state->filename, "/pg_xlog") ||
1619 pg_str_endswith(state->filename, "/archive_status")) &&
1620 errno == EEXIST))
1622 pg_log_error("could not create directory \"%s\": %m",
1623 state->filename);
1624 exit(1);
1627 #ifndef WIN32
1628 if (chmod(state->filename, (mode_t) filemode))
1630 pg_log_error("could not set permissions on directory \"%s\": %m",
1631 state->filename);
1632 exit(1);
1634 #endif
1636 else if (copybuf[156] == '2')
1639 * Symbolic link
1641 * It's most likely a link in pg_tblspc directory, to the
1642 * location of a tablespace. Apply any tablespace mapping
1643 * given on the command line (--tablespace-mapping). (We
1644 * blindly apply the mapping without checking that the link
1645 * really is inside pg_tblspc. We don't expect there to be
1646 * other symlinks in a data directory, but if there are, you
1647 * can call it an undocumented feature that you can map them
1648 * too.)
1650 state->filename[strlen(state->filename) - 1] = '\0'; /* Remove trailing slash */
1652 state->mapped_tblspc_path =
1653 get_tablespace_mapping(&copybuf[157]);
1654 if (symlink(state->mapped_tblspc_path, state->filename) != 0)
1656 pg_log_error("could not create symbolic link from \"%s\" to \"%s\": %m",
1657 state->filename, state->mapped_tblspc_path);
1658 exit(1);
1661 else
1663 pg_log_error("unrecognized link indicator \"%c\"",
1664 copybuf[156]);
1665 exit(1);
1667 return; /* directory or link handled */
1671 * regular file
1673 state->file = fopen(state->filename, "wb");
1674 if (!state->file)
1676 pg_log_error("could not create file \"%s\": %m", state->filename);
1677 exit(1);
1680 #ifndef WIN32
1681 if (chmod(state->filename, (mode_t) filemode))
1683 pg_log_error("could not set permissions on file \"%s\": %m",
1684 state->filename);
1685 exit(1);
1687 #endif
1689 if (state->current_len_left == 0)
1692 * Done with this file, next one will be a new tar header
1694 fclose(state->file);
1695 state->file = NULL;
1696 return;
1698 } /* new file */
1699 else
1702 * Continuing blocks in existing file
1704 if (state->current_len_left == 0 && r == state->current_padding)
1707 * Received the padding block for this file, ignore it and close
1708 * the file, then move on to the next tar header.
1710 fclose(state->file);
1711 state->file = NULL;
1712 totaldone += r;
1713 return;
1716 errno = 0;
1717 if (fwrite(copybuf, r, 1, state->file) != 1)
1719 /* if write didn't set errno, assume problem is no disk space */
1720 if (errno == 0)
1721 errno = ENOSPC;
1722 pg_log_error("could not write to file \"%s\": %m", state->filename);
1723 exit(1);
1725 totaldone += r;
1726 progress_report(state->tablespacenum, state->filename, false, false);
1728 state->current_len_left -= r;
1729 if (state->current_len_left == 0 && state->current_padding == 0)
1732 * Received the last block, and there is no padding to be
1733 * expected. Close the file and move on to the next tar header.
1735 fclose(state->file);
1736 state->file = NULL;
1737 return;
1739 } /* continuing data in existing file */
1743 * Receive the backup manifest file and write it out to a file.
1745 static void
1746 ReceiveBackupManifest(PGconn *conn)
1748 WriteManifestState state;
1750 snprintf(state.filename, sizeof(state.filename),
1751 "%s/backup_manifest.tmp", basedir);
1752 state.file = fopen(state.filename, "wb");
1753 if (state.file == NULL)
1755 pg_log_error("could not create file \"%s\": %m", state.filename);
1756 exit(1);
1759 ReceiveCopyData(conn, ReceiveBackupManifestChunk, &state);
1761 fclose(state.file);
1765 * Receive one chunk of the backup manifest file and write it out to a file.
1767 static void
1768 ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
1770 WriteManifestState *state = callback_data;
1772 errno = 0;
1773 if (fwrite(copybuf, r, 1, state->file) != 1)
1775 /* if write didn't set errno, assume problem is no disk space */
1776 if (errno == 0)
1777 errno = ENOSPC;
1778 pg_log_error("could not write to file \"%s\": %m", state->filename);
1779 exit(1);
1784 * Receive the backup manifest file and write it out to a file.
1786 static void
1787 ReceiveBackupManifestInMemory(PGconn *conn, PQExpBuffer buf)
1789 ReceiveCopyData(conn, ReceiveBackupManifestInMemoryChunk, buf);
1793 * Receive one chunk of the backup manifest file and write it out to a file.
1795 static void
1796 ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf,
1797 void *callback_data)
1799 PQExpBuffer buf = callback_data;
1801 appendPQExpBuffer(buf, copybuf, r);
1804 static void
1805 BaseBackup(void)
1807 PGresult *res;
1808 char *sysidentifier;
1809 TimeLineID latesttli;
1810 TimeLineID starttli;
1811 char *basebkp;
1812 char escaped_label[MAXPGPATH];
1813 char *maxrate_clause = NULL;
1814 char *manifest_clause = NULL;
1815 char *manifest_checksums_clause = "";
1816 int i;
1817 char xlogstart[64];
1818 char xlogend[64];
1819 int minServerMajor,
1820 maxServerMajor;
1821 int serverVersion,
1822 serverMajor;
1823 int writing_to_stdout;
1825 Assert(conn != NULL);
1828 * Check server version. BASE_BACKUP command was introduced in 9.1, so we
1829 * can't work with servers older than 9.1.
1831 minServerMajor = 901;
1832 maxServerMajor = PG_VERSION_NUM / 100;
1833 serverVersion = PQserverVersion(conn);
1834 serverMajor = serverVersion / 100;
1835 if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1837 const char *serverver = PQparameterStatus(conn, "server_version");
1839 pg_log_error("incompatible server version %s",
1840 serverver ? serverver : "'unknown'");
1841 exit(1);
1845 * If WAL streaming was requested, also check that the server is new
1846 * enough for that.
1848 if (includewal == STREAM_WAL && !CheckServerVersionForStreaming(conn))
1851 * Error message already written in CheckServerVersionForStreaming(),
1852 * but add a hint about using -X none.
1854 pg_log_info("HINT: use -X none or -X fetch to disable log streaming");
1855 exit(1);
1859 * Build contents of configuration file if requested
1861 if (writerecoveryconf)
1862 recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot);
1865 * Run IDENTIFY_SYSTEM so we can get the timeline
1867 if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
1868 exit(1);
1871 * Start the actual backup
1873 PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i);
1875 if (maxrate > 0)
1876 maxrate_clause = psprintf("MAX_RATE %u", maxrate);
1878 if (manifest)
1880 if (manifest_force_encode)
1881 manifest_clause = "MANIFEST 'force-encode'";
1882 else
1883 manifest_clause = "MANIFEST 'yes'";
1884 if (manifest_checksums != NULL)
1885 manifest_checksums_clause = psprintf("MANIFEST_CHECKSUMS '%s'",
1886 manifest_checksums);
1889 if (verbose)
1890 pg_log_info("initiating base backup, waiting for checkpoint to complete");
1892 if (showprogress && !verbose)
1894 fprintf(stderr, "waiting for checkpoint");
1895 if (isatty(fileno(stderr)))
1896 fprintf(stderr, "\r");
1897 else
1898 fprintf(stderr, "\n");
1901 basebkp =
1902 psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s %s %s %s",
1903 escaped_label,
1904 estimatesize ? "PROGRESS" : "",
1905 includewal == FETCH_WAL ? "WAL" : "",
1906 fastcheckpoint ? "FAST" : "",
1907 includewal == NO_WAL ? "" : "NOWAIT",
1908 maxrate_clause ? maxrate_clause : "",
1909 format == 't' ? "TABLESPACE_MAP" : "",
1910 verify_checksums ? "" : "NOVERIFY_CHECKSUMS",
1911 manifest_clause ? manifest_clause : "",
1912 manifest_checksums_clause);
1914 if (PQsendQuery(conn, basebkp) == 0)
1916 pg_log_error("could not send replication command \"%s\": %s",
1917 "BASE_BACKUP", PQerrorMessage(conn));
1918 exit(1);
1922 * Get the starting WAL location
1924 res = PQgetResult(conn);
1925 if (PQresultStatus(res) != PGRES_TUPLES_OK)
1927 pg_log_error("could not initiate base backup: %s",
1928 PQerrorMessage(conn));
1929 exit(1);
1931 if (PQntuples(res) != 1)
1933 pg_log_error("server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
1934 PQntuples(res), PQnfields(res), 1, 2);
1935 exit(1);
1938 strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
1940 if (verbose)
1941 pg_log_info("checkpoint completed");
1944 * 9.3 and later sends the TLI of the starting point. With older servers,
1945 * assume it's the same as the latest timeline reported by
1946 * IDENTIFY_SYSTEM.
1948 if (PQnfields(res) >= 2)
1949 starttli = atoi(PQgetvalue(res, 0, 1));
1950 else
1951 starttli = latesttli;
1952 PQclear(res);
1953 MemSet(xlogend, 0, sizeof(xlogend));
1955 if (verbose && includewal != NO_WAL)
1956 pg_log_info("write-ahead log start point: %s on timeline %u",
1957 xlogstart, starttli);
1960 * Get the header
1962 res = PQgetResult(conn);
1963 if (PQresultStatus(res) != PGRES_TUPLES_OK)
1965 pg_log_error("could not get backup header: %s",
1966 PQerrorMessage(conn));
1967 exit(1);
1969 if (PQntuples(res) < 1)
1971 pg_log_error("no data returned from server");
1972 exit(1);
1976 * Sum up the total size, for progress reporting
1978 totalsize_kb = totaldone = 0;
1979 tablespacecount = PQntuples(res);
1980 for (i = 0; i < PQntuples(res); i++)
1982 totalsize_kb += atol(PQgetvalue(res, i, 2));
1985 * Verify tablespace directories are empty. Don't bother with the
1986 * first once since it can be relocated, and it will be checked before
1987 * we do anything anyway.
1989 if (format == 'p' && !PQgetisnull(res, i, 1))
1991 char *path = unconstify(char *, get_tablespace_mapping(PQgetvalue(res, i, 1)));
1993 verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs);
1998 * When writing to stdout, require a single tablespace
2000 writing_to_stdout = format == 't' && strcmp(basedir, "-") == 0;
2001 if (writing_to_stdout && PQntuples(res) > 1)
2003 pg_log_error("can only write single tablespace to stdout, database has %d",
2004 PQntuples(res));
2005 exit(1);
2009 * If we're streaming WAL, start the streaming session before we start
2010 * receiving the actual data chunks.
2012 if (includewal == STREAM_WAL)
2014 if (verbose)
2015 pg_log_info("starting background WAL receiver");
2016 StartLogStreamer(xlogstart, starttli, sysidentifier);
2020 * Start receiving chunks
2022 for (i = 0; i < PQntuples(res); i++)
2024 if (format == 't')
2025 ReceiveTarFile(conn, res, i);
2026 else
2027 ReceiveAndUnpackTarFile(conn, res, i);
2028 } /* Loop over all tablespaces */
2031 * Now receive backup manifest, if appropriate.
2033 * If we're writing a tarfile to stdout, ReceiveTarFile will have already
2034 * processed the backup manifest and included it in the output tarfile.
2035 * Such a configuration doesn't allow for writing multiple files.
2037 * If we're talking to an older server, it won't send a backup manifest,
2038 * so don't try to receive one.
2040 if (!writing_to_stdout && manifest)
2041 ReceiveBackupManifest(conn);
2043 if (showprogress)
2044 progress_report(PQntuples(res), NULL, true, true);
2046 PQclear(res);
2049 * Get the stop position
2051 res = PQgetResult(conn);
2052 if (PQresultStatus(res) != PGRES_TUPLES_OK)
2054 pg_log_error("could not get write-ahead log end position from server: %s",
2055 PQerrorMessage(conn));
2056 exit(1);
2058 if (PQntuples(res) != 1)
2060 pg_log_error("no write-ahead log end position returned from server");
2061 exit(1);
2063 strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend));
2064 if (verbose && includewal != NO_WAL)
2065 pg_log_info("write-ahead log end point: %s", xlogend);
2066 PQclear(res);
2068 res = PQgetResult(conn);
2069 if (PQresultStatus(res) != PGRES_COMMAND_OK)
2071 const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
2073 if (sqlstate &&
2074 strcmp(sqlstate, ERRCODE_DATA_CORRUPTED) == 0)
2076 pg_log_error("checksum error occurred");
2077 checksum_failure = true;
2079 else
2081 pg_log_error("final receive failed: %s",
2082 PQerrorMessage(conn));
2084 exit(1);
2087 if (bgchild > 0)
2089 #ifndef WIN32
2090 int status;
2091 pid_t r;
2092 #else
2093 DWORD status;
2096 * get a pointer sized version of bgchild to avoid warnings about
2097 * casting to a different size on WIN64.
2099 intptr_t bgchild_handle = bgchild;
2100 uint32 hi,
2102 #endif
2104 if (verbose)
2105 pg_log_info("waiting for background process to finish streaming ...");
2107 #ifndef WIN32
2108 if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2110 pg_log_info("could not send command to background pipe: %m");
2111 exit(1);
2114 /* Just wait for the background process to exit */
2115 r = waitpid(bgchild, &status, 0);
2116 if (r == (pid_t) -1)
2118 pg_log_error("could not wait for child process: %m");
2119 exit(1);
2121 if (r != bgchild)
2123 pg_log_error("child %d died, expected %d", (int) r, (int) bgchild);
2124 exit(1);
2126 if (status != 0)
2128 pg_log_error("%s", wait_result_to_str(status));
2129 exit(1);
2131 /* Exited normally, we're happy! */
2132 #else /* WIN32 */
2135 * On Windows, since we are in the same process, we can just store the
2136 * value directly in the variable, and then set the flag that says
2137 * it's there.
2139 if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
2141 pg_log_error("could not parse write-ahead log location \"%s\"",
2142 xlogend);
2143 exit(1);
2145 xlogendptr = ((uint64) hi) << 32 | lo;
2146 InterlockedIncrement(&has_xlogendptr);
2148 /* First wait for the thread to exit */
2149 if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2150 WAIT_OBJECT_0)
2152 _dosmaperr(GetLastError());
2153 pg_log_error("could not wait for child thread: %m");
2154 exit(1);
2156 if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2158 _dosmaperr(GetLastError());
2159 pg_log_error("could not get child thread exit status: %m");
2160 exit(1);
2162 if (status != 0)
2164 pg_log_error("child thread exited with error %u",
2165 (unsigned int) status);
2166 exit(1);
2168 /* Exited normally, we're happy */
2169 #endif
2172 /* Free the configuration file contents */
2173 destroyPQExpBuffer(recoveryconfcontents);
2176 * End of copy data. Final result is already checked inside the loop.
2178 PQclear(res);
2179 PQfinish(conn);
2180 conn = NULL;
2183 * Make data persistent on disk once backup is completed. For tar format
2184 * sync the parent directory and all its contents as each tar file was not
2185 * synced after being completed. In plain format, all the data of the
2186 * base directory is synced, taking into account all the tablespaces.
2187 * Errors are not considered fatal.
2189 if (do_sync)
2191 if (verbose)
2192 pg_log_info("syncing data to disk ...");
2193 if (format == 't')
2195 if (strcmp(basedir, "-") != 0)
2196 (void) fsync_dir_recurse(basedir);
2198 else
2200 (void) fsync_pgdata(basedir, serverVersion);
2205 * After synchronizing data to disk, perform a durable rename of
2206 * backup_manifest.tmp to backup_manifest, if we wrote such a file. This
2207 * way, a failure or system crash before we reach this point will leave us
2208 * without a backup_manifest file, decreasing the chances that a directory
2209 * we leave behind will be mistaken for a valid backup.
2211 if (!writing_to_stdout && manifest)
2213 char tmp_filename[MAXPGPATH];
2214 char filename[MAXPGPATH];
2216 if (verbose)
2217 pg_log_info("renaming backup_manifest.tmp to backup_manifest");
2219 snprintf(tmp_filename, MAXPGPATH, "%s/backup_manifest.tmp", basedir);
2220 snprintf(filename, MAXPGPATH, "%s/backup_manifest", basedir);
2222 /* durable_rename emits its own log message in case of failure */
2223 if (durable_rename(tmp_filename, filename) != 0)
2224 exit(1);
2227 if (verbose)
2228 pg_log_info("base backup completed");
2233 main(int argc, char **argv)
2235 static struct option long_options[] = {
2236 {"help", no_argument, NULL, '?'},
2237 {"version", no_argument, NULL, 'V'},
2238 {"pgdata", required_argument, NULL, 'D'},
2239 {"format", required_argument, NULL, 'F'},
2240 {"checkpoint", required_argument, NULL, 'c'},
2241 {"create-slot", no_argument, NULL, 'C'},
2242 {"max-rate", required_argument, NULL, 'r'},
2243 {"write-recovery-conf", no_argument, NULL, 'R'},
2244 {"slot", required_argument, NULL, 'S'},
2245 {"tablespace-mapping", required_argument, NULL, 'T'},
2246 {"wal-method", required_argument, NULL, 'X'},
2247 {"gzip", no_argument, NULL, 'z'},
2248 {"compress", required_argument, NULL, 'Z'},
2249 {"label", required_argument, NULL, 'l'},
2250 {"no-clean", no_argument, NULL, 'n'},
2251 {"no-sync", no_argument, NULL, 'N'},
2252 {"dbname", required_argument, NULL, 'd'},
2253 {"host", required_argument, NULL, 'h'},
2254 {"port", required_argument, NULL, 'p'},
2255 {"username", required_argument, NULL, 'U'},
2256 {"no-password", no_argument, NULL, 'w'},
2257 {"password", no_argument, NULL, 'W'},
2258 {"status-interval", required_argument, NULL, 's'},
2259 {"verbose", no_argument, NULL, 'v'},
2260 {"progress", no_argument, NULL, 'P'},
2261 {"waldir", required_argument, NULL, 1},
2262 {"no-slot", no_argument, NULL, 2},
2263 {"no-verify-checksums", no_argument, NULL, 3},
2264 {"no-estimate-size", no_argument, NULL, 4},
2265 {"no-manifest", no_argument, NULL, 5},
2266 {"manifest-force-encode", no_argument, NULL, 6},
2267 {"manifest-checksums", required_argument, NULL, 7},
2268 {NULL, 0, NULL, 0}
2270 int c;
2272 int option_index;
2274 pg_logging_init(argv[0]);
2275 progname = get_progname(argv[0]);
2276 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
2278 if (argc > 1)
2280 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2282 usage();
2283 exit(0);
2285 else if (strcmp(argv[1], "-V") == 0
2286 || strcmp(argv[1], "--version") == 0)
2288 puts("pg_basebackup (PostgreSQL) " PG_VERSION);
2289 exit(0);
2293 atexit(cleanup_directories_atexit);
2295 while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP",
2296 long_options, &option_index)) != -1)
2298 switch (c)
2300 case 'C':
2301 create_slot = true;
2302 break;
2303 case 'D':
2304 basedir = pg_strdup(optarg);
2305 break;
2306 case 'F':
2307 if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
2308 format = 'p';
2309 else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
2310 format = 't';
2311 else
2313 pg_log_error("invalid output format \"%s\", must be \"plain\" or \"tar\"",
2314 optarg);
2315 exit(1);
2317 break;
2318 case 'r':
2319 maxrate = parse_max_rate(optarg);
2320 break;
2321 case 'R':
2322 writerecoveryconf = true;
2323 break;
2324 case 'S':
2327 * When specifying replication slot name, use a permanent
2328 * slot.
2330 replication_slot = pg_strdup(optarg);
2331 temp_replication_slot = false;
2332 break;
2333 case 2:
2334 no_slot = true;
2335 break;
2336 case 'T':
2337 tablespace_list_append(optarg);
2338 break;
2339 case 'X':
2340 if (strcmp(optarg, "n") == 0 ||
2341 strcmp(optarg, "none") == 0)
2343 includewal = NO_WAL;
2345 else if (strcmp(optarg, "f") == 0 ||
2346 strcmp(optarg, "fetch") == 0)
2348 includewal = FETCH_WAL;
2350 else if (strcmp(optarg, "s") == 0 ||
2351 strcmp(optarg, "stream") == 0)
2353 includewal = STREAM_WAL;
2355 else
2357 pg_log_error("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2358 optarg);
2359 exit(1);
2361 break;
2362 case 1:
2363 xlog_dir = pg_strdup(optarg);
2364 break;
2365 case 'l':
2366 label = pg_strdup(optarg);
2367 break;
2368 case 'n':
2369 noclean = true;
2370 break;
2371 case 'N':
2372 do_sync = false;
2373 break;
2374 case 'z':
2375 #ifdef HAVE_LIBZ
2376 compresslevel = Z_DEFAULT_COMPRESSION;
2377 #else
2378 compresslevel = 1; /* will be rejected below */
2379 #endif
2380 break;
2381 case 'Z':
2382 if (!option_parse_int(optarg, "-Z/--compress", 0, 9,
2383 &compresslevel))
2384 exit(1);
2385 break;
2386 case 'c':
2387 if (pg_strcasecmp(optarg, "fast") == 0)
2388 fastcheckpoint = true;
2389 else if (pg_strcasecmp(optarg, "spread") == 0)
2390 fastcheckpoint = false;
2391 else
2393 pg_log_error("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2394 optarg);
2395 exit(1);
2397 break;
2398 case 'd':
2399 connection_string = pg_strdup(optarg);
2400 break;
2401 case 'h':
2402 dbhost = pg_strdup(optarg);
2403 break;
2404 case 'p':
2405 dbport = pg_strdup(optarg);
2406 break;
2407 case 'U':
2408 dbuser = pg_strdup(optarg);
2409 break;
2410 case 'w':
2411 dbgetpassword = -1;
2412 break;
2413 case 'W':
2414 dbgetpassword = 1;
2415 break;
2416 case 's':
2417 if (!option_parse_int(optarg, "-s/--status-interval", 0,
2418 INT_MAX / 1000,
2419 &standby_message_timeout))
2420 exit(1);
2421 standby_message_timeout *= 1000;
2422 break;
2423 case 'v':
2424 verbose++;
2425 break;
2426 case 'P':
2427 showprogress = true;
2428 break;
2429 case 3:
2430 verify_checksums = false;
2431 break;
2432 case 4:
2433 estimatesize = false;
2434 break;
2435 case 5:
2436 manifest = false;
2437 break;
2438 case 6:
2439 manifest_force_encode = true;
2440 break;
2441 case 7:
2442 manifest_checksums = pg_strdup(optarg);
2443 break;
2444 default:
2447 * getopt_long already emitted a complaint
2449 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2450 progname);
2451 exit(1);
2456 * Any non-option arguments?
2458 if (optind < argc)
2460 pg_log_error("too many command-line arguments (first is \"%s\")",
2461 argv[optind]);
2462 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2463 progname);
2464 exit(1);
2468 * Required arguments
2470 if (basedir == NULL)
2472 pg_log_error("no target directory specified");
2473 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2474 progname);
2475 exit(1);
2479 * Mutually exclusive arguments
2481 if (format == 'p' && compresslevel != 0)
2483 pg_log_error("only tar mode backups can be compressed");
2484 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2485 progname);
2486 exit(1);
2489 if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
2491 pg_log_error("cannot stream write-ahead logs in tar mode to stdout");
2492 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2493 progname);
2494 exit(1);
2497 if (replication_slot && includewal != STREAM_WAL)
2499 pg_log_error("replication slots can only be used with WAL streaming");
2500 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2501 progname);
2502 exit(1);
2505 if (no_slot)
2507 if (replication_slot)
2509 pg_log_error("--no-slot cannot be used with slot name");
2510 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2511 progname);
2512 exit(1);
2514 temp_replication_slot = false;
2517 if (create_slot)
2519 if (!replication_slot)
2521 pg_log_error("%s needs a slot to be specified using --slot",
2522 "--create-slot");
2523 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2524 progname);
2525 exit(1);
2528 if (no_slot)
2530 pg_log_error("%s and %s are incompatible options",
2531 "--create-slot", "--no-slot");
2532 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2533 progname);
2534 exit(1);
2538 if (xlog_dir)
2540 if (format != 'p')
2542 pg_log_error("WAL directory location can only be specified in plain mode");
2543 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2544 progname);
2545 exit(1);
2548 /* clean up xlog directory name, check it's absolute */
2549 canonicalize_path(xlog_dir);
2550 if (!is_absolute_path(xlog_dir))
2552 pg_log_error("WAL directory location must be an absolute path");
2553 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2554 progname);
2555 exit(1);
2559 #ifndef HAVE_LIBZ
2560 if (compresslevel != 0)
2562 pg_log_error("this build does not support compression");
2563 exit(1);
2565 #endif
2567 if (showprogress && !estimatesize)
2569 pg_log_error("%s and %s are incompatible options",
2570 "--progress", "--no-estimate-size");
2571 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2572 progname);
2573 exit(1);
2576 if (!manifest && manifest_checksums != NULL)
2578 pg_log_error("%s and %s are incompatible options",
2579 "--no-manifest", "--manifest-checksums");
2580 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2581 progname);
2582 exit(1);
2585 if (!manifest && manifest_force_encode)
2587 pg_log_error("%s and %s are incompatible options",
2588 "--no-manifest", "--manifest-force-encode");
2589 fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2590 progname);
2591 exit(1);
2594 /* connection in replication mode to server */
2595 conn = GetConnection();
2596 if (!conn)
2598 /* Error message already written in GetConnection() */
2599 exit(1);
2601 atexit(disconnect_atexit);
2604 * Set umask so that directories/files are created with the same
2605 * permissions as directories/files in the source data directory.
2607 * pg_mode_mask is set to owner-only by default and then updated in
2608 * GetConnection() where we get the mode from the server-side with
2609 * RetrieveDataDirCreatePerm() and then call SetDataDirectoryCreatePerm().
2611 umask(pg_mode_mask);
2613 /* Backup manifests are supported in 13 and newer versions */
2614 if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_MANIFESTS)
2615 manifest = false;
2618 * Verify that the target directory exists, or create it. For plaintext
2619 * backups, always require the directory. For tar backups, require it
2620 * unless we are writing to stdout.
2622 if (format == 'p' || strcmp(basedir, "-") != 0)
2623 verify_dir_is_empty_or_create(basedir, &made_new_pgdata, &found_existing_pgdata);
2625 /* determine remote server's xlog segment size */
2626 if (!RetrieveWalSegSize(conn))
2627 exit(1);
2629 /* Create pg_wal symlink, if required */
2630 if (xlog_dir)
2632 char *linkloc;
2634 verify_dir_is_empty_or_create(xlog_dir, &made_new_xlogdir, &found_existing_xlogdir);
2637 * Form name of the place where the symlink must go. pg_xlog has been
2638 * renamed to pg_wal in post-10 clusters.
2640 linkloc = psprintf("%s/%s", basedir,
2641 PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
2642 "pg_xlog" : "pg_wal");
2644 #ifdef HAVE_SYMLINK
2645 if (symlink(xlog_dir, linkloc) != 0)
2647 pg_log_error("could not create symbolic link \"%s\": %m", linkloc);
2648 exit(1);
2650 #else
2651 pg_log_error("symlinks are not supported on this platform");
2652 exit(1);
2653 #endif
2654 free(linkloc);
2657 BaseBackup();
2659 success = true;
2660 return 0;