PostgreSQL Source Code  git master
pg_basebackup.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * pg_basebackup.c - receive a base backup using streaming replication protocol
4  *
5  * Author: Magnus Hagander <magnus@hagander.net>
6  *
7  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
8  *
9  * IDENTIFICATION
10  * src/bin/pg_basebackup/pg_basebackup.c
11  *-------------------------------------------------------------------------
12  */
13 
14 #include "postgres_fe.h"
15 
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
29 
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"
46 
47 #define ERRCODE_DATA_CORRUPTED "XX001"
48 
49 typedef struct TablespaceListCell
50 {
55 
56 typedef struct TablespaceList
57 {
61 
62 typedef struct WriteTarState
63 {
66  FILE *tarfile;
67  char tarhdr[TAR_BLOCK_SIZE];
69  bool in_tarhdr;
70  bool skip_file;
75  size_t tarhdrsz;
77 #ifdef HAVE_LIBZ
78  gzFile ztarfile;
79 #endif
81 
82 typedef struct UnpackTarState
83 {
85  char current_path[MAXPGPATH];
87  const char *mapped_tblspc_path;
90  FILE *file;
92 
93 typedef struct WriteManifestState
94 {
96  FILE *file;
98 
99 typedef void (*WriteDataCallback) (size_t nbytes, char *buf,
100  void *callback_data);
101 
102 /*
103  * pg_xlog has been renamed to pg_wal in version 10. This version number
104  * should be compared with PQserverVersion().
105  */
106 #define MINIMUM_VERSION_FOR_PG_WAL 100000
107 
108 /*
109  * Temporary replication slots are supported from version 10.
110  */
111 #define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
112 
113 /*
114  * Backup manifests are supported from version 13.
115  */
116 #define MINIMUM_VERSION_FOR_MANIFESTS 130000
117 
118 /*
119  * Different ways to include WAL
120  */
121 typedef enum
122 {
126 } IncludeWal;
127 
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;
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 */
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;
155 
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;
163 
164 /* Progress counters */
165 static uint64 totalsize_kb;
166 static uint64 totaldone;
167 static int tablespacecount;
168 
169 /* Pipe to communicate with background wal receiver process */
170 #ifndef WIN32
171 static int bgpipe[2] = {-1, -1};
172 #endif
173 
174 /* Handle to child process */
175 static pid_t bgchild = -1;
176 static bool in_log_streamer = false;
177 
178 /* End position for xlog streaming, empty string if unknown yet */
180 
181 #ifndef WIN32
182 static int has_xlogendptr = 0;
183 #else
184 static volatile LONG has_xlogendptr = 0;
185 #endif
186 
187 /* Contents of configuration file to be generated */
189 
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);
195 
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);
205 static void ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf,
206  void *callback_data);
207 static void BaseBackup(void);
208 
209 static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline,
210  bool segment_finished);
211 
212 static const char *get_tablespace_mapping(const char *dir);
213 static void tablespace_list_append(const char *arg);
214 
215 
216 static void
218 {
219  if (success || in_log_streamer)
220  return;
221 
222  if (!noclean && !checksum_failure)
223  {
224  if (made_new_pgdata)
225  {
226  pg_log_info("removing data directory \"%s\"", basedir);
227  if (!rmtree(basedir, true))
228  pg_log_error("failed to remove data directory");
229  }
230  else if (found_existing_pgdata)
231  {
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");
235  }
236 
237  if (made_new_xlogdir)
238  {
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");
242  }
243  else if (found_existing_xlogdir)
244  {
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");
248  }
249  }
250  else
251  {
253  pg_log_info("data directory \"%s\" not removed at user's request", basedir);
254 
256  pg_log_info("WAL directory \"%s\" not removed at user's request", xlog_dir);
257  }
258 
260  pg_log_info("changes to tablespace directories will not be undone");
261 }
262 
263 static void
265 {
266  if (conn != NULL)
267  PQfinish(conn);
268 }
269 
270 #ifndef WIN32
271 /*
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.
275  */
276 static void
278 {
279  if (bgchild > 0)
280  kill(bgchild, SIGTERM);
281 }
282 #endif
283 
284 /*
285  * Split argument into old_dir and new_dir and append to tablespace mapping
286  * list.
287  */
288 static void
290 {
292  char *dst;
293  char *dst_ptr;
294  const char *arg_ptr;
295 
296  dst_ptr = dst = cell->old_dir;
297  for (arg_ptr = arg; *arg_ptr; arg_ptr++)
298  {
299  if (dst_ptr - dst >= MAXPGPATH)
300  {
301  pg_log_error("directory name too long");
302  exit(1);
303  }
304 
305  if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
306  ; /* skip backslash escaping = */
307  else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
308  {
309  if (*cell->new_dir)
310  {
311  pg_log_error("multiple \"=\" signs in tablespace mapping");
312  exit(1);
313  }
314  else
315  dst = dst_ptr = cell->new_dir;
316  }
317  else
318  *dst_ptr++ = *arg_ptr;
319  }
320 
321  if (!*cell->old_dir || !*cell->new_dir)
322  {
323  pg_log_error("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"", arg);
324  exit(1);
325  }
326 
327  /*
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.
332  */
333  if (!is_absolute_path(cell->old_dir))
334  {
335  pg_log_error("old directory is not an absolute path in tablespace mapping: %s",
336  cell->old_dir);
337  exit(1);
338  }
339 
340  if (!is_absolute_path(cell->new_dir))
341  {
342  pg_log_error("new directory is not an absolute path in tablespace mapping: %s",
343  cell->new_dir);
344  exit(1);
345  }
346 
347  /*
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.
351  */
352  canonicalize_path(cell->old_dir);
353  canonicalize_path(cell->new_dir);
354 
355  if (tablespace_dirs.tail)
356  tablespace_dirs.tail->next = cell;
357  else
358  tablespace_dirs.head = cell;
359  tablespace_dirs.tail = cell;
360 }
361 
362 
363 #ifdef HAVE_LIBZ
364 static const char *
365 get_gz_error(gzFile gzf)
366 {
367  int errnum;
368  const char *errmsg;
369 
370  errmsg = gzerror(gzf, &errnum);
371  if (errnum == Z_ERRNO)
372  return strerror(errno);
373  else
374  return errmsg;
375 }
376 #endif
377 
378 static void
379 usage(void)
380 {
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);
431 }
432 
433 
434 /*
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.
441  */
442 static bool
444  bool segment_finished)
445 {
446  if (!has_xlogendptr)
447  {
448 #ifndef WIN32
449  fd_set fds;
450  struct timeval tv;
451  int r;
452 
453  /*
454  * Don't have the end pointer yet - check our pipe to see if it has
455  * been sent yet.
456  */
457  FD_ZERO(&fds);
458  FD_SET(bgpipe[0], &fds);
459 
460  MemSet(&tv, 0, sizeof(tv));
461 
462  r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv);
463  if (r == 1)
464  {
465  char xlogend[64];
466  uint32 hi,
467  lo;
468 
469  MemSet(xlogend, 0, sizeof(xlogend));
470  r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
471  if (r < 0)
472  {
473  pg_log_error("could not read from ready pipe: %m");
474  exit(1);
475  }
476 
477  if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
478  {
479  pg_log_error("could not parse write-ahead log location \"%s\"",
480  xlogend);
481  exit(1);
482  }
483  xlogendptr = ((uint64) hi) << 32 | lo;
484  has_xlogendptr = 1;
485 
486  /*
487  * Fall through to check if we've reached the point further
488  * already.
489  */
490  }
491  else
492  {
493  /*
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.
496  */
497  return false;
498  }
499 #else
500 
501  /*
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.
504  */
505  return false;
506 #endif
507  }
508 
509  /*
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.
512  */
513  if (segendpos >= xlogendptr)
514  return true;
515 
516  /*
517  * Have end pointer, but haven't reached it yet - so tell the caller to
518  * keep streaming.
519  */
520  return false;
521 }
522 
523 typedef struct
524 {
527  char xlog[MAXPGPATH]; /* directory or tarfile depending on mode */
529  int timeline;
531 
532 static int
534 {
535  StreamCtl stream;
536 
537  in_log_streamer = true;
538 
539  MemSet(&stream, 0, sizeof(stream));
540  stream.startpos = param->startptr;
541  stream.timeline = param->timeline;
542  stream.sysidentifier = param->sysidentifier;
544 #ifndef WIN32
545  stream.stop_socket = bgpipe[0];
546 #else
547  stream.stop_socket = PGINVALID_SOCKET;
548 #endif
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;
556 
557  if (format == 'p')
558  stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0,
559  stream.do_sync);
560  else
562  stream.do_sync);
563 
564  if (!ReceiveXlogStream(param->bgconn, &stream))
565 
566  /*
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.
570  */
571  return 1;
572 
573  if (!stream.walmethod->finish())
574  {
575  pg_log_error("could not finish writing WAL files: %m");
576  return 1;
577  }
578 
579  PQfinish(param->bgconn);
580 
581  if (format == 'p')
583  else
585  pg_free(stream.walmethod);
586 
587  return 0;
588 }
589 
590 /*
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.
594  */
595 static void
596 StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
597 {
598  logstreamer_param *param;
599  uint32 hi,
600  lo;
601  char statusdir[MAXPGPATH];
602 
603  param = pg_malloc0(sizeof(logstreamer_param));
604  param->timeline = timeline;
605  param->sysidentifier = sysidentifier;
606 
607  /* Convert the starting position */
608  if (sscanf(startpos, "%X/%X", &hi, &lo) != 2)
609  {
610  pg_log_error("could not parse write-ahead log location \"%s\"",
611  startpos);
612  exit(1);
613  }
614  param->startptr = ((uint64) hi) << 32 | lo;
615  /* Round off to even segment position */
616  param->startptr -= XLogSegmentOffset(param->startptr, WalSegSz);
617 
618 #ifndef WIN32
619  /* Create our background pipe */
620  if (pipe(bgpipe) < 0)
621  {
622  pg_log_error("could not create pipe for background process: %m");
623  exit(1);
624  }
625 #endif
626 
627  /* Get a second connection */
628  param->bgconn = GetConnection();
629  if (!param->bgconn)
630  /* Error message already written in GetConnection() */
631  exit(1);
632 
633  /* In post-10 cluster, pg_xlog has been renamed to pg_wal */
634  snprintf(param->xlog, sizeof(param->xlog), "%s/%s",
635  basedir,
637  "pg_xlog" : "pg_wal");
638 
639  /* Temporary replication slots are only supported in 10 and newer */
641  temp_replication_slot = false;
642 
643  /*
644  * Create replication slot if requested
645  */
647  replication_slot = psprintf("pg_basebackup_%d", (int) PQbackendPID(param->bgconn));
649  {
650  if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL,
651  temp_replication_slot, true, true, false, false))
652  exit(1);
653 
654  if (verbose)
655  {
657  pg_log_info("created temporary replication slot \"%s\"",
659  else
660  pg_log_info("created replication slot \"%s\"",
662  }
663  }
664 
665  if (format == 'p')
666  {
667  /*
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.
672  */
673  snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status",
674  basedir,
676  "pg_xlog" : "pg_wal");
677 
678  if (pg_mkdir_p(statusdir, pg_dir_create_mode) != 0 && errno != EEXIST)
679  {
680  pg_log_error("could not create directory \"%s\": %m", statusdir);
681  exit(1);
682  }
683  }
684 
685  /*
686  * Start a child process and tell it to start streaming. On Unix, this is
687  * a fork(). On Windows, we create a thread.
688  */
689 #ifndef WIN32
690  bgchild = fork();
691  if (bgchild == 0)
692  {
693  /* in child process */
694  exit(LogStreamerMain(param));
695  }
696  else if (bgchild < 0)
697  {
698  pg_log_error("could not create background process: %m");
699  exit(1);
700  }
701 
702  /*
703  * Else we are in the parent process and all is well.
704  */
705  atexit(kill_bgchild_atexit);
706 #else /* WIN32 */
707  bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
708  if (bgchild == 0)
709  {
710  pg_log_error("could not create background thread: %m");
711  exit(1);
712  }
713 #endif
714 }
715 
716 /*
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.
720  */
721 static void
722 verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
723 {
724  switch (pg_check_dir(dirname))
725  {
726  case 0:
727 
728  /*
729  * Does not exist, so create
730  */
731  if (pg_mkdir_p(dirname, pg_dir_create_mode) == -1)
732  {
733  pg_log_error("could not create directory \"%s\": %m", dirname);
734  exit(1);
735  }
736  if (created)
737  *created = true;
738  return;
739  case 1:
740 
741  /*
742  * Exists, empty
743  */
744  if (found)
745  *found = true;
746  return;
747  case 2:
748  case 3:
749  case 4:
750 
751  /*
752  * Exists, not empty
753  */
754  pg_log_error("directory \"%s\" exists but is not empty", dirname);
755  exit(1);
756  case -1:
757 
758  /*
759  * Access problem
760  */
761  pg_log_error("could not access directory \"%s\": %m", dirname);
762  exit(1);
763  }
764 }
765 
766 
767 /*
768  * Print a progress report based on the global variables. If verbose output
769  * is enabled, also print the current file name.
770  *
771  * Progress report is written at maximum once per second, unless the force
772  * parameter is set to true.
773  *
774  * If finished is set to true, this is the last progress report. The cursor
775  * is moved to the next line.
776  */
777 static void
778 progress_report(int tablespacenum, const char *filename,
779  bool force, bool finished)
780 {
781  int percent;
782  char totaldone_str[32];
783  char totalsize_str[32];
784  pg_time_t now;
785 
786  if (!showprogress)
787  return;
788 
789  now = time(NULL);
790  if (now == last_progress_report && !force && !finished)
791  return; /* Max once per second */
792 
794  percent = totalsize_kb ? (int) ((totaldone / 1024) * 100 / totalsize_kb) : 0;
795 
796  /*
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.
801  */
802  if (percent > 100)
803  percent = 100;
804  if (totaldone / 1024 > totalsize_kb)
805  totalsize_kb = totaldone / 1024;
806 
807  /*
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.
811  */
812  snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT,
813  totaldone / 1024);
814  snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize_kb);
815 
816 #define VERBOSE_FILENAME_LENGTH 35
817  if (verbose)
818  {
819  if (!filename)
820 
821  /*
822  * No filename given, so clear the status line (used for last
823  * call)
824  */
825  fprintf(stderr,
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, "");
833  else
834  {
835  bool truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH);
836 
837  fprintf(stderr,
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 ? "..." : "",
848  /* Truncate filename at beginning if it's too long */
849  truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename);
850  }
851  }
852  else
853  fprintf(stderr,
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);
860 
861  /*
862  * Stay on the same line if reporting to a terminal and we're not done
863  * yet.
864  */
865  fputc((!finished && isatty(fileno(stderr))) ? '\r' : '\n', stderr);
866 }
867 
868 static int32
869 parse_max_rate(char *src)
870 {
871  double result;
872  char *after_num;
873  char *suffix = NULL;
874 
875  errno = 0;
876  result = strtod(src, &after_num);
877  if (src == after_num)
878  {
879  pg_log_error("transfer rate \"%s\" is not a valid value", src);
880  exit(1);
881  }
882  if (errno != 0)
883  {
884  pg_log_error("invalid transfer rate \"%s\": %m", src);
885  exit(1);
886  }
887 
888  if (result <= 0)
889  {
890  /*
891  * Reject obviously wrong values here.
892  */
893  pg_log_error("transfer rate must be greater than zero");
894  exit(1);
895  }
896 
897  /*
898  * Evaluate suffix, after skipping over possible whitespace. Lack of
899  * suffix means kilobytes.
900  */
901  while (*after_num != '\0' && isspace((unsigned char) *after_num))
902  after_num++;
903 
904  if (*after_num != '\0')
905  {
906  suffix = after_num;
907  if (*after_num == 'k')
908  {
909  /* kilobyte is the expected unit. */
910  after_num++;
911  }
912  else if (*after_num == 'M')
913  {
914  after_num++;
915  result *= 1024.0;
916  }
917  }
918 
919  /* The rest can only consist of white space. */
920  while (*after_num != '\0' && isspace((unsigned char) *after_num))
921  after_num++;
922 
923  if (*after_num != '\0')
924  {
925  pg_log_error("invalid --max-rate unit: \"%s\"", suffix);
926  exit(1);
927  }
928 
929  /* Valid integer? */
930  if ((uint64) result != (uint64) ((uint32) result))
931  {
932  pg_log_error("transfer rate \"%s\" exceeds integer range", src);
933  exit(1);
934  }
935 
936  /*
937  * The range is checked on the server side too, but avoid the server
938  * connection if a nonsensical value was passed.
939  */
940  if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
941  {
942  pg_log_error("transfer rate \"%s\" is out of range", src);
943  exit(1);
944  }
945 
946  return (int32) result;
947 }
948 
949 /*
950  * Read a stream of COPY data and invoke the provided callback for each
951  * chunk.
952  */
953 static void
955  void *callback_data)
956 {
957  PGresult *res;
958 
959  /* Get the COPY data stream. */
960  res = PQgetResult(conn);
961  if (PQresultStatus(res) != PGRES_COPY_OUT)
962  {
963  pg_log_error("could not get COPY data stream: %s",
964  PQerrorMessage(conn));
965  exit(1);
966  }
967  PQclear(res);
968 
969  /* Loop over chunks until done. */
970  while (1)
971  {
972  int r;
973  char *copybuf;
974 
975  r = PQgetCopyData(conn, &copybuf, 0);
976  if (r == -1)
977  {
978  /* End of chunk. */
979  break;
980  }
981  else if (r == -2)
982  {
983  pg_log_error("could not read COPY data: %s",
984  PQerrorMessage(conn));
985  exit(1);
986  }
987 
988  (*callback) (r, copybuf, callback_data);
989 
990  PQfreemem(copybuf);
991  }
992 }
993 
994 /*
995  * Write a piece of tar data
996  */
997 static void
999 {
1000 #ifdef HAVE_LIBZ
1001  if (state->ztarfile != NULL)
1002  {
1003  errno = 0;
1004  if (gzwrite(state->ztarfile, buf, r) != r)
1005  {
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);
1012  }
1013  }
1014  else
1015 #endif
1016  {
1017  errno = 0;
1018  if (fwrite(buf, r, 1, state->tarfile) != 1)
1019  {
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);
1026  }
1027  }
1028 }
1029 
1030 /*
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.
1034  *
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.
1037  *
1038  * No attempt to inspect or validate the contents of the file is done.
1039  */
1040 static void
1041 ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
1042 {
1043  char zerobuf[TAR_BLOCK_SIZE * 2];
1045 
1046  memset(&state, 0, sizeof(state));
1047  state.tablespacenum = rownum;
1048  state.basetablespace = PQgetisnull(res, rownum, 0);
1049  state.in_tarhdr = true;
1050 
1051  /* recovery.conf is integrated into postgresql.conf in 12 and newer */
1053  state.is_recovery_guc_supported = true;
1054 
1055  if (state.basetablespace)
1056  {
1057  /*
1058  * Base tablespaces
1059  */
1060  if (strcmp(basedir, "-") == 0)
1061  {
1062 #ifdef WIN32
1063  _setmode(fileno(stdout), _O_BINARY);
1064 #endif
1065 
1066 #ifdef HAVE_LIBZ
1067  if (compresslevel != 0)
1068  {
1069  int fd = dup(fileno(stdout));
1070 
1071  if (fd < 0)
1072  {
1073  pg_log_error("could not duplicate stdout: %m");
1074  exit(1);
1075  }
1076 
1077  state.ztarfile = gzdopen(fd, "wb");
1078  if (state.ztarfile == NULL)
1079  {
1080  pg_log_error("could not open output file: %m");
1081  exit(1);
1082  }
1083 
1084  if (gzsetparams(state.ztarfile, compresslevel,
1085  Z_DEFAULT_STRATEGY) != Z_OK)
1086  {
1087  pg_log_error("could not set compression level %d: %s",
1088  compresslevel, get_gz_error(state.ztarfile));
1089  exit(1);
1090  }
1091  }
1092  else
1093 #endif
1094  state.tarfile = stdout;
1095  strcpy(state.filename, "-");
1096  }
1097  else
1098  {
1099 #ifdef HAVE_LIBZ
1100  if (compresslevel != 0)
1101  {
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)
1107  {
1108  pg_log_error("could not set compression level %d: %s",
1109  compresslevel, get_gz_error(state.ztarfile));
1110  exit(1);
1111  }
1112  }
1113  else
1114 #endif
1115  {
1116  snprintf(state.filename, sizeof(state.filename),
1117  "%s/base.tar", basedir);
1118  state.tarfile = fopen(state.filename, "wb");
1119  }
1120  }
1121  }
1122  else
1123  {
1124  /*
1125  * Specific tablespace
1126  */
1127 #ifdef HAVE_LIBZ
1128  if (compresslevel != 0)
1129  {
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)
1136  {
1137  pg_log_error("could not set compression level %d: %s",
1138  compresslevel, get_gz_error(state.ztarfile));
1139  exit(1);
1140  }
1141  }
1142  else
1143 #endif
1144  {
1145  snprintf(state.filename, sizeof(state.filename), "%s/%s.tar",
1146  basedir, PQgetvalue(res, rownum, 0));
1147  state.tarfile = fopen(state.filename, "wb");
1148  }
1149  }
1150 
1151 #ifdef HAVE_LIBZ
1152  if (compresslevel != 0)
1153  {
1154  if (!state.ztarfile)
1155  {
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);
1160  }
1161  }
1162  else
1163 #endif
1164  {
1165  /* Either no zlib support, or zlib support but compresslevel = 0 */
1166  if (!state.tarfile)
1167  {
1168  pg_log_error("could not create file \"%s\": %m", state.filename);
1169  exit(1);
1170  }
1171  }
1172 
1173  ReceiveCopyData(conn, ReceiveTarCopyChunk, &state);
1174 
1175  /*
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).
1179  *
1180  * Also, write two completely empty blocks at the end of the tar file, as
1181  * required by some tar programs.
1182  */
1183 
1184  MemSet(zerobuf, 0, sizeof(zerobuf));
1185 
1186  if (state.basetablespace && writerecoveryconf)
1187  {
1188  char header[TAR_BLOCK_SIZE];
1189 
1190  /*
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.
1195  */
1197  {
1198  int padding;
1199 
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));
1206 
1207  padding = tarPaddingBytesRequired(recoveryconfcontents->len);
1208 
1209  writeTarData(&state, header, sizeof(header));
1210  writeTarData(&state, recoveryconfcontents->data,
1211  recoveryconfcontents->len);
1212  if (padding)
1213  writeTarData(&state, zerobuf, padding);
1214  }
1215 
1216  /*
1217  * standby.signal is supported only if recovery parameters are GUCs.
1218  */
1219  if (state.is_recovery_guc_supported)
1220  {
1221  tarCreateHeader(header, "standby.signal", NULL,
1222  0, /* zero-length file */
1223  pg_file_create_mode, 04000, 02000,
1224  time(NULL));
1225 
1226  writeTarData(&state, header, sizeof(header));
1227 
1228  /*
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.
1232  */
1233  }
1234  }
1235 
1236  /*
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.
1240  */
1241  if (strcmp(basedir, "-") == 0 && manifest)
1242  {
1243  char header[TAR_BLOCK_SIZE];
1245 
1246  initPQExpBuffer(&buf);
1247  ReceiveBackupManifestInMemory(conn, &buf);
1248  if (PQExpBufferDataBroken(buf))
1249  {
1250  pg_log_error("out of memory");
1251  exit(1);
1252  }
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);
1259  }
1260 
1261  /* 2 * TAR_BLOCK_SIZE bytes empty data at end of file */
1262  writeTarData(&state, zerobuf, sizeof(zerobuf));
1263 
1264 #ifdef HAVE_LIBZ
1265  if (state.ztarfile != NULL)
1266  {
1267  if (gzclose(state.ztarfile) != 0)
1268  {
1269  pg_log_error("could not close compressed file \"%s\": %s",
1270  state.filename, get_gz_error(state.ztarfile));
1271  exit(1);
1272  }
1273  }
1274  else
1275 #endif
1276  {
1277  if (strcmp(basedir, "-") != 0)
1278  {
1279  if (fclose(state.tarfile) != 0)
1280  {
1281  pg_log_error("could not close file \"%s\": %m",
1282  state.filename);
1283  exit(1);
1284  }
1285  }
1286  }
1287 
1288  progress_report(rownum, state.filename, true, false);
1289 
1290  /*
1291  * Do not sync the resulting tar file yet, all files are synced once at
1292  * the end.
1293  */
1294 }
1295 
1296 /*
1297  * Receive one chunk of tar-format data from the server.
1298  */
1299 static void
1300 ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
1301 {
1302  WriteTarState *state = callback_data;
1303 
1304  if (!writerecoveryconf || !state->basetablespace)
1305  {
1306  /*
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.
1310  */
1311  writeTarData(state, copybuf, r);
1312  }
1313  else
1314  {
1315  /*
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.
1319  *
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.
1325  */
1326  int rr = r;
1327  int pos = 0;
1328 
1329  while (rr > 0)
1330  {
1331  if (state->in_tarhdr)
1332  {
1333  /*
1334  * We're currently reading a header structure inside the TAR
1335  * stream, i.e. the file metadata.
1336  */
1337  if (state->tarhdrsz < TAR_BLOCK_SIZE)
1338  {
1339  /*
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.
1343  */
1344  int hdrleft;
1345  int bytes2copy;
1346 
1347  hdrleft = TAR_BLOCK_SIZE - state->tarhdrsz;
1348  bytes2copy = (rr > hdrleft ? hdrleft : rr);
1349 
1350  memcpy(&state->tarhdr[state->tarhdrsz], copybuf + pos,
1351  bytes2copy);
1352 
1353  rr -= bytes2copy;
1354  pos += bytes2copy;
1355  state->tarhdrsz += bytes2copy;
1356  }
1357  else
1358  {
1359  /*
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.
1366  */
1367  if (state->is_recovery_guc_supported)
1368  {
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);
1373  }
1374  else
1375  state->skip_file =
1376  (strcmp(&state->tarhdr[0], "recovery.conf") == 0);
1377 
1378  state->filesz = read_tar_number(&state->tarhdr[124], 12);
1379  state->file_padding_len =
1381 
1382  if (state->is_recovery_guc_supported &&
1383  state->is_postgresql_auto_conf &&
1385  {
1386  /* replace tar header */
1387  char header[TAR_BLOCK_SIZE];
1388 
1389  tarCreateHeader(header, "postgresql.auto.conf", NULL,
1390  state->filesz + recoveryconfcontents->len,
1391  pg_file_create_mode, 04000, 02000,
1392  time(NULL));
1393 
1394  writeTarData(state, header, sizeof(header));
1395  }
1396  else
1397  {
1398  /* copy stream with padding */
1399  state->filesz += state->file_padding_len;
1400 
1401  if (!state->skip_file)
1402  {
1403  /*
1404  * If we're not skipping the file, write the tar
1405  * header unmodified.
1406  */
1407  writeTarData(state, state->tarhdr, TAR_BLOCK_SIZE);
1408  }
1409  }
1410 
1411  /* Next part is the file, not the header */
1412  state->in_tarhdr = false;
1413  }
1414  }
1415  else
1416  {
1417  /*
1418  * We're processing a file's contents.
1419  */
1420  if (state->filesz > 0)
1421  {
1422  /*
1423  * We still have data to read (and possibly write).
1424  */
1425  int bytes2write;
1426 
1427  bytes2write = (state->filesz > rr ? rr : state->filesz);
1428 
1429  if (!state->skip_file)
1430  writeTarData(state, copybuf + pos, bytes2write);
1431 
1432  rr -= bytes2write;
1433  pos += bytes2write;
1434  state->filesz -= bytes2write;
1435  }
1436  else if (state->is_recovery_guc_supported &&
1437  state->is_postgresql_auto_conf &&
1439  {
1440  /* append recovery config to postgresql.auto.conf */
1441  int padding;
1442  int tailsize;
1443 
1444  tailsize = (TAR_BLOCK_SIZE - state->file_padding_len) + recoveryconfcontents->len;
1445  padding = tarPaddingBytesRequired(tailsize);
1446 
1447  writeTarData(state, recoveryconfcontents->data,
1448  recoveryconfcontents->len);
1449 
1450  if (padding)
1451  {
1452  char zerobuf[TAR_BLOCK_SIZE];
1453 
1454  MemSet(zerobuf, 0, sizeof(zerobuf));
1455  writeTarData(state, zerobuf, padding);
1456  }
1457 
1458  /* skip original file padding */
1459  state->is_postgresql_auto_conf = false;
1460  state->skip_file = true;
1461  state->filesz += state->file_padding_len;
1462 
1463  state->found_postgresql_auto_conf = true;
1464  }
1465  else
1466  {
1467  /*
1468  * No more data in the current file, the next piece of
1469  * data (if any) will be a new file header structure.
1470  */
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;
1476  }
1477  }
1478  }
1479  }
1480  totaldone += r;
1481  progress_report(state->tablespacenum, state->filename, false, false);
1482 }
1483 
1484 
1485 /*
1486  * Retrieve tablespace path, either relocated or original depending on whether
1487  * -T was passed or not.
1488  */
1489 static const char *
1490 get_tablespace_mapping(const char *dir)
1491 {
1492  TablespaceListCell *cell;
1493  char canon_dir[MAXPGPATH];
1494 
1495  /* Canonicalize path for comparison consistency */
1496  strlcpy(canon_dir, dir, sizeof(canon_dir));
1497  canonicalize_path(canon_dir);
1498 
1499  for (cell = tablespace_dirs.head; cell; cell = cell->next)
1500  if (strcmp(canon_dir, cell->old_dir) == 0)
1501  return cell->new_dir;
1502 
1503  return dir;
1504 }
1505 
1506 
1507 /*
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.
1511  *
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.
1515  */
1516 static void
1518 {
1520  bool basetablespace;
1521 
1522  memset(&state, 0, sizeof(state));
1523  state.tablespacenum = rownum;
1524 
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));
1532 
1534 
1535 
1536  if (state.file)
1537  fclose(state.file);
1538 
1539  progress_report(rownum, state.filename, true, false);
1540 
1541  if (state.file != NULL)
1542  {
1543  pg_log_error("COPY stream ended before last file was finished");
1544  exit(1);
1545  }
1546 
1547  if (basetablespace && writerecoveryconf)
1548  WriteRecoveryConfig(conn, basedir, recoveryconfcontents);
1549 
1550  /*
1551  * No data is synced here, everything is done for all tablespaces at the
1552  * end.
1553  */
1554 }
1555 
1556 static void
1557 ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
1558 {
1559  UnpackTarState *state = callback_data;
1560 
1561  if (state->file == NULL)
1562  {
1563 #ifndef WIN32
1564  int filemode;
1565 #endif
1566 
1567  /*
1568  * No current file, so this must be the header for a new file
1569  */
1570  if (r != TAR_BLOCK_SIZE)
1571  {
1572  pg_log_error("invalid tar block header size: %zu", r);
1573  exit(1);
1574  }
1576 
1577  state->current_len_left = read_tar_number(&copybuf[124], 12);
1578 
1579 #ifndef WIN32
1580  /* Set permissions on the file */
1581  filemode = read_tar_number(&copybuf[100], 8);
1582 #endif
1583 
1584  /*
1585  * All files are padded up to a multiple of TAR_BLOCK_SIZE
1586  */
1587  state->current_padding =
1589 
1590  /*
1591  * First part of header is zero terminated filename
1592  */
1593  snprintf(state->filename, sizeof(state->filename),
1594  "%s/%s", state->current_path, copybuf);
1595  if (state->filename[strlen(state->filename) - 1] == '/')
1596  {
1597  /*
1598  * Ends in a slash means directory or symlink to directory
1599  */
1600  if (copybuf[156] == '5')
1601  {
1602  /*
1603  * Directory. Remove trailing slash first.
1604  */
1605  state->filename[strlen(state->filename) - 1] = '\0';
1606  if (mkdir(state->filename, pg_dir_create_mode) != 0)
1607  {
1608  /*
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.
1616  */
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))
1621  {
1622  pg_log_error("could not create directory \"%s\": %m",
1623  state->filename);
1624  exit(1);
1625  }
1626  }
1627 #ifndef WIN32
1628  if (chmod(state->filename, (mode_t) filemode))
1629  {
1630  pg_log_error("could not set permissions on directory \"%s\": %m",
1631  state->filename);
1632  exit(1);
1633  }
1634 #endif
1635  }
1636  else if (copybuf[156] == '2')
1637  {
1638  /*
1639  * Symbolic link
1640  *
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.)
1649  */
1650  state->filename[strlen(state->filename) - 1] = '\0'; /* Remove trailing slash */
1651 
1652  state->mapped_tblspc_path =
1653  get_tablespace_mapping(&copybuf[157]);
1654  if (symlink(state->mapped_tblspc_path, state->filename) != 0)
1655  {
1656  pg_log_error("could not create symbolic link from \"%s\" to \"%s\": %m",
1657  state->filename, state->mapped_tblspc_path);
1658  exit(1);
1659  }
1660  }
1661  else
1662  {
1663  pg_log_error("unrecognized link indicator \"%c\"",
1664  copybuf[156]);
1665  exit(1);
1666  }
1667  return; /* directory or link handled */
1668  }
1669 
1670  /*
1671  * regular file
1672  */
1673  state->file = fopen(state->filename, "wb");
1674  if (!state->file)
1675  {
1676  pg_log_error("could not create file \"%s\": %m", state->filename);
1677  exit(1);
1678  }
1679 
1680 #ifndef WIN32
1681  if (chmod(state->filename, (mode_t) filemode))
1682  {
1683  pg_log_error("could not set permissions on file \"%s\": %m",
1684  state->filename);
1685  exit(1);
1686  }
1687 #endif
1688 
1689  if (state->current_len_left == 0)
1690  {
1691  /*
1692  * Done with this file, next one will be a new tar header
1693  */
1694  fclose(state->file);
1695  state->file = NULL;
1696  return;
1697  }
1698  } /* new file */
1699  else
1700  {
1701  /*
1702  * Continuing blocks in existing file
1703  */
1704  if (state->current_len_left == 0 && r == state->current_padding)
1705  {
1706  /*
1707  * Received the padding block for this file, ignore it and close
1708  * the file, then move on to the next tar header.
1709  */
1710  fclose(state->file);
1711  state->file = NULL;
1712  totaldone += r;
1713  return;
1714  }
1715 
1716  errno = 0;
1717  if (fwrite(copybuf, r, 1, state->file) != 1)
1718  {
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);
1724  }
1725  totaldone += r;
1726  progress_report(state->tablespacenum, state->filename, false, false);
1727 
1728  state->current_len_left -= r;
1729  if (state->current_len_left == 0 && state->current_padding == 0)
1730  {
1731  /*
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.
1734  */
1735  fclose(state->file);
1736  state->file = NULL;
1737  return;
1738  }
1739  } /* continuing data in existing file */
1740 }
1741 
1742 /*
1743  * Receive the backup manifest file and write it out to a file.
1744  */
1745 static void
1747 {
1749 
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)
1754  {
1755  pg_log_error("could not create file \"%s\": %m", state.filename);
1756  exit(1);
1757  }
1758 
1760 
1761  fclose(state.file);
1762 }
1763 
1764 /*
1765  * Receive one chunk of the backup manifest file and write it out to a file.
1766  */
1767 static void
1768 ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
1769 {
1770  WriteManifestState *state = callback_data;
1771 
1772  errno = 0;
1773  if (fwrite(copybuf, r, 1, state->file) != 1)
1774  {
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);
1780  }
1781 }
1782 
1783 /*
1784  * Receive the backup manifest file and write it out to a file.
1785  */
1786 static void
1788 {
1790 }
1791 
1792 /*
1793  * Receive one chunk of the backup manifest file and write it out to a file.
1794  */
1795 static void
1797  void *callback_data)
1798 {
1799  PQExpBuffer buf = callback_data;
1800 
1801  appendPQExpBuffer(buf, copybuf, r);
1802 }
1803 
1804 static void
1806 {
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;
1824 
1825  Assert(conn != NULL);
1826 
1827  /*
1828  * Check server version. BASE_BACKUP command was introduced in 9.1, so we
1829  * can't work with servers older than 9.1.
1830  */
1831  minServerMajor = 901;
1832  maxServerMajor = PG_VERSION_NUM / 100;
1833  serverVersion = PQserverVersion(conn);
1834  serverMajor = serverVersion / 100;
1835  if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1836  {
1837  const char *serverver = PQparameterStatus(conn, "server_version");
1838 
1839  pg_log_error("incompatible server version %s",
1840  serverver ? serverver : "'unknown'");
1841  exit(1);
1842  }
1843 
1844  /*
1845  * If WAL streaming was requested, also check that the server is new
1846  * enough for that.
1847  */
1849  {
1850  /*
1851  * Error message already written in CheckServerVersionForStreaming(),
1852  * but add a hint about using -X none.
1853  */
1854  pg_log_info("HINT: use -X none or -X fetch to disable log streaming");
1855  exit(1);
1856  }
1857 
1858  /*
1859  * Build contents of configuration file if requested
1860  */
1861  if (writerecoveryconf)
1862  recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot);
1863 
1864  /*
1865  * Run IDENTIFY_SYSTEM so we can get the timeline
1866  */
1867  if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
1868  exit(1);
1869 
1870  /*
1871  * Start the actual backup
1872  */
1873  PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i);
1874 
1875  if (maxrate > 0)
1876  maxrate_clause = psprintf("MAX_RATE %u", maxrate);
1877 
1878  if (manifest)
1879  {
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'",
1887  }
1888 
1889  if (verbose)
1890  pg_log_info("initiating base backup, waiting for checkpoint to complete");
1891 
1892  if (showprogress && !verbose)
1893  {
1894  fprintf(stderr, "waiting for checkpoint");
1895  if (isatty(fileno(stderr)))
1896  fprintf(stderr, "\r");
1897  else
1898  fprintf(stderr, "\n");
1899  }
1900 
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);
1913 
1914  if (PQsendQuery(conn, basebkp) == 0)
1915  {
1916  pg_log_error("could not send replication command \"%s\": %s",
1917  "BASE_BACKUP", PQerrorMessage(conn));
1918  exit(1);
1919  }
1920 
1921  /*
1922  * Get the starting WAL location
1923  */
1924  res = PQgetResult(conn);
1925  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1926  {
1927  pg_log_error("could not initiate base backup: %s",
1928  PQerrorMessage(conn));
1929  exit(1);
1930  }
1931  if (PQntuples(res) != 1)
1932  {
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);
1936  }
1937 
1938  strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
1939 
1940  if (verbose)
1941  pg_log_info("checkpoint completed");
1942 
1943  /*
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.
1947  */
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));
1954 
1955  if (verbose && includewal != NO_WAL)
1956  pg_log_info("write-ahead log start point: %s on timeline %u",
1957  xlogstart, starttli);
1958 
1959  /*
1960  * Get the header
1961  */
1962  res = PQgetResult(conn);
1963  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1964  {
1965  pg_log_error("could not get backup header: %s",
1966  PQerrorMessage(conn));
1967  exit(1);
1968  }
1969  if (PQntuples(res) < 1)
1970  {
1971  pg_log_error("no data returned from server");
1972  exit(1);
1973  }
1974 
1975  /*
1976  * Sum up the total size, for progress reporting
1977  */
1978  totalsize_kb = totaldone = 0;
1979  tablespacecount = PQntuples(res);
1980  for (i = 0; i < PQntuples(res); i++)
1981  {
1982  totalsize_kb += atol(PQgetvalue(res, i, 2));
1983 
1984  /*
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.
1988  */
1989  if (format == 'p' && !PQgetisnull(res, i, 1))
1990  {
1991  char *path = unconstify(char *, get_tablespace_mapping(PQgetvalue(res, i, 1)));
1992 
1994  }
1995  }
1996 
1997  /*
1998  * When writing to stdout, require a single tablespace
1999  */
2000  writing_to_stdout = format == 't' && strcmp(basedir, "-") == 0;
2001  if (writing_to_stdout && PQntuples(res) > 1)
2002  {
2003  pg_log_error("can only write single tablespace to stdout, database has %d",
2004  PQntuples(res));
2005  exit(1);
2006  }
2007 
2008  /*
2009  * If we're streaming WAL, start the streaming session before we start
2010  * receiving the actual data chunks.
2011  */
2012  if (includewal == STREAM_WAL)
2013  {
2014  if (verbose)
2015  pg_log_info("starting background WAL receiver");
2016  StartLogStreamer(xlogstart, starttli, sysidentifier);
2017  }
2018 
2019  /*
2020  * Start receiving chunks
2021  */
2022  for (i = 0; i < PQntuples(res); i++)
2023  {
2024  if (format == 't')
2025  ReceiveTarFile(conn, res, i);
2026  else
2027  ReceiveAndUnpackTarFile(conn, res, i);
2028  } /* Loop over all tablespaces */
2029 
2030  /*
2031  * Now receive backup manifest, if appropriate.
2032  *
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.
2036  *
2037  * If we're talking to an older server, it won't send a backup manifest,
2038  * so don't try to receive one.
2039  */
2040  if (!writing_to_stdout && manifest)
2042 
2043  if (showprogress)
2044  progress_report(PQntuples(res), NULL, true, true);
2045 
2046  PQclear(res);
2047 
2048  /*
2049  * Get the stop position
2050  */
2051  res = PQgetResult(conn);
2052  if (PQresultStatus(res) != PGRES_TUPLES_OK)
2053  {
2054  pg_log_error("could not get write-ahead log end position from server: %s",
2055  PQerrorMessage(conn));
2056  exit(1);
2057  }
2058  if (PQntuples(res) != 1)
2059  {
2060  pg_log_error("no write-ahead log end position returned from server");
2061  exit(1);
2062  }
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);
2067 
2068  res = PQgetResult(conn);
2069  if (PQresultStatus(res) != PGRES_COMMAND_OK)
2070  {
2071  const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
2072 
2073  if (sqlstate &&
2074  strcmp(sqlstate, ERRCODE_DATA_CORRUPTED) == 0)
2075  {
2076  pg_log_error("checksum error occurred");
2077  checksum_failure = true;
2078  }
2079  else
2080  {
2081  pg_log_error("final receive failed: %s",
2082  PQerrorMessage(conn));
2083  }
2084  exit(1);
2085  }
2086 
2087  if (bgchild > 0)
2088  {
2089 #ifndef WIN32
2090  int status;
2091  pid_t r;
2092 #else
2093  DWORD status;
2094 
2095  /*
2096  * get a pointer sized version of bgchild to avoid warnings about
2097  * casting to a different size on WIN64.
2098  */
2099  intptr_t bgchild_handle = bgchild;
2100  uint32 hi,
2101  lo;
2102 #endif
2103 
2104  if (verbose)
2105  pg_log_info("waiting for background process to finish streaming ...");
2106 
2107 #ifndef WIN32
2108  if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2109  {
2110  pg_log_info("could not send command to background pipe: %m");
2111  exit(1);
2112  }
2113 
2114  /* Just wait for the background process to exit */
2115  r = waitpid(bgchild, &status, 0);
2116  if (r == (pid_t) -1)
2117  {
2118  pg_log_error("could not wait for child process: %m");
2119  exit(1);
2120  }
2121  if (r != bgchild)
2122  {
2123  pg_log_error("child %d died, expected %d", (int) r, (int) bgchild);
2124  exit(1);
2125  }
2126  if (status != 0)
2127  {
2128  pg_log_error("%s", wait_result_to_str(status));
2129  exit(1);
2130  }
2131  /* Exited normally, we're happy! */
2132 #else /* WIN32 */
2133 
2134  /*
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.
2138  */
2139  if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
2140  {
2141  pg_log_error("could not parse write-ahead log location \"%s\"",
2142  xlogend);
2143  exit(1);
2144  }
2145  xlogendptr = ((uint64) hi) << 32 | lo;
2146  InterlockedIncrement(&has_xlogendptr);
2147 
2148  /* First wait for the thread to exit */
2149  if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2150  WAIT_OBJECT_0)
2151  {
2152  _dosmaperr(GetLastError());
2153  pg_log_error("could not wait for child thread: %m");
2154  exit(1);
2155  }
2156  if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2157  {
2158  _dosmaperr(GetLastError());
2159  pg_log_error("could not get child thread exit status: %m");
2160  exit(1);
2161  }
2162  if (status != 0)
2163  {
2164  pg_log_error("child thread exited with error %u",
2165  (unsigned int) status);
2166  exit(1);
2167  }
2168  /* Exited normally, we're happy */
2169 #endif
2170  }
2171 
2172  /* Free the configuration file contents */
2173  destroyPQExpBuffer(recoveryconfcontents);
2174 
2175  /*
2176  * End of copy data. Final result is already checked inside the loop.
2177  */
2178  PQclear(res);
2179  PQfinish(conn);
2180  conn = NULL;
2181 
2182  /*
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.
2188  */
2189  if (do_sync)
2190  {
2191  if (verbose)
2192  pg_log_info("syncing data to disk ...");
2193  if (format == 't')
2194  {
2195  if (strcmp(basedir, "-") != 0)
2196  (void) fsync_dir_recurse(basedir);
2197  }
2198  else
2199  {
2200  (void) fsync_pgdata(basedir, serverVersion);
2201  }
2202  }
2203 
2204  /*
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.
2210  */
2211  if (!writing_to_stdout && manifest)
2212  {
2213  char tmp_filename[MAXPGPATH];
2214  char filename[MAXPGPATH];
2215 
2216  if (verbose)
2217  pg_log_info("renaming backup_manifest.tmp to backup_manifest");
2218 
2219  snprintf(tmp_filename, MAXPGPATH, "%s/backup_manifest.tmp", basedir);
2220  snprintf(filename, MAXPGPATH, "%s/backup_manifest", basedir);
2221 
2222  /* durable_rename emits its own log message in case of failure */
2223  if (durable_rename(tmp_filename, filename) != 0)
2224  exit(1);
2225  }
2226 
2227  if (verbose)
2228  pg_log_info("base backup completed");
2229 }
2230 
2231 
2232 int
2233 main(int argc, char **argv)
2234 {
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}
2269  };
2270  int c;
2271 
2272  int option_index;
2273 
2274  pg_logging_init(argv[0]);
2275  progname = get_progname(argv[0]);
2276  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
2277 
2278  if (argc > 1)
2279  {
2280  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2281  {
2282  usage();
2283  exit(0);
2284  }
2285  else if (strcmp(argv[1], "-V") == 0
2286  || strcmp(argv[1], "--version") == 0)
2287  {
2288  puts("pg_basebackup (PostgreSQL) " PG_VERSION);
2289  exit(0);
2290  }
2291  }
2292 
2294 
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)
2297  {
2298  switch (c)
2299  {
2300  case 'C':
2301  create_slot = true;
2302  break;
2303  case 'D':
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
2312  {
2313  pg_log_error("invalid output format \"%s\", must be \"plain\" or \"tar\"",
2314  optarg);
2315  exit(1);
2316  }
2317  break;
2318  case 'r':
2320  break;
2321  case 'R':
2322  writerecoveryconf = true;
2323  break;
2324  case 'S':
2325 
2326  /*
2327  * When specifying replication slot name, use a permanent
2328  * slot.
2329  */
2331  temp_replication_slot = false;
2332  break;
2333  case 2:
2334  no_slot = true;
2335  break;
2336  case 'T':
2338  break;
2339  case 'X':
2340  if (strcmp(optarg, "n") == 0 ||
2341  strcmp(optarg, "none") == 0)
2342  {
2343  includewal = NO_WAL;
2344  }
2345  else if (strcmp(optarg, "f") == 0 ||
2346  strcmp(optarg, "fetch") == 0)
2347  {
2349  }
2350  else if (strcmp(optarg, "s") == 0 ||
2351  strcmp(optarg, "stream") == 0)
2352  {
2354  }
2355  else
2356  {
2357  pg_log_error("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2358  optarg);
2359  exit(1);
2360  }
2361  break;
2362  case 1:
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
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
2392  {
2393  pg_log_error("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2394  optarg);
2395  exit(1);
2396  }
2397  break;
2398  case 'd':
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,
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:
2443  break;
2444  default:
2445 
2446  /*
2447  * getopt_long already emitted a complaint
2448  */
2449  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2450  progname);
2451  exit(1);
2452  }
2453  }
2454 
2455  /*
2456  * Any non-option arguments?
2457  */
2458  if (optind < argc)
2459  {
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);
2465  }
2466 
2467  /*
2468  * Required arguments
2469  */
2470  if (basedir == NULL)
2471  {
2472  pg_log_error("no target directory specified");
2473  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2474  progname);
2475  exit(1);
2476  }
2477 
2478  /*
2479  * Mutually exclusive arguments
2480  */
2481  if (format == 'p' && compresslevel != 0)
2482  {
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);
2487  }
2488 
2489  if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
2490  {
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);
2495  }
2496 
2498  {
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);
2503  }
2504 
2505  if (no_slot)
2506  {
2507  if (replication_slot)
2508  {
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);
2513  }
2514  temp_replication_slot = false;
2515  }
2516 
2517  if (create_slot)
2518  {
2519  if (!replication_slot)
2520  {
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);
2526  }
2527 
2528  if (no_slot)
2529  {
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);
2535  }
2536  }
2537 
2538  if (xlog_dir)
2539  {
2540  if (format != 'p')
2541  {
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);
2546  }
2547 
2548  /* clean up xlog directory name, check it's absolute */
2550  if (!is_absolute_path(xlog_dir))
2551  {
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);
2556  }
2557  }
2558 
2559 #ifndef HAVE_LIBZ
2560  if (compresslevel != 0)
2561  {
2562  pg_log_error("this build does not support compression");
2563  exit(1);
2564  }
2565 #endif
2566 
2567  if (showprogress && !estimatesize)
2568  {
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);
2574  }
2575 
2576  if (!manifest && manifest_checksums != NULL)
2577  {
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);
2583  }
2584 
2586  {
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);
2592  }
2593 
2594  /* connection in replication mode to server */
2595  conn = GetConnection();
2596  if (!conn)
2597  {
2598  /* Error message already written in GetConnection() */
2599  exit(1);
2600  }
2601  atexit(disconnect_atexit);
2602 
2603  /*
2604  * Set umask so that directories/files are created with the same
2605  * permissions as directories/files in the source data directory.
2606  *
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().
2610  */
2611  umask(pg_mode_mask);
2612 
2613  /* Backup manifests are supported in 13 and newer versions */
2615  manifest = false;
2616 
2617  /*
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.
2621  */
2622  if (format == 'p' || strcmp(basedir, "-") != 0)
2624 
2625  /* determine remote server's xlog segment size */
2626  if (!RetrieveWalSegSize(conn))
2627  exit(1);
2628 
2629  /* Create pg_wal symlink, if required */
2630  if (xlog_dir)
2631  {
2632  char *linkloc;
2633 
2635 
2636  /*
2637  * Form name of the place where the symlink must go. pg_xlog has been
2638  * renamed to pg_wal in post-10 clusters.
2639  */
2640  linkloc = psprintf("%s/%s", basedir,
2642  "pg_xlog" : "pg_wal");
2643 
2644 #ifdef HAVE_SYMLINK
2645  if (symlink(xlog_dir, linkloc) != 0)
2646  {
2647  pg_log_error("could not create symbolic link \"%s\": %m", linkloc);
2648  exit(1);
2649  }
2650 #else
2651  pg_log_error("symlinks are not supported on this platform");
2652  exit(1);
2653 #endif
2654  free(linkloc);
2655  }
2656 
2657  BaseBackup();
2658 
2659  success = true;
2660  return 0;
2661 }
bool found_postgresql_auto_conf
Definition: pg_basebackup.c:73
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3256
char current_path[MAXPGPATH]
Definition: pg_basebackup.c:85
static PQExpBuffer recoveryconfcontents
static IncludeWal includewal
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6737
#define Z_DEFAULT_COMPRESSION
int pg_file_create_mode
Definition: file_perm.c:19
static bool verify_checksums
static int bgpipe[2]
static bool found_existing_pgdata
uint32 TimeLineID
Definition: xlogdefs.h:59
const char * progname
Definition: main.c:46
int64 pg_time_t
Definition: pgtime.h:23
bool is_recovery_guc_supported
Definition: pg_basebackup.c:71
static void usage(void)
static bool found_tablespace_dirs
const char * mapped_tblspc_path
Definition: pg_basebackup.c:87
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
Definition: fe-connect.c:6702
bool pg_str_endswith(const char *str, const char *end)
Definition: string.c:31
int pg_mkdir_p(char *path, int omode)
Definition: pgmkdirp.c:57
static TablespaceList tablespace_dirs
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
Definition: option_utils.c:50
#define write(a, b, c)
Definition: win32.h:14
bool do_sync
Definition: receivelog.h:38
const char * get_progname(const char *argv0)
Definition: path.c:453
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
uint64 read_tar_number(const char *s, int len)
Definition: tar.c:58
#define pg_log_error(...)
Definition: logging.h:80
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
static int32 parse_max_rate(char *src)
static bool manifest_force_encode
void pg_logging_init(const char *argv0)
Definition: logging.c:81
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char tarhdr[TAR_BLOCK_SIZE]
Definition: pg_basebackup.c:67
void WriteRecoveryConfig(PGconn *pgconn, char *target_dir, PQExpBuffer contents)
Definition: recovery_gen.c:117
static pg_time_t last_progress_report
char old_dir[MAXPGPATH]
Definition: pg_basebackup.c:52
static int tablespacecount
static void writeTarData(WriteTarState *state, char *buf, int r)
void _dosmaperr(unsigned long)
Definition: win32error.c:171
bool RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, XLogRecPtr *startpos, char **db_name)
Definition: streamutil.c:409
#define VERBOSE_FILENAME_LENGTH
struct UnpackTarState UnpackTarState
IncludeWal
void canonicalize_path(char *path)
Definition: path.c:254
char * sysidentifier
Definition: receivelog.h:33
static bool writerecoveryconf
static bool create_slot
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4224
static int compresslevel
static bool checksum_failure
#define MemSet(start, val, len)
Definition: c.h:1008
#define MINIMUM_VERSION_FOR_RECOVERY_GUC
Definition: recovery_gen.h:21
#define kill(pid, sig)
Definition: win32_port.h:454
static void ReceiveBackupManifest(PGconn *conn)
#define printf(...)
Definition: port.h:222
char filename[MAXPGPATH]
Definition: pg_basebackup.c:86
XLogRecPtr startpos
Definition: receivelog.h:31
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
char * partial_suffix
Definition: receivelog.h:47
char new_dir[MAXPGPATH]
Definition: pg_basebackup.c:53
int PQserverVersion(const PGconn *conn)
Definition: fe-connect.c:6727
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define fprintf
Definition: port.h:220
static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finished)
char * wait_result_to_str(int exitstatus)
Definition: wait_error.c:32
static int fd(const char *x, int i)
Definition: preproc-init.c:105
TimeLineID timeline
Definition: receivelog.h:32
static char * basedir
struct TablespaceListCell TablespaceListCell
WalWriteMethod * CreateWalDirectoryMethod(const char *basedir, int compression, bool sync)
Definition: walmethods.c:376
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
static void ReceiveBackupManifestInMemory(PGconn *conn, PQExpBuffer buf)
int PQgetCopyData(PGconn *conn, char **buffer, int async)
Definition: fe-exec.c:2668
signed int int32
Definition: c.h:429
int main(int argc, char **argv)
static void BaseBackup(void)
pgoff_t filesz
Definition: pg_basebackup.c:76
#define pgoff_t
Definition: win32_port.h:200
int PQsendQuery(PGconn *conn, const char *query)
Definition: fe-exec.c:1326
void destroyPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:116
#define required_argument
Definition: getopt_long.h:25
static void ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
int optind
Definition: getopt.c:50
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
Definition: connection.c:125
#define MAX_RATE_UPPER
Definition: basebackup.h:21
char * connection_string
Definition: streamutil.c:47
static void ReceiveCopyData(PGconn *conn, WriteDataCallback callback, void *callback_data)
struct TablespaceList TablespaceList
bool is_postgresql_auto_conf
Definition: pg_basebackup.c:72
bool RetrieveWalSegSize(PGconn *conn)
Definition: streamutil.c:277
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
PGconn * conn
Definition: streamutil.c:54
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
Definition: test_ifaddrs.c:48
#define MINIMUM_VERSION_FOR_PG_WAL
static bool found_existing_xlogdir
static uint64 totaldone
static bool estimatesize
char * replication_slot
Definition: receivelog.h:48
bool mark_done
Definition: receivelog.h:37
static bool success
#define TAR_BLOCK_SIZE
Definition: pgtar.h:17
static int32 maxrate
char * c
static char * buf
Definition: pg_test_fsync.c:68
#define symlink(oldpath, newpath)
Definition: win32_port.h:227
static int has_xlogendptr
static bool made_new_pgdata
#define is_absolute_path(filename)
Definition: port.h:86
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3910
#define select(n, r, w, e, timeout)
Definition: win32_port.h:464
unsigned int uint32
Definition: c.h:441
static char * manifest_checksums
static const char * get_tablespace_mapping(const char *dir)
static void ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
Definition: fd.c:692
XLogRecPtr startptr
PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, char *replication_slot)
Definition: recovery_gen.c:23
stream_stop_callback stream_stop
Definition: receivelog.h:41
#define ERRCODE_DATA_CORRUPTED
Definition: pg_basebackup.c:47
WalWriteMethod * walmethod
Definition: receivelog.h:46
static int verbose
#define unconstify(underlying_type, expr)
Definition: c.h:1243
bool rmtree(const char *path, bool rmtopdir)
Definition: rmtree.c:42
static int standby_message_timeout
int pg_dir_create_mode
Definition: file_perm.c:18
static bool showprogress
enum tarError tarCreateHeader(char *h, const char *filename, const char *linktarget, pgoff_t size, mode_t mode, uid_t uid, gid_t gid, time_t mtime)
Definition: tar.c:114
int dbgetpassword
Definition: streamutil.c:52
#define no_argument
Definition: getopt_long.h:24
void FreeWalTarMethod(void)
Definition: walmethods.c:1068
#define ngettext(s, p, n)
Definition: c.h:1182
#define PG_TEXTDOMAIN(domain)
Definition: c.h:1215
static bool temp_replication_slot
int PQbackendPID(const PGconn *conn)
Definition: fe-connect.c:6771
#define PGINVALID_SOCKET
Definition: port.h:33
static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
struct TablespaceListCell * next
Definition: pg_basebackup.c:51
static char * label
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
StringInfo copybuf
Definition: tablesync.c:124
static size_t tarPaddingBytesRequired(size_t len)
Definition: pgtar.h:40
static void disconnect_atexit(void)
static void StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier)
TablespaceListCell * tail
Definition: pg_basebackup.c:59
char * dbport
Definition: streamutil.c:50
static void cleanup_directories_atexit(void)
void PQclear(PGresult *res)
Definition: fe-exec.c:694
static void ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf, void *callback_data)
#define free(a)
Definition: header.h:65
static bool in_log_streamer
#define MINIMUM_VERSION_FOR_MANIFESTS
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define PQExpBufferDataBroken(buf)
Definition: pqexpbuffer.h:67
char * PQresultErrorField(const PGresult *res, int fieldcode)
Definition: fe-exec.c:3233
static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:804
Definition: regguts.h:317
WalWriteMethod * CreateWalTarMethod(const char *tarbase, int compression, bool sync)
Definition: walmethods.c:1035
static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
char * dbhost
Definition: streamutil.c:48
void(* WriteDataCallback)(size_t nbytes, char *buf, void *callback_data)
Definition: pg_basebackup.c:99
bool ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
Definition: receivelog.c:444
static void kill_bgchild_atexit(void)
#define strerror
Definition: port.h:229
static char * xlog_dir
static bool manifest
static XLogRecPtr xlogendptr
static XLogRecPtr startpos
static bool no_slot
TablespaceListCell * head
Definition: pg_basebackup.c:58
bool synchronous
Definition: receivelog.h:36
void pg_free(void *ptr)
Definition: fe_memutils.c:105
bool(* finish)(void)
Definition: walmethods.h:84
struct WriteManifestState WriteManifestState
pgsocket stop_socket
Definition: receivelog.h:43
static void header(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:210
#define INT64_FORMAT
Definition: c.h:483
static bool made_new_xlogdir
static void CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
Definition: walsender.c:924
uint32 WalSegSz
Definition: streamutil.c:34
static bool fastcheckpoint
static void tablespace_list_append(const char *arg)
static bool made_tablespace_dirs
static char * filename
Definition: pg_dumpall.c:92
void set_pglocale_pgservice(const char *argv0, const char *app)
Definition: exec.c:433
int errmsg(const char *fmt,...)
Definition: elog.c:909
static pid_t bgchild
char * dbuser
Definition: streamutil.c:49
char * optarg
Definition: getopt.c:52
static uint64 totalsize_kb
struct WriteTarState WriteTarState
int pg_check_dir(const char *dir)
Definition: pgcheckdir.c:31
int i
int standby_message_timeout
Definition: receivelog.h:35
void * arg
static bool do_sync
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
static char format
char filename[MAXPGPATH]
Definition: pg_basebackup.c:95
#define mkdir(a, b)
Definition: win32_port.h:63
static char * replication_slot
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
static int LogStreamerMain(logstreamer_param *param)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3667
#define snprintf
Definition: port.h:216
#define _(x)
Definition: elog.c:89
void PQfreemem(void *ptr)
Definition: fe-exec.c:3796
int pg_mode_mask
Definition: file_perm.c:25
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1544
PGresult * PQgetResult(PGconn *conn)
Definition: fe-exec.c:1978
#define MINIMUM_VERSION_FOR_TEMP_SLOTS
#define read(a, b, c)
Definition: win32.h:13
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
#define pg_log_info(...)
Definition: logging.h:88
void FreeWalDirectoryMethod(void)
Definition: walmethods.c:402
bool CheckServerVersionForStreaming(PGconn *conn)
Definition: receivelog.c:366
char filename[MAXPGPATH]
Definition: pg_basebackup.c:65
static void progress_report(int tablespacenum, const char *filename, bool force, bool finished)
char xlog[MAXPGPATH]
pgoff_t current_len_left
Definition: pg_basebackup.c:88
static bool noclean