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  snprintf(totaldone_str, sizeof(totaldone_str), UINT64_FORMAT,
808  totaldone / 1024);
809  snprintf(totalsize_str, sizeof(totalsize_str), UINT64_FORMAT, totalsize_kb);
810 
811 #define VERBOSE_FILENAME_LENGTH 35
812  if (verbose)
813  {
814  if (!filename)
815 
816  /*
817  * No filename given, so clear the status line (used for last
818  * call)
819  */
820  fprintf(stderr,
821  ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
822  "%*s/%s kB (100%%), %d/%d tablespaces %*s",
824  (int) strlen(totalsize_str),
825  totaldone_str, totalsize_str,
826  tablespacenum, tablespacecount,
827  VERBOSE_FILENAME_LENGTH + 5, "");
828  else
829  {
830  bool truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH);
831 
832  fprintf(stderr,
833  ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
834  "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
836  (int) strlen(totalsize_str),
837  totaldone_str, totalsize_str, percent,
838  tablespacenum, tablespacecount,
839  /* Prefix with "..." if we do leading truncation */
840  truncate ? "..." : "",
843  /* Truncate filename at beginning if it's too long */
844  truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename);
845  }
846  }
847  else
848  fprintf(stderr,
849  ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
850  "%*s/%s kB (%d%%), %d/%d tablespaces",
852  (int) strlen(totalsize_str),
853  totaldone_str, totalsize_str, percent,
854  tablespacenum, tablespacecount);
855 
856  /*
857  * Stay on the same line if reporting to a terminal and we're not done
858  * yet.
859  */
860  fputc((!finished && isatty(fileno(stderr))) ? '\r' : '\n', stderr);
861 }
862 
863 static int32
864 parse_max_rate(char *src)
865 {
866  double result;
867  char *after_num;
868  char *suffix = NULL;
869 
870  errno = 0;
871  result = strtod(src, &after_num);
872  if (src == after_num)
873  {
874  pg_log_error("transfer rate \"%s\" is not a valid value", src);
875  exit(1);
876  }
877  if (errno != 0)
878  {
879  pg_log_error("invalid transfer rate \"%s\": %m", src);
880  exit(1);
881  }
882 
883  if (result <= 0)
884  {
885  /*
886  * Reject obviously wrong values here.
887  */
888  pg_log_error("transfer rate must be greater than zero");
889  exit(1);
890  }
891 
892  /*
893  * Evaluate suffix, after skipping over possible whitespace. Lack of
894  * suffix means kilobytes.
895  */
896  while (*after_num != '\0' && isspace((unsigned char) *after_num))
897  after_num++;
898 
899  if (*after_num != '\0')
900  {
901  suffix = after_num;
902  if (*after_num == 'k')
903  {
904  /* kilobyte is the expected unit. */
905  after_num++;
906  }
907  else if (*after_num == 'M')
908  {
909  after_num++;
910  result *= 1024.0;
911  }
912  }
913 
914  /* The rest can only consist of white space. */
915  while (*after_num != '\0' && isspace((unsigned char) *after_num))
916  after_num++;
917 
918  if (*after_num != '\0')
919  {
920  pg_log_error("invalid --max-rate unit: \"%s\"", suffix);
921  exit(1);
922  }
923 
924  /* Valid integer? */
925  if ((uint64) result != (uint64) ((uint32) result))
926  {
927  pg_log_error("transfer rate \"%s\" exceeds integer range", src);
928  exit(1);
929  }
930 
931  /*
932  * The range is checked on the server side too, but avoid the server
933  * connection if a nonsensical value was passed.
934  */
935  if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
936  {
937  pg_log_error("transfer rate \"%s\" is out of range", src);
938  exit(1);
939  }
940 
941  return (int32) result;
942 }
943 
944 /*
945  * Read a stream of COPY data and invoke the provided callback for each
946  * chunk.
947  */
948 static void
950  void *callback_data)
951 {
952  PGresult *res;
953 
954  /* Get the COPY data stream. */
955  res = PQgetResult(conn);
956  if (PQresultStatus(res) != PGRES_COPY_OUT)
957  {
958  pg_log_error("could not get COPY data stream: %s",
959  PQerrorMessage(conn));
960  exit(1);
961  }
962  PQclear(res);
963 
964  /* Loop over chunks until done. */
965  while (1)
966  {
967  int r;
968  char *copybuf;
969 
970  r = PQgetCopyData(conn, &copybuf, 0);
971  if (r == -1)
972  {
973  /* End of chunk. */
974  break;
975  }
976  else if (r == -2)
977  {
978  pg_log_error("could not read COPY data: %s",
979  PQerrorMessage(conn));
980  exit(1);
981  }
982 
983  (*callback) (r, copybuf, callback_data);
984 
985  PQfreemem(copybuf);
986  }
987 }
988 
989 /*
990  * Write a piece of tar data
991  */
992 static void
994 {
995 #ifdef HAVE_LIBZ
996  if (state->ztarfile != NULL)
997  {
998  errno = 0;
999  if (gzwrite(state->ztarfile, buf, r) != r)
1000  {
1001  /* if write didn't set errno, assume problem is no disk space */
1002  if (errno == 0)
1003  errno = ENOSPC;
1004  pg_log_error("could not write to compressed file \"%s\": %s",
1005  state->filename, get_gz_error(state->ztarfile));
1006  exit(1);
1007  }
1008  }
1009  else
1010 #endif
1011  {
1012  errno = 0;
1013  if (fwrite(buf, r, 1, state->tarfile) != 1)
1014  {
1015  /* if write didn't set errno, assume problem is no disk space */
1016  if (errno == 0)
1017  errno = ENOSPC;
1018  pg_log_error("could not write to file \"%s\": %m",
1019  state->filename);
1020  exit(1);
1021  }
1022  }
1023 }
1024 
1025 /*
1026  * Receive a tar format file from the connection to the server, and write
1027  * the data from this file directly into a tar file. If compression is
1028  * enabled, the data will be compressed while written to the file.
1029  *
1030  * The file will be named base.tar[.gz] if it's for the main data directory
1031  * or <tablespaceoid>.tar[.gz] if it's for another tablespace.
1032  *
1033  * No attempt to inspect or validate the contents of the file is done.
1034  */
1035 static void
1036 ReceiveTarFile(PGconn *conn, PGresult *res, int rownum)
1037 {
1038  char zerobuf[TAR_BLOCK_SIZE * 2];
1040 
1041  memset(&state, 0, sizeof(state));
1042  state.tablespacenum = rownum;
1043  state.basetablespace = PQgetisnull(res, rownum, 0);
1044  state.in_tarhdr = true;
1045 
1046  /* recovery.conf is integrated into postgresql.conf in 12 and newer */
1048  state.is_recovery_guc_supported = true;
1049 
1050  if (state.basetablespace)
1051  {
1052  /*
1053  * Base tablespaces
1054  */
1055  if (strcmp(basedir, "-") == 0)
1056  {
1057 #ifdef WIN32
1058  _setmode(fileno(stdout), _O_BINARY);
1059 #endif
1060 
1061 #ifdef HAVE_LIBZ
1062  if (compresslevel != 0)
1063  {
1064  int fd = dup(fileno(stdout));
1065 
1066  if (fd < 0)
1067  {
1068  pg_log_error("could not duplicate stdout: %m");
1069  exit(1);
1070  }
1071 
1072  state.ztarfile = gzdopen(fd, "wb");
1073  if (state.ztarfile == NULL)
1074  {
1075  pg_log_error("could not open output file: %m");
1076  exit(1);
1077  }
1078 
1079  if (gzsetparams(state.ztarfile, compresslevel,
1080  Z_DEFAULT_STRATEGY) != Z_OK)
1081  {
1082  pg_log_error("could not set compression level %d: %s",
1083  compresslevel, get_gz_error(state.ztarfile));
1084  exit(1);
1085  }
1086  }
1087  else
1088 #endif
1089  state.tarfile = stdout;
1090  strcpy(state.filename, "-");
1091  }
1092  else
1093  {
1094 #ifdef HAVE_LIBZ
1095  if (compresslevel != 0)
1096  {
1097  snprintf(state.filename, sizeof(state.filename),
1098  "%s/base.tar.gz", basedir);
1099  state.ztarfile = gzopen(state.filename, "wb");
1100  if (gzsetparams(state.ztarfile, compresslevel,
1101  Z_DEFAULT_STRATEGY) != Z_OK)
1102  {
1103  pg_log_error("could not set compression level %d: %s",
1104  compresslevel, get_gz_error(state.ztarfile));
1105  exit(1);
1106  }
1107  }
1108  else
1109 #endif
1110  {
1111  snprintf(state.filename, sizeof(state.filename),
1112  "%s/base.tar", basedir);
1113  state.tarfile = fopen(state.filename, "wb");
1114  }
1115  }
1116  }
1117  else
1118  {
1119  /*
1120  * Specific tablespace
1121  */
1122 #ifdef HAVE_LIBZ
1123  if (compresslevel != 0)
1124  {
1125  snprintf(state.filename, sizeof(state.filename),
1126  "%s/%s.tar.gz",
1127  basedir, PQgetvalue(res, rownum, 0));
1128  state.ztarfile = gzopen(state.filename, "wb");
1129  if (gzsetparams(state.ztarfile, compresslevel,
1130  Z_DEFAULT_STRATEGY) != Z_OK)
1131  {
1132  pg_log_error("could not set compression level %d: %s",
1133  compresslevel, get_gz_error(state.ztarfile));
1134  exit(1);
1135  }
1136  }
1137  else
1138 #endif
1139  {
1140  snprintf(state.filename, sizeof(state.filename), "%s/%s.tar",
1141  basedir, PQgetvalue(res, rownum, 0));
1142  state.tarfile = fopen(state.filename, "wb");
1143  }
1144  }
1145 
1146 #ifdef HAVE_LIBZ
1147  if (compresslevel != 0)
1148  {
1149  if (!state.ztarfile)
1150  {
1151  /* Compression is in use */
1152  pg_log_error("could not create compressed file \"%s\": %s",
1153  state.filename, get_gz_error(state.ztarfile));
1154  exit(1);
1155  }
1156  }
1157  else
1158 #endif
1159  {
1160  /* Either no zlib support, or zlib support but compresslevel = 0 */
1161  if (!state.tarfile)
1162  {
1163  pg_log_error("could not create file \"%s\": %m", state.filename);
1164  exit(1);
1165  }
1166  }
1167 
1168  ReceiveCopyData(conn, ReceiveTarCopyChunk, &state);
1169 
1170  /*
1171  * End of copy data. If requested, and this is the base tablespace, write
1172  * configuration file into the tarfile. When done, close the file (but not
1173  * stdout).
1174  *
1175  * Also, write two completely empty blocks at the end of the tar file, as
1176  * required by some tar programs.
1177  */
1178 
1179  MemSet(zerobuf, 0, sizeof(zerobuf));
1180 
1181  if (state.basetablespace && writerecoveryconf)
1182  {
1183  char header[TAR_BLOCK_SIZE];
1184 
1185  /*
1186  * If postgresql.auto.conf has not been found in the streamed data,
1187  * add recovery configuration to postgresql.auto.conf if recovery
1188  * parameters are GUCs. If the instance connected to is older than
1189  * 12, create recovery.conf with this data otherwise.
1190  */
1192  {
1193  int padding;
1194 
1195  tarCreateHeader(header,
1196  state.is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf",
1197  NULL,
1198  recoveryconfcontents->len,
1199  pg_file_create_mode, 04000, 02000,
1200  time(NULL));
1201 
1202  padding = tarPaddingBytesRequired(recoveryconfcontents->len);
1203 
1204  writeTarData(&state, header, sizeof(header));
1205  writeTarData(&state, recoveryconfcontents->data,
1206  recoveryconfcontents->len);
1207  if (padding)
1208  writeTarData(&state, zerobuf, padding);
1209  }
1210 
1211  /*
1212  * standby.signal is supported only if recovery parameters are GUCs.
1213  */
1214  if (state.is_recovery_guc_supported)
1215  {
1216  tarCreateHeader(header, "standby.signal", NULL,
1217  0, /* zero-length file */
1218  pg_file_create_mode, 04000, 02000,
1219  time(NULL));
1220 
1221  writeTarData(&state, header, sizeof(header));
1222 
1223  /*
1224  * we don't need to pad out to a multiple of the tar block size
1225  * here, because the file is zero length, which is a multiple of
1226  * any block size.
1227  */
1228  }
1229  }
1230 
1231  /*
1232  * Normally, we emit the backup manifest as a separate file, but when
1233  * we're writing a tarfile to stdout, we don't have that option, so
1234  * include it in the one tarfile we've got.
1235  */
1236  if (strcmp(basedir, "-") == 0 && manifest)
1237  {
1238  char header[TAR_BLOCK_SIZE];
1240 
1241  initPQExpBuffer(&buf);
1242  ReceiveBackupManifestInMemory(conn, &buf);
1243  if (PQExpBufferDataBroken(buf))
1244  {
1245  pg_log_error("out of memory");
1246  exit(1);
1247  }
1248  tarCreateHeader(header, "backup_manifest", NULL, buf.len,
1249  pg_file_create_mode, 04000, 02000,
1250  time(NULL));
1251  writeTarData(&state, header, sizeof(header));
1252  writeTarData(&state, buf.data, buf.len);
1253  termPQExpBuffer(&buf);
1254  }
1255 
1256  /* 2 * TAR_BLOCK_SIZE bytes empty data at end of file */
1257  writeTarData(&state, zerobuf, sizeof(zerobuf));
1258 
1259 #ifdef HAVE_LIBZ
1260  if (state.ztarfile != NULL)
1261  {
1262  if (gzclose(state.ztarfile) != 0)
1263  {
1264  pg_log_error("could not close compressed file \"%s\": %s",
1265  state.filename, get_gz_error(state.ztarfile));
1266  exit(1);
1267  }
1268  }
1269  else
1270 #endif
1271  {
1272  if (strcmp(basedir, "-") != 0)
1273  {
1274  if (fclose(state.tarfile) != 0)
1275  {
1276  pg_log_error("could not close file \"%s\": %m",
1277  state.filename);
1278  exit(1);
1279  }
1280  }
1281  }
1282 
1283  progress_report(rownum, state.filename, true, false);
1284 
1285  /*
1286  * Do not sync the resulting tar file yet, all files are synced once at
1287  * the end.
1288  */
1289 }
1290 
1291 /*
1292  * Receive one chunk of tar-format data from the server.
1293  */
1294 static void
1295 ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
1296 {
1297  WriteTarState *state = callback_data;
1298 
1299  if (!writerecoveryconf || !state->basetablespace)
1300  {
1301  /*
1302  * When not writing config file, or when not working on the base
1303  * tablespace, we never have to look for an existing configuration
1304  * file in the stream.
1305  */
1306  writeTarData(state, copybuf, r);
1307  }
1308  else
1309  {
1310  /*
1311  * Look for a config file in the existing tar stream. If it's there,
1312  * we must skip it so we can later overwrite it with our own version
1313  * of the file.
1314  *
1315  * To do this, we have to process the individual files inside the TAR
1316  * stream. The stream consists of a header and zero or more chunks,
1317  * each with a length equal to TAR_BLOCK_SIZE. The stream from the
1318  * server is broken up into smaller pieces, so we have to track the
1319  * size of the files to find the next header structure.
1320  */
1321  int rr = r;
1322  int pos = 0;
1323 
1324  while (rr > 0)
1325  {
1326  if (state->in_tarhdr)
1327  {
1328  /*
1329  * We're currently reading a header structure inside the TAR
1330  * stream, i.e. the file metadata.
1331  */
1332  if (state->tarhdrsz < TAR_BLOCK_SIZE)
1333  {
1334  /*
1335  * Copy the header structure into tarhdr in case the
1336  * header is not aligned properly or it's not returned in
1337  * whole by the last PQgetCopyData call.
1338  */
1339  int hdrleft;
1340  int bytes2copy;
1341 
1342  hdrleft = TAR_BLOCK_SIZE - state->tarhdrsz;
1343  bytes2copy = (rr > hdrleft ? hdrleft : rr);
1344 
1345  memcpy(&state->tarhdr[state->tarhdrsz], copybuf + pos,
1346  bytes2copy);
1347 
1348  rr -= bytes2copy;
1349  pos += bytes2copy;
1350  state->tarhdrsz += bytes2copy;
1351  }
1352  else
1353  {
1354  /*
1355  * We have the complete header structure in tarhdr, look
1356  * at the file metadata: we may want append recovery info
1357  * into postgresql.auto.conf and skip standby.signal file
1358  * if recovery parameters are integrated as GUCs, and
1359  * recovery.conf otherwise. In both cases we must
1360  * calculate tar padding.
1361  */
1362  if (state->is_recovery_guc_supported)
1363  {
1364  state->skip_file =
1365  (strcmp(&state->tarhdr[0], "standby.signal") == 0);
1366  state->is_postgresql_auto_conf =
1367  (strcmp(&state->tarhdr[0], "postgresql.auto.conf") == 0);
1368  }
1369  else
1370  state->skip_file =
1371  (strcmp(&state->tarhdr[0], "recovery.conf") == 0);
1372 
1373  state->filesz = read_tar_number(&state->tarhdr[124], 12);
1374  state->file_padding_len =
1376 
1377  if (state->is_recovery_guc_supported &&
1378  state->is_postgresql_auto_conf &&
1380  {
1381  /* replace tar header */
1382  char header[TAR_BLOCK_SIZE];
1383 
1384  tarCreateHeader(header, "postgresql.auto.conf", NULL,
1385  state->filesz + recoveryconfcontents->len,
1386  pg_file_create_mode, 04000, 02000,
1387  time(NULL));
1388 
1389  writeTarData(state, header, sizeof(header));
1390  }
1391  else
1392  {
1393  /* copy stream with padding */
1394  state->filesz += state->file_padding_len;
1395 
1396  if (!state->skip_file)
1397  {
1398  /*
1399  * If we're not skipping the file, write the tar
1400  * header unmodified.
1401  */
1402  writeTarData(state, state->tarhdr, TAR_BLOCK_SIZE);
1403  }
1404  }
1405 
1406  /* Next part is the file, not the header */
1407  state->in_tarhdr = false;
1408  }
1409  }
1410  else
1411  {
1412  /*
1413  * We're processing a file's contents.
1414  */
1415  if (state->filesz > 0)
1416  {
1417  /*
1418  * We still have data to read (and possibly write).
1419  */
1420  int bytes2write;
1421 
1422  bytes2write = (state->filesz > rr ? rr : state->filesz);
1423 
1424  if (!state->skip_file)
1425  writeTarData(state, copybuf + pos, bytes2write);
1426 
1427  rr -= bytes2write;
1428  pos += bytes2write;
1429  state->filesz -= bytes2write;
1430  }
1431  else if (state->is_recovery_guc_supported &&
1432  state->is_postgresql_auto_conf &&
1434  {
1435  /* append recovery config to postgresql.auto.conf */
1436  int padding;
1437  int tailsize;
1438 
1439  tailsize = (TAR_BLOCK_SIZE - state->file_padding_len) + recoveryconfcontents->len;
1440  padding = tarPaddingBytesRequired(tailsize);
1441 
1442  writeTarData(state, recoveryconfcontents->data,
1443  recoveryconfcontents->len);
1444 
1445  if (padding)
1446  {
1447  char zerobuf[TAR_BLOCK_SIZE];
1448 
1449  MemSet(zerobuf, 0, sizeof(zerobuf));
1450  writeTarData(state, zerobuf, padding);
1451  }
1452 
1453  /* skip original file padding */
1454  state->is_postgresql_auto_conf = false;
1455  state->skip_file = true;
1456  state->filesz += state->file_padding_len;
1457 
1458  state->found_postgresql_auto_conf = true;
1459  }
1460  else
1461  {
1462  /*
1463  * No more data in the current file, the next piece of
1464  * data (if any) will be a new file header structure.
1465  */
1466  state->in_tarhdr = true;
1467  state->skip_file = false;
1468  state->is_postgresql_auto_conf = false;
1469  state->tarhdrsz = 0;
1470  state->filesz = 0;
1471  }
1472  }
1473  }
1474  }
1475  totaldone += r;
1476  progress_report(state->tablespacenum, state->filename, false, false);
1477 }
1478 
1479 
1480 /*
1481  * Retrieve tablespace path, either relocated or original depending on whether
1482  * -T was passed or not.
1483  */
1484 static const char *
1485 get_tablespace_mapping(const char *dir)
1486 {
1487  TablespaceListCell *cell;
1488  char canon_dir[MAXPGPATH];
1489 
1490  /* Canonicalize path for comparison consistency */
1491  strlcpy(canon_dir, dir, sizeof(canon_dir));
1492  canonicalize_path(canon_dir);
1493 
1494  for (cell = tablespace_dirs.head; cell; cell = cell->next)
1495  if (strcmp(canon_dir, cell->old_dir) == 0)
1496  return cell->new_dir;
1497 
1498  return dir;
1499 }
1500 
1501 
1502 /*
1503  * Receive a tar format stream from the connection to the server, and unpack
1504  * the contents of it into a directory. Only files, directories and
1505  * symlinks are supported, no other kinds of special files.
1506  *
1507  * If the data is for the main data directory, it will be restored in the
1508  * specified directory. If it's for another tablespace, it will be restored
1509  * in the original or mapped directory.
1510  */
1511 static void
1513 {
1515  bool basetablespace;
1516 
1517  memset(&state, 0, sizeof(state));
1518  state.tablespacenum = rownum;
1519 
1520  basetablespace = PQgetisnull(res, rownum, 0);
1521  if (basetablespace)
1522  strlcpy(state.current_path, basedir, sizeof(state.current_path));
1523  else
1524  strlcpy(state.current_path,
1525  get_tablespace_mapping(PQgetvalue(res, rownum, 1)),
1526  sizeof(state.current_path));
1527 
1529 
1530 
1531  if (state.file)
1532  fclose(state.file);
1533 
1534  progress_report(rownum, state.filename, true, false);
1535 
1536  if (state.file != NULL)
1537  {
1538  pg_log_error("COPY stream ended before last file was finished");
1539  exit(1);
1540  }
1541 
1542  if (basetablespace && writerecoveryconf)
1543  WriteRecoveryConfig(conn, basedir, recoveryconfcontents);
1544 
1545  /*
1546  * No data is synced here, everything is done for all tablespaces at the
1547  * end.
1548  */
1549 }
1550 
1551 static void
1552 ReceiveTarAndUnpackCopyChunk(size_t r, char *copybuf, void *callback_data)
1553 {
1554  UnpackTarState *state = callback_data;
1555 
1556  if (state->file == NULL)
1557  {
1558 #ifndef WIN32
1559  int filemode;
1560 #endif
1561 
1562  /*
1563  * No current file, so this must be the header for a new file
1564  */
1565  if (r != TAR_BLOCK_SIZE)
1566  {
1567  pg_log_error("invalid tar block header size: %zu", r);
1568  exit(1);
1569  }
1571 
1572  state->current_len_left = read_tar_number(&copybuf[124], 12);
1573 
1574 #ifndef WIN32
1575  /* Set permissions on the file */
1576  filemode = read_tar_number(&copybuf[100], 8);
1577 #endif
1578 
1579  /*
1580  * All files are padded up to a multiple of TAR_BLOCK_SIZE
1581  */
1582  state->current_padding =
1584 
1585  /*
1586  * First part of header is zero terminated filename
1587  */
1588  snprintf(state->filename, sizeof(state->filename),
1589  "%s/%s", state->current_path, copybuf);
1590  if (state->filename[strlen(state->filename) - 1] == '/')
1591  {
1592  /*
1593  * Ends in a slash means directory or symlink to directory
1594  */
1595  if (copybuf[156] == '5')
1596  {
1597  /*
1598  * Directory. Remove trailing slash first.
1599  */
1600  state->filename[strlen(state->filename) - 1] = '\0';
1601  if (mkdir(state->filename, pg_dir_create_mode) != 0)
1602  {
1603  /*
1604  * When streaming WAL, pg_wal (or pg_xlog for pre-9.6
1605  * clusters) will have been created by the wal receiver
1606  * process. Also, when the WAL directory location was
1607  * specified, pg_wal (or pg_xlog) has already been created
1608  * as a symbolic link before starting the actual backup.
1609  * So just ignore creation failures on related
1610  * directories.
1611  */
1612  if (!((pg_str_endswith(state->filename, "/pg_wal") ||
1613  pg_str_endswith(state->filename, "/pg_xlog") ||
1614  pg_str_endswith(state->filename, "/archive_status")) &&
1615  errno == EEXIST))
1616  {
1617  pg_log_error("could not create directory \"%s\": %m",
1618  state->filename);
1619  exit(1);
1620  }
1621  }
1622 #ifndef WIN32
1623  if (chmod(state->filename, (mode_t) filemode))
1624  {
1625  pg_log_error("could not set permissions on directory \"%s\": %m",
1626  state->filename);
1627  exit(1);
1628  }
1629 #endif
1630  }
1631  else if (copybuf[156] == '2')
1632  {
1633  /*
1634  * Symbolic link
1635  *
1636  * It's most likely a link in pg_tblspc directory, to the
1637  * location of a tablespace. Apply any tablespace mapping
1638  * given on the command line (--tablespace-mapping). (We
1639  * blindly apply the mapping without checking that the link
1640  * really is inside pg_tblspc. We don't expect there to be
1641  * other symlinks in a data directory, but if there are, you
1642  * can call it an undocumented feature that you can map them
1643  * too.)
1644  */
1645  state->filename[strlen(state->filename) - 1] = '\0'; /* Remove trailing slash */
1646 
1647  state->mapped_tblspc_path =
1648  get_tablespace_mapping(&copybuf[157]);
1649  if (symlink(state->mapped_tblspc_path, state->filename) != 0)
1650  {
1651  pg_log_error("could not create symbolic link from \"%s\" to \"%s\": %m",
1652  state->filename, state->mapped_tblspc_path);
1653  exit(1);
1654  }
1655  }
1656  else
1657  {
1658  pg_log_error("unrecognized link indicator \"%c\"",
1659  copybuf[156]);
1660  exit(1);
1661  }
1662  return; /* directory or link handled */
1663  }
1664 
1665  /*
1666  * regular file
1667  */
1668  state->file = fopen(state->filename, "wb");
1669  if (!state->file)
1670  {
1671  pg_log_error("could not create file \"%s\": %m", state->filename);
1672  exit(1);
1673  }
1674 
1675 #ifndef WIN32
1676  if (chmod(state->filename, (mode_t) filemode))
1677  {
1678  pg_log_error("could not set permissions on file \"%s\": %m",
1679  state->filename);
1680  exit(1);
1681  }
1682 #endif
1683 
1684  if (state->current_len_left == 0)
1685  {
1686  /*
1687  * Done with this file, next one will be a new tar header
1688  */
1689  fclose(state->file);
1690  state->file = NULL;
1691  return;
1692  }
1693  } /* new file */
1694  else
1695  {
1696  /*
1697  * Continuing blocks in existing file
1698  */
1699  if (state->current_len_left == 0 && r == state->current_padding)
1700  {
1701  /*
1702  * Received the padding block for this file, ignore it and close
1703  * the file, then move on to the next tar header.
1704  */
1705  fclose(state->file);
1706  state->file = NULL;
1707  totaldone += r;
1708  return;
1709  }
1710 
1711  errno = 0;
1712  if (fwrite(copybuf, r, 1, state->file) != 1)
1713  {
1714  /* if write didn't set errno, assume problem is no disk space */
1715  if (errno == 0)
1716  errno = ENOSPC;
1717  pg_log_error("could not write to file \"%s\": %m", state->filename);
1718  exit(1);
1719  }
1720  totaldone += r;
1721  progress_report(state->tablespacenum, state->filename, false, false);
1722 
1723  state->current_len_left -= r;
1724  if (state->current_len_left == 0 && state->current_padding == 0)
1725  {
1726  /*
1727  * Received the last block, and there is no padding to be
1728  * expected. Close the file and move on to the next tar header.
1729  */
1730  fclose(state->file);
1731  state->file = NULL;
1732  return;
1733  }
1734  } /* continuing data in existing file */
1735 }
1736 
1737 /*
1738  * Receive the backup manifest file and write it out to a file.
1739  */
1740 static void
1742 {
1744 
1745  snprintf(state.filename, sizeof(state.filename),
1746  "%s/backup_manifest.tmp", basedir);
1747  state.file = fopen(state.filename, "wb");
1748  if (state.file == NULL)
1749  {
1750  pg_log_error("could not create file \"%s\": %m", state.filename);
1751  exit(1);
1752  }
1753 
1755 
1756  fclose(state.file);
1757 }
1758 
1759 /*
1760  * Receive one chunk of the backup manifest file and write it out to a file.
1761  */
1762 static void
1763 ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
1764 {
1765  WriteManifestState *state = callback_data;
1766 
1767  errno = 0;
1768  if (fwrite(copybuf, r, 1, state->file) != 1)
1769  {
1770  /* if write didn't set errno, assume problem is no disk space */
1771  if (errno == 0)
1772  errno = ENOSPC;
1773  pg_log_error("could not write to file \"%s\": %m", state->filename);
1774  exit(1);
1775  }
1776 }
1777 
1778 /*
1779  * Receive the backup manifest file and write it out to a file.
1780  */
1781 static void
1783 {
1785 }
1786 
1787 /*
1788  * Receive one chunk of the backup manifest file and write it out to a file.
1789  */
1790 static void
1792  void *callback_data)
1793 {
1794  PQExpBuffer buf = callback_data;
1795 
1796  appendPQExpBuffer(buf, copybuf, r);
1797 }
1798 
1799 static void
1801 {
1802  PGresult *res;
1803  char *sysidentifier;
1804  TimeLineID latesttli;
1805  TimeLineID starttli;
1806  char *basebkp;
1807  int i;
1808  char xlogstart[64];
1809  char xlogend[64];
1810  int minServerMajor,
1811  maxServerMajor;
1812  int serverVersion,
1813  serverMajor;
1814  int writing_to_stdout;
1815  bool use_new_option_syntax = false;
1817 
1818  Assert(conn != NULL);
1819  initPQExpBuffer(&buf);
1820 
1821  /*
1822  * Check server version. BASE_BACKUP command was introduced in 9.1, so we
1823  * can't work with servers older than 9.1.
1824  */
1825  minServerMajor = 901;
1826  maxServerMajor = PG_VERSION_NUM / 100;
1827  serverVersion = PQserverVersion(conn);
1828  serverMajor = serverVersion / 100;
1829  if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1830  {
1831  const char *serverver = PQparameterStatus(conn, "server_version");
1832 
1833  pg_log_error("incompatible server version %s",
1834  serverver ? serverver : "'unknown'");
1835  exit(1);
1836  }
1837  if (serverMajor >= 1500)
1838  use_new_option_syntax = true;
1839 
1840  /*
1841  * If WAL streaming was requested, also check that the server is new
1842  * enough for that.
1843  */
1845  {
1846  /*
1847  * Error message already written in CheckServerVersionForStreaming(),
1848  * but add a hint about using -X none.
1849  */
1850  pg_log_info("HINT: use -X none or -X fetch to disable log streaming");
1851  exit(1);
1852  }
1853 
1854  /*
1855  * Build contents of configuration file if requested
1856  */
1857  if (writerecoveryconf)
1858  recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot);
1859 
1860  /*
1861  * Run IDENTIFY_SYSTEM so we can get the timeline
1862  */
1863  if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
1864  exit(1);
1865 
1866  /*
1867  * Start the actual backup
1868  */
1869  AppendStringCommandOption(&buf, use_new_option_syntax, "LABEL", label);
1870  if (estimatesize)
1871  AppendPlainCommandOption(&buf, use_new_option_syntax, "PROGRESS");
1872  if (includewal == FETCH_WAL)
1873  AppendPlainCommandOption(&buf, use_new_option_syntax, "WAL");
1874  if (fastcheckpoint)
1875  {
1876  if (use_new_option_syntax)
1877  AppendStringCommandOption(&buf, use_new_option_syntax,
1878  "CHECKPOINT", "fast");
1879  else
1880  AppendPlainCommandOption(&buf, use_new_option_syntax, "FAST");
1881  }
1882  if (includewal != NO_WAL)
1883  {
1884  if (use_new_option_syntax)
1885  AppendIntegerCommandOption(&buf, use_new_option_syntax, "WAIT", 0);
1886  else
1887  AppendPlainCommandOption(&buf, use_new_option_syntax, "NOWAIT");
1888  }
1889  if (maxrate > 0)
1890  AppendIntegerCommandOption(&buf, use_new_option_syntax, "MAX_RATE",
1891  maxrate);
1892  if (format == 't')
1893  AppendPlainCommandOption(&buf, use_new_option_syntax, "TABLESPACE_MAP");
1894  if (!verify_checksums)
1895  {
1896  if (use_new_option_syntax)
1897  AppendIntegerCommandOption(&buf, use_new_option_syntax,
1898  "VERIFY_CHECKSUMS", 0);
1899  else
1900  AppendPlainCommandOption(&buf, use_new_option_syntax,
1901  "NOVERIFY_CHECKSUMS");
1902  }
1903 
1904  if (manifest)
1905  {
1906  AppendStringCommandOption(&buf, use_new_option_syntax, "MANIFEST",
1907  manifest_force_encode ? "force-encode" : "yes");
1908  if (manifest_checksums != NULL)
1909  AppendStringCommandOption(&buf, use_new_option_syntax,
1910  "MANIFEST_CHECKSUMS", manifest_checksums);
1911  }
1912 
1913  if (verbose)
1914  pg_log_info("initiating base backup, waiting for checkpoint to complete");
1915 
1916  if (showprogress && !verbose)
1917  {
1918  fprintf(stderr, "waiting for checkpoint");
1919  if (isatty(fileno(stderr)))
1920  fprintf(stderr, "\r");
1921  else
1922  fprintf(stderr, "\n");
1923  }
1924 
1925  if (use_new_option_syntax && buf.len > 0)
1926  basebkp = psprintf("BASE_BACKUP (%s)", buf.data);
1927  else
1928  basebkp = psprintf("BASE_BACKUP %s", buf.data);
1929 
1930  if (PQsendQuery(conn, basebkp) == 0)
1931  {
1932  pg_log_error("could not send replication command \"%s\": %s",
1933  "BASE_BACKUP", PQerrorMessage(conn));
1934  exit(1);
1935  }
1936 
1937  /*
1938  * Get the starting WAL location
1939  */
1940  res = PQgetResult(conn);
1941  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1942  {
1943  pg_log_error("could not initiate base backup: %s",
1944  PQerrorMessage(conn));
1945  exit(1);
1946  }
1947  if (PQntuples(res) != 1)
1948  {
1949  pg_log_error("server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
1950  PQntuples(res), PQnfields(res), 1, 2);
1951  exit(1);
1952  }
1953 
1954  strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
1955 
1956  if (verbose)
1957  pg_log_info("checkpoint completed");
1958 
1959  /*
1960  * 9.3 and later sends the TLI of the starting point. With older servers,
1961  * assume it's the same as the latest timeline reported by
1962  * IDENTIFY_SYSTEM.
1963  */
1964  if (PQnfields(res) >= 2)
1965  starttli = atoi(PQgetvalue(res, 0, 1));
1966  else
1967  starttli = latesttli;
1968  PQclear(res);
1969  MemSet(xlogend, 0, sizeof(xlogend));
1970 
1971  if (verbose && includewal != NO_WAL)
1972  pg_log_info("write-ahead log start point: %s on timeline %u",
1973  xlogstart, starttli);
1974 
1975  /*
1976  * Get the header
1977  */
1978  res = PQgetResult(conn);
1979  if (PQresultStatus(res) != PGRES_TUPLES_OK)
1980  {
1981  pg_log_error("could not get backup header: %s",
1982  PQerrorMessage(conn));
1983  exit(1);
1984  }
1985  if (PQntuples(res) < 1)
1986  {
1987  pg_log_error("no data returned from server");
1988  exit(1);
1989  }
1990 
1991  /*
1992  * Sum up the total size, for progress reporting
1993  */
1994  totalsize_kb = totaldone = 0;
1995  tablespacecount = PQntuples(res);
1996  for (i = 0; i < PQntuples(res); i++)
1997  {
1998  totalsize_kb += atol(PQgetvalue(res, i, 2));
1999 
2000  /*
2001  * Verify tablespace directories are empty. Don't bother with the
2002  * first once since it can be relocated, and it will be checked before
2003  * we do anything anyway.
2004  */
2005  if (format == 'p' && !PQgetisnull(res, i, 1))
2006  {
2007  char *path = unconstify(char *, get_tablespace_mapping(PQgetvalue(res, i, 1)));
2008 
2010  }
2011  }
2012 
2013  /*
2014  * When writing to stdout, require a single tablespace
2015  */
2016  writing_to_stdout = format == 't' && strcmp(basedir, "-") == 0;
2017  if (writing_to_stdout && PQntuples(res) > 1)
2018  {
2019  pg_log_error("can only write single tablespace to stdout, database has %d",
2020  PQntuples(res));
2021  exit(1);
2022  }
2023 
2024  /*
2025  * If we're streaming WAL, start the streaming session before we start
2026  * receiving the actual data chunks.
2027  */
2028  if (includewal == STREAM_WAL)
2029  {
2030  if (verbose)
2031  pg_log_info("starting background WAL receiver");
2032  StartLogStreamer(xlogstart, starttli, sysidentifier);
2033  }
2034 
2035  /*
2036  * Start receiving chunks
2037  */
2038  for (i = 0; i < PQntuples(res); i++)
2039  {
2040  if (format == 't')
2041  ReceiveTarFile(conn, res, i);
2042  else
2043  ReceiveAndUnpackTarFile(conn, res, i);
2044  } /* Loop over all tablespaces */
2045 
2046  /*
2047  * Now receive backup manifest, if appropriate.
2048  *
2049  * If we're writing a tarfile to stdout, ReceiveTarFile will have already
2050  * processed the backup manifest and included it in the output tarfile.
2051  * Such a configuration doesn't allow for writing multiple files.
2052  *
2053  * If we're talking to an older server, it won't send a backup manifest,
2054  * so don't try to receive one.
2055  */
2056  if (!writing_to_stdout && manifest)
2058 
2059  if (showprogress)
2060  progress_report(PQntuples(res), NULL, true, true);
2061 
2062  PQclear(res);
2063 
2064  /*
2065  * Get the stop position
2066  */
2067  res = PQgetResult(conn);
2068  if (PQresultStatus(res) != PGRES_TUPLES_OK)
2069  {
2070  pg_log_error("could not get write-ahead log end position from server: %s",
2071  PQerrorMessage(conn));
2072  exit(1);
2073  }
2074  if (PQntuples(res) != 1)
2075  {
2076  pg_log_error("no write-ahead log end position returned from server");
2077  exit(1);
2078  }
2079  strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend));
2080  if (verbose && includewal != NO_WAL)
2081  pg_log_info("write-ahead log end point: %s", xlogend);
2082  PQclear(res);
2083 
2084  res = PQgetResult(conn);
2085  if (PQresultStatus(res) != PGRES_COMMAND_OK)
2086  {
2087  const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
2088 
2089  if (sqlstate &&
2090  strcmp(sqlstate, ERRCODE_DATA_CORRUPTED) == 0)
2091  {
2092  pg_log_error("checksum error occurred");
2093  checksum_failure = true;
2094  }
2095  else
2096  {
2097  pg_log_error("final receive failed: %s",
2098  PQerrorMessage(conn));
2099  }
2100  exit(1);
2101  }
2102 
2103  if (bgchild > 0)
2104  {
2105 #ifndef WIN32
2106  int status;
2107  pid_t r;
2108 #else
2109  DWORD status;
2110 
2111  /*
2112  * get a pointer sized version of bgchild to avoid warnings about
2113  * casting to a different size on WIN64.
2114  */
2115  intptr_t bgchild_handle = bgchild;
2116  uint32 hi,
2117  lo;
2118 #endif
2119 
2120  if (verbose)
2121  pg_log_info("waiting for background process to finish streaming ...");
2122 
2123 #ifndef WIN32
2124  if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2125  {
2126  pg_log_info("could not send command to background pipe: %m");
2127  exit(1);
2128  }
2129 
2130  /* Just wait for the background process to exit */
2131  r = waitpid(bgchild, &status, 0);
2132  if (r == (pid_t) -1)
2133  {
2134  pg_log_error("could not wait for child process: %m");
2135  exit(1);
2136  }
2137  if (r != bgchild)
2138  {
2139  pg_log_error("child %d died, expected %d", (int) r, (int) bgchild);
2140  exit(1);
2141  }
2142  if (status != 0)
2143  {
2144  pg_log_error("%s", wait_result_to_str(status));
2145  exit(1);
2146  }
2147  /* Exited normally, we're happy! */
2148 #else /* WIN32 */
2149 
2150  /*
2151  * On Windows, since we are in the same process, we can just store the
2152  * value directly in the variable, and then set the flag that says
2153  * it's there.
2154  */
2155  if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
2156  {
2157  pg_log_error("could not parse write-ahead log location \"%s\"",
2158  xlogend);
2159  exit(1);
2160  }
2161  xlogendptr = ((uint64) hi) << 32 | lo;
2162  InterlockedIncrement(&has_xlogendptr);
2163 
2164  /* First wait for the thread to exit */
2165  if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2166  WAIT_OBJECT_0)
2167  {
2168  _dosmaperr(GetLastError());
2169  pg_log_error("could not wait for child thread: %m");
2170  exit(1);
2171  }
2172  if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2173  {
2174  _dosmaperr(GetLastError());
2175  pg_log_error("could not get child thread exit status: %m");
2176  exit(1);
2177  }
2178  if (status != 0)
2179  {
2180  pg_log_error("child thread exited with error %u",
2181  (unsigned int) status);
2182  exit(1);
2183  }
2184  /* Exited normally, we're happy */
2185 #endif
2186  }
2187 
2188  /* Free the configuration file contents */
2189  destroyPQExpBuffer(recoveryconfcontents);
2190 
2191  /*
2192  * End of copy data. Final result is already checked inside the loop.
2193  */
2194  PQclear(res);
2195  PQfinish(conn);
2196  conn = NULL;
2197 
2198  /*
2199  * Make data persistent on disk once backup is completed. For tar format
2200  * sync the parent directory and all its contents as each tar file was not
2201  * synced after being completed. In plain format, all the data of the
2202  * base directory is synced, taking into account all the tablespaces.
2203  * Errors are not considered fatal.
2204  */
2205  if (do_sync)
2206  {
2207  if (verbose)
2208  pg_log_info("syncing data to disk ...");
2209  if (format == 't')
2210  {
2211  if (strcmp(basedir, "-") != 0)
2212  (void) fsync_dir_recurse(basedir);
2213  }
2214  else
2215  {
2216  (void) fsync_pgdata(basedir, serverVersion);
2217  }
2218  }
2219 
2220  /*
2221  * After synchronizing data to disk, perform a durable rename of
2222  * backup_manifest.tmp to backup_manifest, if we wrote such a file. This
2223  * way, a failure or system crash before we reach this point will leave us
2224  * without a backup_manifest file, decreasing the chances that a directory
2225  * we leave behind will be mistaken for a valid backup.
2226  */
2227  if (!writing_to_stdout && manifest)
2228  {
2229  char tmp_filename[MAXPGPATH];
2230  char filename[MAXPGPATH];
2231 
2232  if (verbose)
2233  pg_log_info("renaming backup_manifest.tmp to backup_manifest");
2234 
2235  snprintf(tmp_filename, MAXPGPATH, "%s/backup_manifest.tmp", basedir);
2236  snprintf(filename, MAXPGPATH, "%s/backup_manifest", basedir);
2237 
2238  /* durable_rename emits its own log message in case of failure */
2239  if (durable_rename(tmp_filename, filename) != 0)
2240  exit(1);
2241  }
2242 
2243  if (verbose)
2244  pg_log_info("base backup completed");
2245 }
2246 
2247 
2248 int
2249 main(int argc, char **argv)
2250 {
2251  static struct option long_options[] = {
2252  {"help", no_argument, NULL, '?'},
2253  {"version", no_argument, NULL, 'V'},
2254  {"pgdata", required_argument, NULL, 'D'},
2255  {"format", required_argument, NULL, 'F'},
2256  {"checkpoint", required_argument, NULL, 'c'},
2257  {"create-slot", no_argument, NULL, 'C'},
2258  {"max-rate", required_argument, NULL, 'r'},
2259  {"write-recovery-conf", no_argument, NULL, 'R'},
2260  {"slot", required_argument, NULL, 'S'},
2261  {"tablespace-mapping", required_argument, NULL, 'T'},
2262  {"wal-method", required_argument, NULL, 'X'},
2263  {"gzip", no_argument, NULL, 'z'},
2264  {"compress", required_argument, NULL, 'Z'},
2265  {"label", required_argument, NULL, 'l'},
2266  {"no-clean", no_argument, NULL, 'n'},
2267  {"no-sync", no_argument, NULL, 'N'},
2268  {"dbname", required_argument, NULL, 'd'},
2269  {"host", required_argument, NULL, 'h'},
2270  {"port", required_argument, NULL, 'p'},
2271  {"username", required_argument, NULL, 'U'},
2272  {"no-password", no_argument, NULL, 'w'},
2273  {"password", no_argument, NULL, 'W'},
2274  {"status-interval", required_argument, NULL, 's'},
2275  {"verbose", no_argument, NULL, 'v'},
2276  {"progress", no_argument, NULL, 'P'},
2277  {"waldir", required_argument, NULL, 1},
2278  {"no-slot", no_argument, NULL, 2},
2279  {"no-verify-checksums", no_argument, NULL, 3},
2280  {"no-estimate-size", no_argument, NULL, 4},
2281  {"no-manifest", no_argument, NULL, 5},
2282  {"manifest-force-encode", no_argument, NULL, 6},
2283  {"manifest-checksums", required_argument, NULL, 7},
2284  {NULL, 0, NULL, 0}
2285  };
2286  int c;
2287 
2288  int option_index;
2289 
2290  pg_logging_init(argv[0]);
2291  progname = get_progname(argv[0]);
2292  set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
2293 
2294  if (argc > 1)
2295  {
2296  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2297  {
2298  usage();
2299  exit(0);
2300  }
2301  else if (strcmp(argv[1], "-V") == 0
2302  || strcmp(argv[1], "--version") == 0)
2303  {
2304  puts("pg_basebackup (PostgreSQL) " PG_VERSION);
2305  exit(0);
2306  }
2307  }
2308 
2310 
2311  while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP",
2312  long_options, &option_index)) != -1)
2313  {
2314  switch (c)
2315  {
2316  case 'C':
2317  create_slot = true;
2318  break;
2319  case 'D':
2321  break;
2322  case 'F':
2323  if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
2324  format = 'p';
2325  else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
2326  format = 't';
2327  else
2328  {
2329  pg_log_error("invalid output format \"%s\", must be \"plain\" or \"tar\"",
2330  optarg);
2331  exit(1);
2332  }
2333  break;
2334  case 'r':
2336  break;
2337  case 'R':
2338  writerecoveryconf = true;
2339  break;
2340  case 'S':
2341 
2342  /*
2343  * When specifying replication slot name, use a permanent
2344  * slot.
2345  */
2347  temp_replication_slot = false;
2348  break;
2349  case 2:
2350  no_slot = true;
2351  break;
2352  case 'T':
2354  break;
2355  case 'X':
2356  if (strcmp(optarg, "n") == 0 ||
2357  strcmp(optarg, "none") == 0)
2358  {
2359  includewal = NO_WAL;
2360  }
2361  else if (strcmp(optarg, "f") == 0 ||
2362  strcmp(optarg, "fetch") == 0)
2363  {
2365  }
2366  else if (strcmp(optarg, "s") == 0 ||
2367  strcmp(optarg, "stream") == 0)
2368  {
2370  }
2371  else
2372  {
2373  pg_log_error("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2374  optarg);
2375  exit(1);
2376  }
2377  break;
2378  case 1:
2380  break;
2381  case 'l':
2382  label = pg_strdup(optarg);
2383  break;
2384  case 'n':
2385  noclean = true;
2386  break;
2387  case 'N':
2388  do_sync = false;
2389  break;
2390  case 'z':
2391 #ifdef HAVE_LIBZ
2393 #else
2394  compresslevel = 1; /* will be rejected below */
2395 #endif
2396  break;
2397  case 'Z':
2398  if (!option_parse_int(optarg, "-Z/--compress", 0, 9,
2399  &compresslevel))
2400  exit(1);
2401  break;
2402  case 'c':
2403  if (pg_strcasecmp(optarg, "fast") == 0)
2404  fastcheckpoint = true;
2405  else if (pg_strcasecmp(optarg, "spread") == 0)
2406  fastcheckpoint = false;
2407  else
2408  {
2409  pg_log_error("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2410  optarg);
2411  exit(1);
2412  }
2413  break;
2414  case 'd':
2416  break;
2417  case 'h':
2418  dbhost = pg_strdup(optarg);
2419  break;
2420  case 'p':
2421  dbport = pg_strdup(optarg);
2422  break;
2423  case 'U':
2424  dbuser = pg_strdup(optarg);
2425  break;
2426  case 'w':
2427  dbgetpassword = -1;
2428  break;
2429  case 'W':
2430  dbgetpassword = 1;
2431  break;
2432  case 's':
2433  if (!option_parse_int(optarg, "-s/--status-interval", 0,
2434  INT_MAX / 1000,
2436  exit(1);
2437  standby_message_timeout *= 1000;
2438  break;
2439  case 'v':
2440  verbose++;
2441  break;
2442  case 'P':
2443  showprogress = true;
2444  break;
2445  case 3:
2446  verify_checksums = false;
2447  break;
2448  case 4:
2449  estimatesize = false;
2450  break;
2451  case 5:
2452  manifest = false;
2453  break;
2454  case 6:
2455  manifest_force_encode = true;
2456  break;
2457  case 7:
2459  break;
2460  default:
2461 
2462  /*
2463  * getopt_long already emitted a complaint
2464  */
2465  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2466  progname);
2467  exit(1);
2468  }
2469  }
2470 
2471  /*
2472  * Any non-option arguments?
2473  */
2474  if (optind < argc)
2475  {
2476  pg_log_error("too many command-line arguments (first is \"%s\")",
2477  argv[optind]);
2478  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2479  progname);
2480  exit(1);
2481  }
2482 
2483  /*
2484  * Required arguments
2485  */
2486  if (basedir == NULL)
2487  {
2488  pg_log_error("no target directory specified");
2489  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2490  progname);
2491  exit(1);
2492  }
2493 
2494  /*
2495  * Mutually exclusive arguments
2496  */
2497  if (format == 'p' && compresslevel != 0)
2498  {
2499  pg_log_error("only tar mode backups can be compressed");
2500  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2501  progname);
2502  exit(1);
2503  }
2504 
2505  if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
2506  {
2507  pg_log_error("cannot stream write-ahead logs in tar mode to stdout");
2508  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2509  progname);
2510  exit(1);
2511  }
2512 
2514  {
2515  pg_log_error("replication slots can only be used with WAL streaming");
2516  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2517  progname);
2518  exit(1);
2519  }
2520 
2521  if (no_slot)
2522  {
2523  if (replication_slot)
2524  {
2525  pg_log_error("--no-slot cannot be used with slot name");
2526  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2527  progname);
2528  exit(1);
2529  }
2530  temp_replication_slot = false;
2531  }
2532 
2533  if (create_slot)
2534  {
2535  if (!replication_slot)
2536  {
2537  pg_log_error("%s needs a slot to be specified using --slot",
2538  "--create-slot");
2539  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2540  progname);
2541  exit(1);
2542  }
2543 
2544  if (no_slot)
2545  {
2546  pg_log_error("%s and %s are incompatible options",
2547  "--create-slot", "--no-slot");
2548  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2549  progname);
2550  exit(1);
2551  }
2552  }
2553 
2554  if (xlog_dir)
2555  {
2556  if (format != 'p')
2557  {
2558  pg_log_error("WAL directory location can only be specified in plain mode");
2559  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2560  progname);
2561  exit(1);
2562  }
2563 
2564  /* clean up xlog directory name, check it's absolute */
2566  if (!is_absolute_path(xlog_dir))
2567  {
2568  pg_log_error("WAL directory location must be an absolute path");
2569  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2570  progname);
2571  exit(1);
2572  }
2573  }
2574 
2575 #ifndef HAVE_LIBZ
2576  if (compresslevel != 0)
2577  {
2578  pg_log_error("this build does not support compression");
2579  exit(1);
2580  }
2581 #endif
2582 
2583  if (showprogress && !estimatesize)
2584  {
2585  pg_log_error("%s and %s are incompatible options",
2586  "--progress", "--no-estimate-size");
2587  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2588  progname);
2589  exit(1);
2590  }
2591 
2592  if (!manifest && manifest_checksums != NULL)
2593  {
2594  pg_log_error("%s and %s are incompatible options",
2595  "--no-manifest", "--manifest-checksums");
2596  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2597  progname);
2598  exit(1);
2599  }
2600 
2602  {
2603  pg_log_error("%s and %s are incompatible options",
2604  "--no-manifest", "--manifest-force-encode");
2605  fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
2606  progname);
2607  exit(1);
2608  }
2609 
2610  /* connection in replication mode to server */
2611  conn = GetConnection();
2612  if (!conn)
2613  {
2614  /* Error message already written in GetConnection() */
2615  exit(1);
2616  }
2617  atexit(disconnect_atexit);
2618 
2619  /*
2620  * Set umask so that directories/files are created with the same
2621  * permissions as directories/files in the source data directory.
2622  *
2623  * pg_mode_mask is set to owner-only by default and then updated in
2624  * GetConnection() where we get the mode from the server-side with
2625  * RetrieveDataDirCreatePerm() and then call SetDataDirectoryCreatePerm().
2626  */
2627  umask(pg_mode_mask);
2628 
2629  /* Backup manifests are supported in 13 and newer versions */
2631  manifest = false;
2632 
2633  /*
2634  * Verify that the target directory exists, or create it. For plaintext
2635  * backups, always require the directory. For tar backups, require it
2636  * unless we are writing to stdout.
2637  */
2638  if (format == 'p' || strcmp(basedir, "-") != 0)
2640 
2641  /* determine remote server's xlog segment size */
2642  if (!RetrieveWalSegSize(conn))
2643  exit(1);
2644 
2645  /* Create pg_wal symlink, if required */
2646  if (xlog_dir)
2647  {
2648  char *linkloc;
2649 
2651 
2652  /*
2653  * Form name of the place where the symlink must go. pg_xlog has been
2654  * renamed to pg_wal in post-10 clusters.
2655  */
2656  linkloc = psprintf("%s/%s", basedir,
2658  "pg_xlog" : "pg_wal");
2659 
2660 #ifdef HAVE_SYMLINK
2661  if (symlink(xlog_dir, linkloc) != 0)
2662  {
2663  pg_log_error("could not create symbolic link \"%s\": %m", linkloc);
2664  exit(1);
2665  }
2666 #else
2667  pg_log_error("symlinks are not supported on this platform");
2668  exit(1);
2669 #endif
2670  free(linkloc);
2671  }
2672 
2673  BaseBackup();
2674 
2675  success = true;
2676  return 0;
2677 }
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:6744
#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:6709
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
void AppendStringCommandOption(PQExpBuffer buf, bool use_new_option_syntax, char *option_name, char *option_value)
Definition: streamutil.c:665
static bool create_slot
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
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:464
static void ReceiveBackupManifest(PGconn *conn)
#define printf(...)
Definition: port.h:223
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:6734
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define PG_DIAG_SQLSTATE
Definition: postgres_ext.h:57
#define fprintf
Definition: port.h:221
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:208
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:127
#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:235
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
#define select(n, r, w, e, timeout)
Definition: win32_port.h:474
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:698
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:6778
#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
void AppendIntegerCommandOption(PQExpBuffer buf, bool use_new_option_syntax, char *option_name, int32 option_value)
Definition: streamutil.c:688
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:454
static void kill_bgchild_atexit(void)
#define strerror
Definition: port.h:230
static char * xlog_dir
static bool manifest
static XLogRecPtr xlogendptr
static XLogRecPtr startpos
static bool no_slot
void AppendPlainCommandOption(PQExpBuffer buf, bool use_new_option_syntax, char *option_name)
Definition: streamutil.c:644
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:212
static bool made_new_xlogdir
static void CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
Definition: walsender.c:1027
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:71
static char * replication_slot
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:229
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:217
#define _(x)
Definition: elog.c:89
#define UINT64_FORMAT
Definition: c.h:484
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:376
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