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
10 * src/bin/pg_basebackup/pg_basebackup.c
11 *-------------------------------------------------------------------------
14 #include "postgres_fe.h"
23 #ifdef HAVE_SYS_SELECT_H
24 #include <sys/select.h>
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"
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
];
56 typedef struct TablespaceList
58 TablespaceListCell
*head
;
59 TablespaceListCell
*tail
;
62 typedef struct WriteTarState
65 char filename
[MAXPGPATH
];
67 char tarhdr
[TAR_BLOCK_SIZE
];
71 bool is_recovery_guc_supported
;
72 bool is_postgresql_auto_conf
;
73 bool found_postgresql_auto_conf
;
82 typedef struct UnpackTarState
85 char current_path
[MAXPGPATH
];
86 char filename
[MAXPGPATH
];
87 const char *mapped_tblspc_path
;
88 pgoff_t current_len_left
;
93 typedef struct WriteManifestState
95 char filename
[MAXPGPATH
];
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
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 */
171 static int bgpipe
[2] = {-1, -1};
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
;
182 static int has_xlogendptr
= 0;
184 static volatile LONG has_xlogendptr
= 0;
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
,
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
);
217 cleanup_directories_atexit(void)
219 if (success
|| in_log_streamer
)
222 if (!noclean
&& !checksum_failure
)
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");
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");
264 disconnect_atexit(void)
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.
277 kill_bgchild_atexit(void)
280 kill(bgchild
, SIGTERM
);
285 * Split argument into old_dir and new_dir and append to tablespace mapping
289 tablespace_list_append(const char *arg
)
291 TablespaceListCell
*cell
= (TablespaceListCell
*) pg_malloc0(sizeof(TablespaceListCell
));
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");
305 if (*arg_ptr
== '\\' && *(arg_ptr
+ 1) == '=')
306 ; /* skip backslash escaping = */
307 else if (*arg_ptr
== '=' && (arg_ptr
== arg
|| *(arg_ptr
- 1) != '\\'))
311 pg_log_error("multiple \"=\" signs in tablespace mapping");
315 dst
= dst_ptr
= cell
->new_dir
;
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
);
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",
340 if (!is_absolute_path(cell
->new_dir
))
342 pg_log_error("new directory is not an absolute path in tablespace mapping: %s",
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
;
358 tablespace_dirs
.head
= cell
;
359 tablespace_dirs
.tail
= cell
;
365 get_gz_error(gzFile gzf
)
370 errmsg
= gzerror(gzf
, &errnum
);
371 if (errnum
== Z_ERRNO
)
372 return strerror(errno
);
381 printf(_("%s takes a base backup of a running PostgreSQL server.\n\n"),
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
443 reached_end_position(XLogRecPtr segendpos
, uint32 timeline
,
444 bool segment_finished
)
454 * Don't have the end pointer yet - check our pipe to see if it has
458 FD_SET(bgpipe
[0], &fds
);
460 MemSet(&tv
, 0, sizeof(tv
));
462 r
= select(bgpipe
[0] + 1, &fds
, NULL
, NULL
, &tv
);
469 MemSet(xlogend
, 0, sizeof(xlogend
));
470 r
= read(bgpipe
[0], xlogend
, sizeof(xlogend
) - 1);
473 pg_log_error("could not read from ready pipe: %m");
477 if (sscanf(xlogend
, "%X/%X", &hi
, &lo
) != 2)
479 pg_log_error("could not parse write-ahead log location \"%s\"",
483 xlogendptr
= ((uint64
) hi
) << 32 | lo
;
487 * Fall through to check if we've reached the point further
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.
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.
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
)
517 * Have end pointer, but haven't reached it yet - so tell the caller to
527 char xlog
[MAXPGPATH
]; /* directory or tarfile depending on mode */
533 LogStreamerMain(logstreamer_param
*param
)
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
;
545 stream
.stop_socket
= bgpipe
[0];
547 stream
.stop_socket
= PGINVALID_SOCKET
;
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
;
558 stream
.walmethod
= CreateWalDirectoryMethod(param
->xlog
, 0,
561 stream
.walmethod
= CreateWalTarMethod(param
->xlog
, compresslevel
,
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
573 if (!stream
.walmethod
->finish())
575 pg_log_error("could not finish writing WAL files: %m");
579 PQfinish(param
->bgconn
);
582 FreeWalDirectoryMethod();
585 pg_free(stream
.walmethod
);
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.
596 StartLogStreamer(char *startpos
, uint32 timeline
, char *sysidentifier
)
598 logstreamer_param
*param
;
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\"",
614 param
->startptr
= ((uint64
) hi
) << 32 | lo
;
615 /* Round off to even segment position */
616 param
->startptr
-= XLogSegmentOffset(param
->startptr
, WalSegSz
);
619 /* Create our background pipe */
620 if (pipe(bgpipe
) < 0)
622 pg_log_error("could not create pipe for background process: %m");
627 /* Get a second connection */
628 param
->bgconn
= GetConnection();
630 /* Error message already written in GetConnection() */
633 /* In post-10 cluster, pg_xlog has been renamed to pg_wal */
634 snprintf(param
->xlog
, sizeof(param
->xlog
), "%s/%s",
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))
656 if (temp_replication_slot
)
657 pg_log_info("created temporary replication slot \"%s\"",
660 pg_log_info("created replication slot \"%s\"",
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",
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
);
686 * Start a child process and tell it to start streaming. On Unix, this is
687 * a fork(). On Windows, we create a thread.
693 /* in child process */
694 exit(LogStreamerMain(param
));
696 else if (bgchild
< 0)
698 pg_log_error("could not create background process: %m");
703 * Else we are in the parent process and all is well.
705 atexit(kill_bgchild_atexit
);
707 bgchild
= _beginthreadex(NULL
, 0, (void *) LogStreamerMain
, param
, 0, NULL
);
710 pg_log_error("could not create background thread: %m");
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.
722 verify_dir_is_empty_or_create(char *dirname
, bool *created
, bool *found
)
724 switch (pg_check_dir(dirname
))
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
);
754 pg_log_error("directory \"%s\" exists but is not empty", dirname
);
761 pg_log_error("could not access directory \"%s\": %m", dirname
);
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.
778 progress_report(int tablespacenum
, const char *filename
,
779 bool force
, bool finished
)
782 char totaldone_str
[32];
783 char totalsize_str
[32];
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.
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
,
814 snprintf(totalsize_str
, sizeof(totalsize_str
), INT64_FORMAT
, totalsize_kb
);
816 #define VERBOSE_FILENAME_LENGTH 35
822 * No filename given, so clear the status line (used for last
826 ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
827 "%*s/%s kB (100%%), %d/%d tablespaces %*s",
829 (int) strlen(totalsize_str
),
830 totaldone_str
, totalsize_str
,
831 tablespacenum
, tablespacecount
,
832 VERBOSE_FILENAME_LENGTH
+ 5, "");
835 bool truncate
= (strlen(filename
) > VERBOSE_FILENAME_LENGTH
);
838 ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
839 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
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
);
854 ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
855 "%*s/%s kB (%d%%), %d/%d tablespaces",
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
865 fputc((!finished
&& isatty(fileno(stderr
))) ? '\r' : '\n', stderr
);
869 parse_max_rate(char *src
)
876 result
= strtod(src
, &after_num
);
877 if (src
== after_num
)
879 pg_log_error("transfer rate \"%s\" is not a valid value", src
);
884 pg_log_error("invalid transfer rate \"%s\": %m", src
);
891 * Reject obviously wrong values here.
893 pg_log_error("transfer rate must be greater than zero");
898 * Evaluate suffix, after skipping over possible whitespace. Lack of
899 * suffix means kilobytes.
901 while (*after_num
!= '\0' && isspace((unsigned char) *after_num
))
904 if (*after_num
!= '\0')
907 if (*after_num
== 'k')
909 /* kilobyte is the expected unit. */
912 else if (*after_num
== 'M')
919 /* The rest can only consist of white space. */
920 while (*after_num
!= '\0' && isspace((unsigned char) *after_num
))
923 if (*after_num
!= '\0')
925 pg_log_error("invalid --max-rate unit: \"%s\"", suffix
);
930 if ((uint64
) result
!= (uint64
) ((uint32
) result
))
932 pg_log_error("transfer rate \"%s\" exceeds integer range", src
);
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
);
946 return (int32
) result
;
950 * Read a stream of COPY data and invoke the provided callback for each
954 ReceiveCopyData(PGconn
*conn
, WriteDataCallback callback
,
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
));
969 /* Loop over chunks until done. */
975 r
= PQgetCopyData(conn
, ©buf
, 0);
983 pg_log_error("could not read COPY data: %s",
984 PQerrorMessage(conn
));
988 (*callback
) (r
, copybuf
, callback_data
);
995 * Write a piece of tar data
998 writeTarData(WriteTarState
*state
, char *buf
, int r
)
1001 if (state
->ztarfile
!= NULL
)
1004 if (gzwrite(state
->ztarfile
, buf
, r
) != r
)
1006 /* if write didn't set errno, assume problem is no disk space */
1009 pg_log_error("could not write to compressed file \"%s\": %s",
1010 state
->filename
, get_gz_error(state
->ztarfile
));
1018 if (fwrite(buf
, r
, 1, state
->tarfile
) != 1)
1020 /* if write didn't set errno, assume problem is no disk space */
1023 pg_log_error("could not write to file \"%s\": %m",
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.
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
)
1060 if (strcmp(basedir
, "-") == 0)
1063 _setmode(fileno(stdout
), _O_BINARY
);
1067 if (compresslevel
!= 0)
1069 int fd
= dup(fileno(stdout
));
1073 pg_log_error("could not duplicate stdout: %m");
1077 state
.ztarfile
= gzdopen(fd
, "wb");
1078 if (state
.ztarfile
== NULL
)
1080 pg_log_error("could not open output file: %m");
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
));
1094 state
.tarfile
= stdout
;
1095 strcpy(state
.filename
, "-");
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
));
1116 snprintf(state
.filename
, sizeof(state
.filename
),
1117 "%s/base.tar", basedir
);
1118 state
.tarfile
= fopen(state
.filename
, "wb");
1125 * Specific tablespace
1128 if (compresslevel
!= 0)
1130 snprintf(state
.filename
, sizeof(state
.filename
),
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
));
1145 snprintf(state
.filename
, sizeof(state
.filename
), "%s/%s.tar",
1146 basedir
, PQgetvalue(res
, rownum
, 0));
1147 state
.tarfile
= fopen(state
.filename
, "wb");
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
));
1165 /* Either no zlib support, or zlib support but compresslevel = 0 */
1168 pg_log_error("could not create file \"%s\": %m", state
.filename
);
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
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
)
1200 tarCreateHeader(header
,
1201 state
.is_recovery_guc_supported
? "postgresql.auto.conf" : "recovery.conf",
1203 recoveryconfcontents
->len
,
1204 pg_file_create_mode
, 04000, 02000,
1207 padding
= tarPaddingBytesRequired(recoveryconfcontents
->len
);
1209 writeTarData(&state
, header
, sizeof(header
));
1210 writeTarData(&state
, recoveryconfcontents
->data
,
1211 recoveryconfcontents
->len
);
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,
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
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");
1253 tarCreateHeader(header
, "backup_manifest", NULL
, buf
.len
,
1254 pg_file_create_mode
, 04000, 02000,
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
));
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
));
1277 if (strcmp(basedir
, "-") != 0)
1279 if (fclose(state
.tarfile
) != 0)
1281 pg_log_error("could not close file \"%s\": %m",
1288 progress_report(rownum
, state
.filename
, true, false);
1291 * Do not sync the resulting tar file yet, all files are synced once at
1297 * Receive one chunk of tar-format data from the server.
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
);
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
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.
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.
1347 hdrleft
= TAR_BLOCK_SIZE
- state
->tarhdrsz
;
1348 bytes2copy
= (rr
> hdrleft
? hdrleft
: rr
);
1350 memcpy(&state
->tarhdr
[state
->tarhdrsz
], copybuf
+ pos
,
1355 state
->tarhdrsz
+= bytes2copy
;
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
)
1370 (strcmp(&state
->tarhdr
[0], "standby.signal") == 0);
1371 state
->is_postgresql_auto_conf
=
1372 (strcmp(&state
->tarhdr
[0], "postgresql.auto.conf") == 0);
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
&&
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,
1394 writeTarData(state
, header
, sizeof(header
));
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;
1418 * We're processing a file's contents.
1420 if (state
->filesz
> 0)
1423 * We still have data to read (and possibly write).
1427 bytes2write
= (state
->filesz
> rr
? rr
: state
->filesz
);
1429 if (!state
->skip_file
)
1430 writeTarData(state
, copybuf
+ pos
, bytes2write
);
1434 state
->filesz
-= bytes2write
;
1436 else if (state
->is_recovery_guc_supported
&&
1437 state
->is_postgresql_auto_conf
&&
1440 /* append recovery config to postgresql.auto.conf */
1444 tailsize
= (TAR_BLOCK_SIZE
- state
->file_padding_len
) + recoveryconfcontents
->len
;
1445 padding
= tarPaddingBytesRequired(tailsize
);
1447 writeTarData(state
, recoveryconfcontents
->data
,
1448 recoveryconfcontents
->len
);
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;
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;
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.
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
;
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.
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);
1527 strlcpy(state
.current_path
, basedir
, sizeof(state
.current_path
));
1529 strlcpy(state
.current_path
,
1530 get_tablespace_mapping(PQgetvalue(res
, rownum
, 1)),
1531 sizeof(state
.current_path
));
1533 ReceiveCopyData(conn
, ReceiveTarAndUnpackCopyChunk
, &state
);
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");
1547 if (basetablespace
&& writerecoveryconf
)
1548 WriteRecoveryConfig(conn
, basedir
, recoveryconfcontents
);
1551 * No data is synced here, everything is done for all tablespaces at the
1557 ReceiveTarAndUnpackCopyChunk(size_t r
, char *copybuf
, void *callback_data
)
1559 UnpackTarState
*state
= callback_data
;
1561 if (state
->file
== NULL
)
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
);
1575 totaldone
+= TAR_BLOCK_SIZE
;
1577 state
->current_len_left
= read_tar_number(©buf
[124], 12);
1580 /* Set permissions on the file */
1581 filemode
= read_tar_number(©buf
[100], 8);
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
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")) &&
1622 pg_log_error("could not create directory \"%s\": %m",
1628 if (chmod(state
->filename
, (mode_t
) filemode
))
1630 pg_log_error("could not set permissions on directory \"%s\": %m",
1636 else if (copybuf
[156] == '2')
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
1650 state
->filename
[strlen(state
->filename
) - 1] = '\0'; /* Remove trailing slash */
1652 state
->mapped_tblspc_path
=
1653 get_tablespace_mapping(©buf
[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
);
1663 pg_log_error("unrecognized link indicator \"%c\"",
1667 return; /* directory or link handled */
1673 state
->file
= fopen(state
->filename
, "wb");
1676 pg_log_error("could not create file \"%s\": %m", state
->filename
);
1681 if (chmod(state
->filename
, (mode_t
) filemode
))
1683 pg_log_error("could not set permissions on file \"%s\": %m",
1689 if (state
->current_len_left
== 0)
1692 * Done with this file, next one will be a new tar header
1694 fclose(state
->file
);
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
);
1717 if (fwrite(copybuf
, r
, 1, state
->file
) != 1)
1719 /* if write didn't set errno, assume problem is no disk space */
1722 pg_log_error("could not write to file \"%s\": %m", state
->filename
);
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
);
1739 } /* continuing data in existing file */
1743 * Receive the backup manifest file and write it out to a file.
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
);
1759 ReceiveCopyData(conn
, ReceiveBackupManifestChunk
, &state
);
1765 * Receive one chunk of the backup manifest file and write it out to a file.
1768 ReceiveBackupManifestChunk(size_t r
, char *copybuf
, void *callback_data
)
1770 WriteManifestState
*state
= callback_data
;
1773 if (fwrite(copybuf
, r
, 1, state
->file
) != 1)
1775 /* if write didn't set errno, assume problem is no disk space */
1778 pg_log_error("could not write to file \"%s\": %m", state
->filename
);
1784 * Receive the backup manifest file and write it out to a file.
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.
1796 ReceiveBackupManifestInMemoryChunk(size_t r
, char *copybuf
,
1797 void *callback_data
)
1799 PQExpBuffer buf
= callback_data
;
1801 appendPQExpBuffer(buf
, copybuf
, r
);
1808 char *sysidentifier
;
1809 TimeLineID latesttli
;
1810 TimeLineID starttli
;
1812 char escaped_label
[MAXPGPATH
];
1813 char *maxrate_clause
= NULL
;
1814 char *manifest_clause
= NULL
;
1815 char *manifest_checksums_clause
= "";
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'");
1845 * If WAL streaming was requested, also check that the server is new
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");
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
))
1871 * Start the actual backup
1873 PQescapeStringConn(conn
, escaped_label
, label
, sizeof(escaped_label
), &i
);
1876 maxrate_clause
= psprintf("MAX_RATE %u", maxrate
);
1880 if (manifest_force_encode
)
1881 manifest_clause
= "MANIFEST 'force-encode'";
1883 manifest_clause
= "MANIFEST 'yes'";
1884 if (manifest_checksums
!= NULL
)
1885 manifest_checksums_clause
= psprintf("MANIFEST_CHECKSUMS '%s'",
1886 manifest_checksums
);
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");
1898 fprintf(stderr
, "\n");
1902 psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s %s %s %s",
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
));
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
));
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);
1938 strlcpy(xlogstart
, PQgetvalue(res
, 0, 0), sizeof(xlogstart
));
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
1948 if (PQnfields(res
) >= 2)
1949 starttli
= atoi(PQgetvalue(res
, 0, 1));
1951 starttli
= latesttli
;
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
);
1962 res
= PQgetResult(conn
);
1963 if (PQresultStatus(res
) != PGRES_TUPLES_OK
)
1965 pg_log_error("could not get backup header: %s",
1966 PQerrorMessage(conn
));
1969 if (PQntuples(res
) < 1)
1971 pg_log_error("no data returned from server");
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",
2009 * If we're streaming WAL, start the streaming session before we start
2010 * receiving the actual data chunks.
2012 if (includewal
== STREAM_WAL
)
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
++)
2025 ReceiveTarFile(conn
, res
, i
);
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
);
2044 progress_report(PQntuples(res
), NULL
, true, true);
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
));
2058 if (PQntuples(res
) != 1)
2060 pg_log_error("no write-ahead log end position returned from server");
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
);
2068 res
= PQgetResult(conn
);
2069 if (PQresultStatus(res
) != PGRES_COMMAND_OK
)
2071 const char *sqlstate
= PQresultErrorField(res
, PG_DIAG_SQLSTATE
);
2074 strcmp(sqlstate
, ERRCODE_DATA_CORRUPTED
) == 0)
2076 pg_log_error("checksum error occurred");
2077 checksum_failure
= true;
2081 pg_log_error("final receive failed: %s",
2082 PQerrorMessage(conn
));
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
;
2105 pg_log_info("waiting for background process to finish streaming ...");
2108 if (write(bgpipe
[1], xlogend
, strlen(xlogend
)) != strlen(xlogend
))
2110 pg_log_info("could not send command to background pipe: %m");
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");
2123 pg_log_error("child %d died, expected %d", (int) r
, (int) bgchild
);
2128 pg_log_error("%s", wait_result_to_str(status
));
2131 /* Exited normally, we're happy! */
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
2139 if (sscanf(xlogend
, "%X/%X", &hi
, &lo
) != 2)
2141 pg_log_error("could not parse write-ahead log location \"%s\"",
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
) !=
2152 _dosmaperr(GetLastError());
2153 pg_log_error("could not wait for child thread: %m");
2156 if (GetExitCodeThread((HANDLE
) bgchild_handle
, &status
) == 0)
2158 _dosmaperr(GetLastError());
2159 pg_log_error("could not get child thread exit status: %m");
2164 pg_log_error("child thread exited with error %u",
2165 (unsigned int) status
);
2168 /* Exited normally, we're happy */
2172 /* Free the configuration file contents */
2173 destroyPQExpBuffer(recoveryconfcontents
);
2176 * End of copy data. Final result is already checked inside the loop.
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.
2192 pg_log_info("syncing data to disk ...");
2195 if (strcmp(basedir
, "-") != 0)
2196 (void) fsync_dir_recurse(basedir
);
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
];
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)
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},
2274 pg_logging_init(argv
[0]);
2275 progname
= get_progname(argv
[0]);
2276 set_pglocale_pgservice(argv
[0], PG_TEXTDOMAIN("pg_basebackup"));
2280 if (strcmp(argv
[1], "--help") == 0 || strcmp(argv
[1], "-?") == 0)
2285 else if (strcmp(argv
[1], "-V") == 0
2286 || strcmp(argv
[1], "--version") == 0)
2288 puts("pg_basebackup (PostgreSQL) " PG_VERSION
);
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)
2304 basedir
= pg_strdup(optarg
);
2307 if (strcmp(optarg
, "p") == 0 || strcmp(optarg
, "plain") == 0)
2309 else if (strcmp(optarg
, "t") == 0 || strcmp(optarg
, "tar") == 0)
2313 pg_log_error("invalid output format \"%s\", must be \"plain\" or \"tar\"",
2319 maxrate
= parse_max_rate(optarg
);
2322 writerecoveryconf
= true;
2327 * When specifying replication slot name, use a permanent
2330 replication_slot
= pg_strdup(optarg
);
2331 temp_replication_slot
= false;
2337 tablespace_list_append(optarg
);
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
;
2357 pg_log_error("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2363 xlog_dir
= pg_strdup(optarg
);
2366 label
= pg_strdup(optarg
);
2376 compresslevel
= Z_DEFAULT_COMPRESSION
;
2378 compresslevel
= 1; /* will be rejected below */
2382 if (!option_parse_int(optarg
, "-Z/--compress", 0, 9,
2387 if (pg_strcasecmp(optarg
, "fast") == 0)
2388 fastcheckpoint
= true;
2389 else if (pg_strcasecmp(optarg
, "spread") == 0)
2390 fastcheckpoint
= false;
2393 pg_log_error("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2399 connection_string
= pg_strdup(optarg
);
2402 dbhost
= pg_strdup(optarg
);
2405 dbport
= pg_strdup(optarg
);
2408 dbuser
= pg_strdup(optarg
);
2417 if (!option_parse_int(optarg
, "-s/--status-interval", 0,
2419 &standby_message_timeout
))
2421 standby_message_timeout
*= 1000;
2427 showprogress
= true;
2430 verify_checksums
= false;
2433 estimatesize
= false;
2439 manifest_force_encode
= true;
2442 manifest_checksums
= pg_strdup(optarg
);
2447 * getopt_long already emitted a complaint
2449 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
2456 * Any non-option arguments?
2460 pg_log_error("too many command-line arguments (first is \"%s\")",
2462 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
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"),
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"),
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"),
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"),
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"),
2514 temp_replication_slot
= false;
2519 if (!replication_slot
)
2521 pg_log_error("%s needs a slot to be specified using --slot",
2523 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
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"),
2542 pg_log_error("WAL directory location can only be specified in plain mode");
2543 fprintf(stderr
, _("Try \"%s --help\" for more information.\n"),
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"),
2560 if (compresslevel
!= 0)
2562 pg_log_error("this build does not support compression");
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"),
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"),
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"),
2594 /* connection in replication mode to server */
2595 conn
= GetConnection();
2598 /* Error message already written in GetConnection() */
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
)
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
))
2629 /* Create pg_wal symlink, if required */
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");
2645 if (symlink(xlog_dir
, linkloc
) != 0)
2647 pg_log_error("could not create symbolic link \"%s\": %m", linkloc
);
2651 pg_log_error("symlinks are not supported on this platform");