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-2019, 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 <sys/stat.h> 19 #include <sys/wait.h> 20 #include <signal.h> 21 #include <time.h> 22 #ifdef HAVE_SYS_SELECT_H 23 #include <sys/select.h> 24 #endif 25 #ifdef HAVE_LIBZ 26 #include <zlib.h> 27 #endif 28 29 #include "access/xlog_internal.h" 30 #include "common/file_perm.h" 31 #include "common/file_utils.h" 32 #include "common/logging.h" 33 #include "common/string.h" 34 #include "fe_utils/string_utils.h" 35 #include "getopt_long.h" 36 #include "libpq-fe.h" 37 #include "pqexpbuffer.h" 38 #include "pgtar.h" 39 #include "pgtime.h" 40 #include "receivelog.h" 41 #include "replication/basebackup.h" 42 #include "streamutil.h" 43 44 #define ERRCODE_DATA_CORRUPTED "XX001" 45 46 typedef struct TablespaceListCell 47 { 48 struct TablespaceListCell *next; 49 char old_dir[MAXPGPATH]; 50 char new_dir[MAXPGPATH]; 51 } TablespaceListCell; 52 53 typedef struct TablespaceList 54 { 55 TablespaceListCell *head; 56 TablespaceListCell *tail; 57 } TablespaceList; 58 59 /* 60 * pg_xlog has been renamed to pg_wal in version 10. This version number 61 * should be compared with PQserverVersion(). 62 */ 63 #define MINIMUM_VERSION_FOR_PG_WAL 100000 64 65 /* 66 * Temporary replication slots are supported from version 10. 67 */ 68 #define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000 69 70 /* 71 * recovery.conf is integrated into postgresql.conf from version 12. 72 */ 73 #define MINIMUM_VERSION_FOR_RECOVERY_GUC 120000 74 75 /* 76 * Different ways to include WAL 77 */ 78 typedef enum 79 { 80 NO_WAL, 81 FETCH_WAL, 82 STREAM_WAL 83 } IncludeWal; 84 85 /* Global options */ 86 static char *basedir = NULL; 87 static TablespaceList tablespace_dirs = {NULL, NULL}; 88 static char *xlog_dir = NULL; 89 static char format = 'p'; /* p(lain)/t(ar) */ 90 static char *label = "pg_basebackup base backup"; 91 static bool noclean = false; 92 static bool checksum_failure = false; 93 static bool showprogress = false; 94 static int verbose = 0; 95 static int compresslevel = 0; 96 static IncludeWal includewal = STREAM_WAL; 97 static bool fastcheckpoint = false; 98 static bool writerecoveryconf = false; 99 static bool do_sync = true; 100 static int standby_message_timeout = 10 * 1000; /* 10 sec = default */ 101 static pg_time_t last_progress_report = 0; 102 static int32 maxrate = 0; /* no limit by default */ 103 static char *replication_slot = NULL; 104 static bool temp_replication_slot = true; 105 static bool create_slot = false; 106 static bool no_slot = false; 107 static bool verify_checksums = true; 108 109 static bool success = false; 110 static bool made_new_pgdata = false; 111 static bool found_existing_pgdata = false; 112 static bool made_new_xlogdir = false; 113 static bool found_existing_xlogdir = false; 114 static bool made_tablespace_dirs = false; 115 static bool found_tablespace_dirs = false; 116 117 /* Progress counters */ 118 static uint64 totalsize; 119 static uint64 totaldone; 120 static int tablespacecount; 121 122 /* Pipe to communicate with background wal receiver process */ 123 #ifndef WIN32 124 static int bgpipe[2] = {-1, -1}; 125 #endif 126 127 /* Handle to child process */ 128 static pid_t bgchild = -1; 129 static bool in_log_streamer = false; 130 131 /* End position for xlog streaming, empty string if unknown yet */ 132 static XLogRecPtr xlogendptr; 133 134 #ifndef WIN32 135 static int has_xlogendptr = 0; 136 #else 137 static volatile LONG has_xlogendptr = 0; 138 #endif 139 140 /* Contents of configuration file to be generated */ 141 static PQExpBuffer recoveryconfcontents = NULL; 142 143 /* Function headers */ 144 static void usage(void); 145 static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found); 146 static void progress_report(int tablespacenum, const char *filename, bool force, 147 bool finished); 148 149 static void ReceiveTarFile(PGconn *conn, PGresult *res, int rownum); 150 static void ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum); 151 static void GenerateRecoveryConf(PGconn *conn); 152 static void WriteRecoveryConf(void); 153 static void BaseBackup(void); 154 155 static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline, 156 bool segment_finished); 157 158 static const char *get_tablespace_mapping(const char *dir); 159 static void tablespace_list_append(const char *arg); 160 161 162 static void 163 cleanup_directories_atexit(void) 164 { 165 if (success || in_log_streamer) 166 return; 167 168 if (!noclean && !checksum_failure) 169 { 170 if (made_new_pgdata) 171 { 172 pg_log_info("removing data directory \"%s\"", basedir); 173 if (!rmtree(basedir, true)) 174 pg_log_error("failed to remove data directory"); 175 } 176 else if (found_existing_pgdata) 177 { 178 pg_log_info("removing contents of data directory \"%s\"", basedir); 179 if (!rmtree(basedir, false)) 180 pg_log_error("failed to remove contents of data directory"); 181 } 182 183 if (made_new_xlogdir) 184 { 185 pg_log_info("removing WAL directory \"%s\"", xlog_dir); 186 if (!rmtree(xlog_dir, true)) 187 pg_log_error("failed to remove WAL directory"); 188 } 189 else if (found_existing_xlogdir) 190 { 191 pg_log_info("removing contents of WAL directory \"%s\"", xlog_dir); 192 if (!rmtree(xlog_dir, false)) 193 pg_log_error("failed to remove contents of WAL directory"); 194 } 195 } 196 else 197 { 198 if ((made_new_pgdata || found_existing_pgdata) && !checksum_failure) 199 pg_log_info("data directory \"%s\" not removed at user's request", basedir); 200 201 if (made_new_xlogdir || found_existing_xlogdir) 202 pg_log_info("WAL directory \"%s\" not removed at user's request", xlog_dir); 203 } 204 205 if ((made_tablespace_dirs || found_tablespace_dirs) && !checksum_failure) 206 pg_log_info("changes to tablespace directories will not be undone"); 207 } 208 209 static void 210 disconnect_atexit(void) 211 { 212 if (conn != NULL) 213 PQfinish(conn); 214 } 215 216 #ifndef WIN32 217 /* 218 * On windows, our background thread dies along with the process. But on 219 * Unix, if we have started a subprocess, we want to kill it off so it 220 * doesn't remain running trying to stream data. 221 */ 222 static void 223 kill_bgchild_atexit(void) 224 { 225 if (bgchild > 0) 226 kill(bgchild, SIGTERM); 227 } 228 #endif 229 230 /* 231 * Split argument into old_dir and new_dir and append to tablespace mapping 232 * list. 233 */ 234 static void 235 tablespace_list_append(const char *arg) 236 { 237 TablespaceListCell *cell = (TablespaceListCell *) pg_malloc0(sizeof(TablespaceListCell)); 238 char *dst; 239 char *dst_ptr; 240 const char *arg_ptr; 241 242 dst_ptr = dst = cell->old_dir; 243 for (arg_ptr = arg; *arg_ptr; arg_ptr++) 244 { 245 if (dst_ptr - dst >= MAXPGPATH) 246 { 247 pg_log_error("directory name too long"); 248 exit(1); 249 } 250 251 if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=') 252 ; /* skip backslash escaping = */ 253 else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\')) 254 { 255 if (*cell->new_dir) 256 { 257 pg_log_error("multiple \"=\" signs in tablespace mapping"); 258 exit(1); 259 } 260 else 261 dst = dst_ptr = cell->new_dir; 262 } 263 else 264 *dst_ptr++ = *arg_ptr; 265 } 266 267 if (!*cell->old_dir || !*cell->new_dir) 268 { 269 pg_log_error("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"", arg); 270 exit(1); 271 } 272 273 /* 274 * This check isn't absolutely necessary. But all tablespaces are created 275 * with absolute directories, so specifying a non-absolute path here would 276 * just never match, possibly confusing users. It's also good to be 277 * consistent with the new_dir check. 278 */ 279 if (!is_absolute_path(cell->old_dir)) 280 { 281 pg_log_error("old directory is not an absolute path in tablespace mapping: %s", 282 cell->old_dir); 283 exit(1); 284 } 285 286 if (!is_absolute_path(cell->new_dir)) 287 { 288 pg_log_error("new directory is not an absolute path in tablespace mapping: %s", 289 cell->new_dir); 290 exit(1); 291 } 292 293 /* 294 * Comparisons done with these values should involve similarly 295 * canonicalized path values. This is particularly sensitive on Windows 296 * where path values may not necessarily use Unix slashes. 297 */ 298 canonicalize_path(cell->old_dir); 299 canonicalize_path(cell->new_dir); 300 301 if (tablespace_dirs.tail) 302 tablespace_dirs.tail->next = cell; 303 else 304 tablespace_dirs.head = cell; 305 tablespace_dirs.tail = cell; 306 } 307 308 309 #ifdef HAVE_LIBZ 310 static const char * 311 get_gz_error(gzFile gzf) 312 { 313 int errnum; 314 const char *errmsg; 315 316 errmsg = gzerror(gzf, &errnum); 317 if (errnum == Z_ERRNO) 318 return strerror(errno); 319 else 320 return errmsg; 321 } 322 #endif 323 324 static void 325 usage(void) 326 { 327 printf(_("%s takes a base backup of a running PostgreSQL server.\n\n"), 328 progname); 329 printf(_("Usage:\n")); 330 printf(_(" %s [OPTION]...\n"), progname); 331 printf(_("\nOptions controlling the output:\n")); 332 printf(_(" -D, --pgdata=DIRECTORY receive base backup into directory\n")); 333 printf(_(" -F, --format=p|t output format (plain (default), tar)\n")); 334 printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" 335 " (in kB/s, or use suffix \"k\" or \"M\")\n")); 336 printf(_(" -R, --write-recovery-conf\n" 337 " write configuration for replication\n")); 338 printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" 339 " relocate tablespace in OLDDIR to NEWDIR\n")); 340 printf(_(" --waldir=WALDIR location for the write-ahead log directory\n")); 341 printf(_(" -X, --wal-method=none|fetch|stream\n" 342 " include required WAL files with specified method\n")); 343 printf(_(" -z, --gzip compress tar output\n")); 344 printf(_(" -Z, --compress=0-9 compress tar output with given compression level\n")); 345 printf(_("\nGeneral options:\n")); 346 printf(_(" -c, --checkpoint=fast|spread\n" 347 " set fast or spread checkpointing\n")); 348 printf(_(" -C, --create-slot create replication slot\n")); 349 printf(_(" -l, --label=LABEL set backup label\n")); 350 printf(_(" -n, --no-clean do not clean up after errors\n")); 351 printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n")); 352 printf(_(" -P, --progress show progress information\n")); 353 printf(_(" -S, --slot=SLOTNAME replication slot to use\n")); 354 printf(_(" -v, --verbose output verbose messages\n")); 355 printf(_(" -V, --version output version information, then exit\n")); 356 printf(_(" --no-slot prevent creation of temporary replication slot\n")); 357 printf(_(" --no-verify-checksums\n" 358 " do not verify checksums\n")); 359 printf(_(" -?, --help show this help, then exit\n")); 360 printf(_("\nConnection options:\n")); 361 printf(_(" -d, --dbname=CONNSTR connection string\n")); 362 printf(_(" -h, --host=HOSTNAME database server host or socket directory\n")); 363 printf(_(" -p, --port=PORT database server port number\n")); 364 printf(_(" -s, --status-interval=INTERVAL\n" 365 " time between status packets sent to server (in seconds)\n")); 366 printf(_(" -U, --username=NAME connect as specified database user\n")); 367 printf(_(" -w, --no-password never prompt for password\n")); 368 printf(_(" -W, --password force password prompt (should happen automatically)\n")); 369 printf(_("\nReport bugs to <pgsql-bugs@lists.postgresql.org>.\n")); 370 } 371 372 373 /* 374 * Called in the background process every time data is received. 375 * On Unix, we check to see if there is any data on our pipe 376 * (which would mean we have a stop position), and if it is, check if 377 * it is time to stop. 378 * On Windows, we are in a single process, so we can just check if it's 379 * time to stop. 380 */ 381 static bool 382 reached_end_position(XLogRecPtr segendpos, uint32 timeline, 383 bool segment_finished) 384 { 385 if (!has_xlogendptr) 386 { 387 #ifndef WIN32 388 fd_set fds; 389 struct timeval tv; 390 int r; 391 392 /* 393 * Don't have the end pointer yet - check our pipe to see if it has 394 * been sent yet. 395 */ 396 FD_ZERO(&fds); 397 FD_SET(bgpipe[0], &fds); 398 399 MemSet(&tv, 0, sizeof(tv)); 400 401 r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv); 402 if (r == 1) 403 { 404 char xlogend[64]; 405 uint32 hi, 406 lo; 407 408 MemSet(xlogend, 0, sizeof(xlogend)); 409 r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1); 410 if (r < 0) 411 { 412 pg_log_error("could not read from ready pipe: %m"); 413 exit(1); 414 } 415 416 if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2) 417 { 418 pg_log_error("could not parse write-ahead log location \"%s\"", 419 xlogend); 420 exit(1); 421 } 422 xlogendptr = ((uint64) hi) << 32 | lo; 423 has_xlogendptr = 1; 424 425 /* 426 * Fall through to check if we've reached the point further 427 * already. 428 */ 429 } 430 else 431 { 432 /* 433 * No data received on the pipe means we don't know the end 434 * position yet - so just say it's not time to stop yet. 435 */ 436 return false; 437 } 438 #else 439 440 /* 441 * On win32, has_xlogendptr is set by the main thread, so if it's not 442 * set here, we just go back and wait until it shows up. 443 */ 444 return false; 445 #endif 446 } 447 448 /* 449 * At this point we have an end pointer, so compare it to the current 450 * position to figure out if it's time to stop. 451 */ 452 if (segendpos >= xlogendptr) 453 return true; 454 455 /* 456 * Have end pointer, but haven't reached it yet - so tell the caller to 457 * keep streaming. 458 */ 459 return false; 460 } 461 462 typedef struct 463 { 464 PGconn *bgconn; 465 XLogRecPtr startptr; 466 char xlog[MAXPGPATH]; /* directory or tarfile depending on mode */ 467 char *sysidentifier; 468 int timeline; 469 } logstreamer_param; 470 471 static int 472 LogStreamerMain(logstreamer_param *param) 473 { 474 StreamCtl stream; 475 476 in_log_streamer = true; 477 478 MemSet(&stream, 0, sizeof(stream)); 479 stream.startpos = param->startptr; 480 stream.timeline = param->timeline; 481 stream.sysidentifier = param->sysidentifier; 482 stream.stream_stop = reached_end_position; 483 #ifndef WIN32 484 stream.stop_socket = bgpipe[0]; 485 #else 486 stream.stop_socket = PGINVALID_SOCKET; 487 #endif 488 stream.standby_message_timeout = standby_message_timeout; 489 stream.synchronous = false; 490 /* fsync happens at the end of pg_basebackup for all data */ 491 stream.do_sync = false; 492 stream.mark_done = true; 493 stream.partial_suffix = NULL; 494 stream.replication_slot = replication_slot; 495 496 if (format == 'p') 497 stream.walmethod = CreateWalDirectoryMethod(param->xlog, 0, 498 stream.do_sync); 499 else 500 stream.walmethod = CreateWalTarMethod(param->xlog, compresslevel, 501 stream.do_sync); 502 503 if (!ReceiveXlogStream(param->bgconn, &stream)) 504 505 /* 506 * Any errors will already have been reported in the function process, 507 * but we need to tell the parent that we didn't shutdown in a nice 508 * way. 509 */ 510 return 1; 511 512 if (!stream.walmethod->finish()) 513 { 514 pg_log_error("could not finish writing WAL files: %m"); 515 return 1; 516 } 517 518 PQfinish(param->bgconn); 519 520 if (format == 'p') 521 FreeWalDirectoryMethod(); 522 else 523 FreeWalTarMethod(); 524 pg_free(stream.walmethod); 525 526 return 0; 527 } 528 529 /* 530 * Initiate background process for receiving xlog during the backup. 531 * The background stream will use its own database connection so we can 532 * stream the logfile in parallel with the backups. 533 */ 534 static void 535 StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) 536 { 537 logstreamer_param *param; 538 uint32 hi, 539 lo; 540 char statusdir[MAXPGPATH]; 541 542 param = pg_malloc0(sizeof(logstreamer_param)); 543 param->timeline = timeline; 544 param->sysidentifier = sysidentifier; 545 546 /* Convert the starting position */ 547 if (sscanf(startpos, "%X/%X", &hi, &lo) != 2) 548 { 549 pg_log_error("could not parse write-ahead log location \"%s\"", 550 startpos); 551 exit(1); 552 } 553 param->startptr = ((uint64) hi) << 32 | lo; 554 /* Round off to even segment position */ 555 param->startptr -= XLogSegmentOffset(param->startptr, WalSegSz); 556 557 #ifndef WIN32 558 /* Create our background pipe */ 559 if (pipe(bgpipe) < 0) 560 { 561 pg_log_error("could not create pipe for background process: %m"); 562 exit(1); 563 } 564 #endif 565 566 /* Get a second connection */ 567 param->bgconn = GetConnection(); 568 if (!param->bgconn) 569 /* Error message already written in GetConnection() */ 570 exit(1); 571 572 /* In post-10 cluster, pg_xlog has been renamed to pg_wal */ 573 snprintf(param->xlog, sizeof(param->xlog), "%s/%s", 574 basedir, 575 PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ? 576 "pg_xlog" : "pg_wal"); 577 578 /* Temporary replication slots are only supported in 10 and newer */ 579 if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_TEMP_SLOTS) 580 temp_replication_slot = false; 581 582 /* 583 * Create replication slot if requested 584 */ 585 if (temp_replication_slot && !replication_slot) 586 replication_slot = psprintf("pg_basebackup_%d", (int) PQbackendPID(param->bgconn)); 587 if (temp_replication_slot || create_slot) 588 { 589 if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL, 590 temp_replication_slot, true, true, false)) 591 exit(1); 592 593 if (verbose) 594 { 595 if (temp_replication_slot) 596 pg_log_info("created temporary replication slot \"%s\"", 597 replication_slot); 598 else 599 pg_log_info("created replication slot \"%s\"", 600 replication_slot); 601 } 602 } 603 604 if (format == 'p') 605 { 606 /* 607 * Create pg_wal/archive_status or pg_xlog/archive_status (and thus 608 * pg_wal or pg_xlog) depending on the target server so we can write 609 * to basedir/pg_wal or basedir/pg_xlog as the directory entry in the 610 * tar file may arrive later. 611 */ 612 snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status", 613 basedir, 614 PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ? 615 "pg_xlog" : "pg_wal"); 616 617 if (pg_mkdir_p(statusdir, pg_dir_create_mode) != 0 && errno != EEXIST) 618 { 619 pg_log_error("could not create directory \"%s\": %m", statusdir); 620 exit(1); 621 } 622 } 623 624 /* 625 * Start a child process and tell it to start streaming. On Unix, this is 626 * a fork(). On Windows, we create a thread. 627 */ 628 #ifndef WIN32 629 bgchild = fork(); 630 if (bgchild == 0) 631 { 632 /* in child process */ 633 exit(LogStreamerMain(param)); 634 } 635 else if (bgchild < 0) 636 { 637 pg_log_error("could not create background process: %m"); 638 exit(1); 639 } 640 641 /* 642 * Else we are in the parent process and all is well. 643 */ 644 atexit(kill_bgchild_atexit); 645 #else /* WIN32 */ 646 bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL); 647 if (bgchild == 0) 648 { 649 pg_log_error("could not create background thread: %m"); 650 exit(1); 651 } 652 #endif 653 } 654 655 /* 656 * Verify that the given directory exists and is empty. If it does not 657 * exist, it is created. If it exists but is not empty, an error will 658 * be given and the process ended. 659 */ 660 static void 661 verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found) 662 { 663 switch (pg_check_dir(dirname)) 664 { 665 case 0: 666 667 /* 668 * Does not exist, so create 669 */ 670 if (pg_mkdir_p(dirname, pg_dir_create_mode) == -1) 671 { 672 pg_log_error("could not create directory \"%s\": %m", dirname); 673 exit(1); 674 } 675 if (created) 676 *created = true; 677 return; 678 case 1: 679 680 /* 681 * Exists, empty 682 */ 683 if (found) 684 *found = true; 685 return; 686 case 2: 687 case 3: 688 case 4: 689 690 /* 691 * Exists, not empty 692 */ 693 pg_log_error("directory \"%s\" exists but is not empty", dirname); 694 exit(1); 695 case -1: 696 697 /* 698 * Access problem 699 */ 700 pg_log_error("could not access directory \"%s\": %m", dirname); 701 exit(1); 702 } 703 } 704 705 706 /* 707 * Print a progress report based on the global variables. If verbose output 708 * is enabled, also print the current file name. 709 * 710 * Progress report is written at maximum once per second, unless the force 711 * parameter is set to true. 712 * 713 * If finished is set to true, this is the last progress report. The cursor 714 * is moved to the next line. 715 */ 716 static void 717 progress_report(int tablespacenum, const char *filename, 718 bool force, bool finished) 719 { 720 int percent; 721 char totaldone_str[32]; 722 char totalsize_str[32]; 723 pg_time_t now; 724 725 if (!showprogress) 726 return; 727 728 now = time(NULL); 729 if (now == last_progress_report && !force && !finished) 730 return; /* Max once per second */ 731 732 last_progress_report = now; 733 percent = totalsize ? (int) ((totaldone / 1024) * 100 / totalsize) : 0; 734 735 /* 736 * Avoid overflowing past 100% or the full size. This may make the total 737 * size number change as we approach the end of the backup (the estimate 738 * will always be wrong if WAL is included), but that's better than having 739 * the done column be bigger than the total. 740 */ 741 if (percent > 100) 742 percent = 100; 743 if (totaldone / 1024 > totalsize) 744 totalsize = totaldone / 1024; 745 746 /* 747 * Separate step to keep platform-dependent format code out of 748 * translatable strings. And we only test for INT64_FORMAT availability 749 * in snprintf, not fprintf. 750 */ 751 snprintf(totaldone_str, sizeof(totaldone_str), INT64_FORMAT, 752 totaldone / 1024); 753 snprintf(totalsize_str, sizeof(totalsize_str), INT64_FORMAT, totalsize); 754 755 #define VERBOSE_FILENAME_LENGTH 35 756 if (verbose) 757 { 758 if (!filename) 759 760 /* 761 * No filename given, so clear the status line (used for last 762 * call) 763 */ 764 fprintf(stderr, 765 ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s", 766 "%*s/%s kB (100%%), %d/%d tablespaces %*s", 767 tablespacecount), 768 (int) strlen(totalsize_str), 769 totaldone_str, totalsize_str, 770 tablespacenum, tablespacecount, 771 VERBOSE_FILENAME_LENGTH + 5, ""); 772 else 773 { 774 bool truncate = (strlen(filename) > VERBOSE_FILENAME_LENGTH); 775 776 fprintf(stderr, 777 ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)", 778 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)", 779 tablespacecount), 780 (int) strlen(totalsize_str), 781 totaldone_str, totalsize_str, percent, 782 tablespacenum, tablespacecount, 783 /* Prefix with "..." if we do leading truncation */ 784 truncate ? "..." : "", 785 truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH, 786 truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH, 787 /* Truncate filename at beginning if it's too long */ 788 truncate ? filename + strlen(filename) - VERBOSE_FILENAME_LENGTH + 3 : filename); 789 } 790 } 791 else 792 fprintf(stderr, 793 ngettext("%*s/%s kB (%d%%), %d/%d tablespace", 794 "%*s/%s kB (%d%%), %d/%d tablespaces", 795 tablespacecount), 796 (int) strlen(totalsize_str), 797 totaldone_str, totalsize_str, percent, 798 tablespacenum, tablespacecount); 799 800 /* 801 * Stay on the same line if reporting to a terminal and we're not done 802 * yet. 803 */ 804 fputc((!finished && isatty(fileno(stderr))) ? '\r' : '\n', stderr); 805 } 806 807 static int32 808 parse_max_rate(char *src) 809 { 810 double result; 811 char *after_num; 812 char *suffix = NULL; 813 814 errno = 0; 815 result = strtod(src, &after_num); 816 if (src == after_num) 817 { 818 pg_log_error("transfer rate \"%s\" is not a valid value", src); 819 exit(1); 820 } 821 if (errno != 0) 822 { 823 pg_log_error("invalid transfer rate \"%s\": %m", src); 824 exit(1); 825 } 826 827 if (result <= 0) 828 { 829 /* 830 * Reject obviously wrong values here. 831 */ 832 pg_log_error("transfer rate must be greater than zero"); 833 exit(1); 834 } 835 836 /* 837 * Evaluate suffix, after skipping over possible whitespace. Lack of 838 * suffix means kilobytes. 839 */ 840 while (*after_num != '\0' && isspace((unsigned char) *after_num)) 841 after_num++; 842 843 if (*after_num != '\0') 844 { 845 suffix = after_num; 846 if (*after_num == 'k') 847 { 848 /* kilobyte is the expected unit. */ 849 after_num++; 850 } 851 else if (*after_num == 'M') 852 { 853 after_num++; 854 result *= 1024.0; 855 } 856 } 857 858 /* The rest can only consist of white space. */ 859 while (*after_num != '\0' && isspace((unsigned char) *after_num)) 860 after_num++; 861 862 if (*after_num != '\0') 863 { 864 pg_log_error("invalid --max-rate unit: \"%s\"", suffix); 865 exit(1); 866 } 867 868 /* Valid integer? */ 869 if ((uint64) result != (uint64) ((uint32) result)) 870 { 871 pg_log_error("transfer rate \"%s\" exceeds integer range", src); 872 exit(1); 873 } 874 875 /* 876 * The range is checked on the server side too, but avoid the server 877 * connection if a nonsensical value was passed. 878 */ 879 if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER) 880 { 881 pg_log_error("transfer rate \"%s\" is out of range", src); 882 exit(1); 883 } 884 885 return (int32) result; 886 } 887 888 /* 889 * Write a piece of tar data 890 */ 891 static void 892 writeTarData( 893 #ifdef HAVE_LIBZ 894 gzFile ztarfile, 895 #endif 896 FILE *tarfile, char *buf, int r, char *current_file) 897 { 898 #ifdef HAVE_LIBZ 899 if (ztarfile != NULL) 900 { 901 errno = 0; 902 if (gzwrite(ztarfile, buf, r) != r) 903 { 904 /* if write didn't set errno, assume problem is no disk space */ 905 if (errno == 0) 906 errno = ENOSPC; 907 pg_log_error("could not write to compressed file \"%s\": %s", 908 current_file, get_gz_error(ztarfile)); 909 exit(1); 910 } 911 } 912 else 913 #endif 914 { 915 errno = 0; 916 if (fwrite(buf, r, 1, tarfile) != 1) 917 { 918 /* if write didn't set errno, assume problem is no disk space */ 919 if (errno == 0) 920 errno = ENOSPC; 921 pg_log_error("could not write to file \"%s\": %m", current_file); 922 exit(1); 923 } 924 } 925 } 926 927 #ifdef HAVE_LIBZ 928 #define WRITE_TAR_DATA(buf, sz) writeTarData(ztarfile, tarfile, buf, sz, filename) 929 #else 930 #define WRITE_TAR_DATA(buf, sz) writeTarData(tarfile, buf, sz, filename) 931 #endif 932 933 /* 934 * Receive a tar format file from the connection to the server, and write 935 * the data from this file directly into a tar file. If compression is 936 * enabled, the data will be compressed while written to the file. 937 * 938 * The file will be named base.tar[.gz] if it's for the main data directory 939 * or <tablespaceoid>.tar[.gz] if it's for another tablespace. 940 * 941 * No attempt to inspect or validate the contents of the file is done. 942 */ 943 static void 944 ReceiveTarFile(PGconn *conn, PGresult *res, int rownum) 945 { 946 char filename[MAXPGPATH]; 947 char *copybuf = NULL; 948 FILE *tarfile = NULL; 949 char tarhdr[512]; 950 bool basetablespace = PQgetisnull(res, rownum, 0); 951 bool in_tarhdr = true; 952 bool skip_file = false; 953 bool is_recovery_guc_supported = true; 954 bool is_postgresql_auto_conf = false; 955 bool found_postgresql_auto_conf = false; 956 int file_padding_len = 0; 957 size_t tarhdrsz = 0; 958 pgoff_t filesz = 0; 959 960 #ifdef HAVE_LIBZ 961 gzFile ztarfile = NULL; 962 #endif 963 964 /* recovery.conf is integrated into postgresql.conf in 12 and newer */ 965 if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) 966 is_recovery_guc_supported = false; 967 968 if (basetablespace) 969 { 970 /* 971 * Base tablespaces 972 */ 973 if (strcmp(basedir, "-") == 0) 974 { 975 #ifdef WIN32 976 _setmode(fileno(stdout), _O_BINARY); 977 #endif 978 979 #ifdef HAVE_LIBZ 980 if (compresslevel != 0) 981 { 982 ztarfile = gzdopen(dup(fileno(stdout)), "wb"); 983 if (gzsetparams(ztarfile, compresslevel, 984 Z_DEFAULT_STRATEGY) != Z_OK) 985 { 986 pg_log_error("could not set compression level %d: %s", 987 compresslevel, get_gz_error(ztarfile)); 988 exit(1); 989 } 990 } 991 else 992 #endif 993 tarfile = stdout; 994 strcpy(filename, "-"); 995 } 996 else 997 { 998 #ifdef HAVE_LIBZ 999 if (compresslevel != 0) 1000 { 1001 snprintf(filename, sizeof(filename), "%s/base.tar.gz", basedir); 1002 ztarfile = gzopen(filename, "wb"); 1003 if (gzsetparams(ztarfile, compresslevel, 1004 Z_DEFAULT_STRATEGY) != Z_OK) 1005 { 1006 pg_log_error("could not set compression level %d: %s", 1007 compresslevel, get_gz_error(ztarfile)); 1008 exit(1); 1009 } 1010 } 1011 else 1012 #endif 1013 { 1014 snprintf(filename, sizeof(filename), "%s/base.tar", basedir); 1015 tarfile = fopen(filename, "wb"); 1016 } 1017 } 1018 } 1019 else 1020 { 1021 /* 1022 * Specific tablespace 1023 */ 1024 #ifdef HAVE_LIBZ 1025 if (compresslevel != 0) 1026 { 1027 snprintf(filename, sizeof(filename), "%s/%s.tar.gz", basedir, 1028 PQgetvalue(res, rownum, 0)); 1029 ztarfile = gzopen(filename, "wb"); 1030 if (gzsetparams(ztarfile, compresslevel, 1031 Z_DEFAULT_STRATEGY) != Z_OK) 1032 { 1033 pg_log_error("could not set compression level %d: %s", 1034 compresslevel, get_gz_error(ztarfile)); 1035 exit(1); 1036 } 1037 } 1038 else 1039 #endif 1040 { 1041 snprintf(filename, sizeof(filename), "%s/%s.tar", basedir, 1042 PQgetvalue(res, rownum, 0)); 1043 tarfile = fopen(filename, "wb"); 1044 } 1045 } 1046 1047 #ifdef HAVE_LIBZ 1048 if (compresslevel != 0) 1049 { 1050 if (!ztarfile) 1051 { 1052 /* Compression is in use */ 1053 pg_log_error("could not create compressed file \"%s\": %s", 1054 filename, get_gz_error(ztarfile)); 1055 exit(1); 1056 } 1057 } 1058 else 1059 #endif 1060 { 1061 /* Either no zlib support, or zlib support but compresslevel = 0 */ 1062 if (!tarfile) 1063 { 1064 pg_log_error("could not create file \"%s\": %m", filename); 1065 exit(1); 1066 } 1067 } 1068 1069 /* 1070 * Get the COPY data stream 1071 */ 1072 res = PQgetResult(conn); 1073 if (PQresultStatus(res) != PGRES_COPY_OUT) 1074 { 1075 pg_log_error("could not get COPY data stream: %s", 1076 PQerrorMessage(conn)); 1077 exit(1); 1078 } 1079 1080 while (1) 1081 { 1082 int r; 1083 1084 if (copybuf != NULL) 1085 { 1086 PQfreemem(copybuf); 1087 copybuf = NULL; 1088 } 1089 1090 r = PQgetCopyData(conn, ©buf, 0); 1091 if (r == -1) 1092 { 1093 /* 1094 * End of chunk. If requested, and this is the base tablespace, 1095 * write configuration file into the tarfile. When done, close the 1096 * file (but not stdout). 1097 * 1098 * Also, write two completely empty blocks at the end of the tar 1099 * file, as required by some tar programs. 1100 */ 1101 char zerobuf[1024]; 1102 1103 MemSet(zerobuf, 0, sizeof(zerobuf)); 1104 1105 if (basetablespace && writerecoveryconf) 1106 { 1107 char header[512]; 1108 1109 /* 1110 * If postgresql.auto.conf has not been found in the streamed 1111 * data, add recovery configuration to postgresql.auto.conf if 1112 * recovery parameters are GUCs. If the instance connected to 1113 * is older than 12, create recovery.conf with this data 1114 * otherwise. 1115 */ 1116 if (!found_postgresql_auto_conf || !is_recovery_guc_supported) 1117 { 1118 int padding; 1119 1120 tarCreateHeader(header, 1121 is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf", 1122 NULL, 1123 recoveryconfcontents->len, 1124 pg_file_create_mode, 04000, 02000, 1125 time(NULL)); 1126 1127 padding = ((recoveryconfcontents->len + 511) & ~511) - recoveryconfcontents->len; 1128 1129 WRITE_TAR_DATA(header, sizeof(header)); 1130 WRITE_TAR_DATA(recoveryconfcontents->data, 1131 recoveryconfcontents->len); 1132 if (padding) 1133 WRITE_TAR_DATA(zerobuf, padding); 1134 } 1135 1136 /* 1137 * standby.signal is supported only if recovery parameters are 1138 * GUCs. 1139 */ 1140 if (is_recovery_guc_supported) 1141 { 1142 tarCreateHeader(header, "standby.signal", NULL, 1143 0, /* zero-length file */ 1144 pg_file_create_mode, 04000, 02000, 1145 time(NULL)); 1146 1147 WRITE_TAR_DATA(header, sizeof(header)); 1148 1149 /* 1150 * we don't need to pad out to a multiple of the tar block 1151 * size here, because the file is zero length, which is a 1152 * multiple of any block size. 1153 */ 1154 } 1155 } 1156 1157 /* 2 * 512 bytes empty data at end of file */ 1158 WRITE_TAR_DATA(zerobuf, sizeof(zerobuf)); 1159 1160 #ifdef HAVE_LIBZ 1161 if (ztarfile != NULL) 1162 { 1163 if (gzclose(ztarfile) != 0) 1164 { 1165 pg_log_error("could not close compressed file \"%s\": %s", 1166 filename, get_gz_error(ztarfile)); 1167 exit(1); 1168 } 1169 } 1170 else 1171 #endif 1172 { 1173 if (strcmp(basedir, "-") != 0) 1174 { 1175 if (fclose(tarfile) != 0) 1176 { 1177 pg_log_error("could not close file \"%s\": %m", 1178 filename); 1179 exit(1); 1180 } 1181 } 1182 } 1183 1184 break; 1185 } 1186 else if (r == -2) 1187 { 1188 pg_log_error("could not read COPY data: %s", 1189 PQerrorMessage(conn)); 1190 exit(1); 1191 } 1192 1193 if (!writerecoveryconf || !basetablespace) 1194 { 1195 /* 1196 * When not writing config file, or when not working on the base 1197 * tablespace, we never have to look for an existing configuration 1198 * file in the stream. 1199 */ 1200 WRITE_TAR_DATA(copybuf, r); 1201 } 1202 else 1203 { 1204 /* 1205 * Look for a config file in the existing tar stream. If it's 1206 * there, we must skip it so we can later overwrite it with our 1207 * own version of the file. 1208 * 1209 * To do this, we have to process the individual files inside the 1210 * TAR stream. The stream consists of a header and zero or more 1211 * chunks, all 512 bytes long. The stream from the server is 1212 * broken up into smaller pieces, so we have to track the size of 1213 * the files to find the next header structure. 1214 */ 1215 int rr = r; 1216 int pos = 0; 1217 1218 while (rr > 0) 1219 { 1220 if (in_tarhdr) 1221 { 1222 /* 1223 * We're currently reading a header structure inside the 1224 * TAR stream, i.e. the file metadata. 1225 */ 1226 if (tarhdrsz < 512) 1227 { 1228 /* 1229 * Copy the header structure into tarhdr in case the 1230 * header is not aligned to 512 bytes or it's not 1231 * returned in whole by the last PQgetCopyData call. 1232 */ 1233 int hdrleft; 1234 int bytes2copy; 1235 1236 hdrleft = 512 - tarhdrsz; 1237 bytes2copy = (rr > hdrleft ? hdrleft : rr); 1238 1239 memcpy(&tarhdr[tarhdrsz], copybuf + pos, bytes2copy); 1240 1241 rr -= bytes2copy; 1242 pos += bytes2copy; 1243 tarhdrsz += bytes2copy; 1244 } 1245 else 1246 { 1247 /* 1248 * We have the complete header structure in tarhdr, 1249 * look at the file metadata: we may want append 1250 * recovery info into postgresql.auto.conf and skip 1251 * standby.signal file if recovery parameters are 1252 * integrated as GUCs, and recovery.conf otherwise. In 1253 * both cases we must calculate tar padding. 1254 */ 1255 if (is_recovery_guc_supported) 1256 { 1257 skip_file = (strcmp(&tarhdr[0], "standby.signal") == 0); 1258 is_postgresql_auto_conf = (strcmp(&tarhdr[0], "postgresql.auto.conf") == 0); 1259 } 1260 else 1261 skip_file = (strcmp(&tarhdr[0], "recovery.conf") == 0); 1262 1263 filesz = read_tar_number(&tarhdr[124], 12); 1264 file_padding_len = ((filesz + 511) & ~511) - filesz; 1265 1266 if (is_recovery_guc_supported && 1267 is_postgresql_auto_conf && 1268 writerecoveryconf) 1269 { 1270 /* replace tar header */ 1271 char header[512]; 1272 1273 tarCreateHeader(header, "postgresql.auto.conf", NULL, 1274 filesz + recoveryconfcontents->len, 1275 pg_file_create_mode, 04000, 02000, 1276 time(NULL)); 1277 1278 WRITE_TAR_DATA(header, sizeof(header)); 1279 } 1280 else 1281 { 1282 /* copy stream with padding */ 1283 filesz += file_padding_len; 1284 1285 if (!skip_file) 1286 { 1287 /* 1288 * If we're not skipping the file, write the 1289 * tar header unmodified. 1290 */ 1291 WRITE_TAR_DATA(tarhdr, 512); 1292 } 1293 } 1294 1295 /* Next part is the file, not the header */ 1296 in_tarhdr = false; 1297 } 1298 } 1299 else 1300 { 1301 /* 1302 * We're processing a file's contents. 1303 */ 1304 if (filesz > 0) 1305 { 1306 /* 1307 * We still have data to read (and possibly write). 1308 */ 1309 int bytes2write; 1310 1311 bytes2write = (filesz > rr ? rr : filesz); 1312 1313 if (!skip_file) 1314 WRITE_TAR_DATA(copybuf + pos, bytes2write); 1315 1316 rr -= bytes2write; 1317 pos += bytes2write; 1318 filesz -= bytes2write; 1319 } 1320 else if (is_recovery_guc_supported && 1321 is_postgresql_auto_conf && 1322 writerecoveryconf) 1323 { 1324 /* append recovery config to postgresql.auto.conf */ 1325 int padding; 1326 int tailsize; 1327 1328 tailsize = (512 - file_padding_len) + recoveryconfcontents->len; 1329 padding = ((tailsize + 511) & ~511) - tailsize; 1330 1331 WRITE_TAR_DATA(recoveryconfcontents->data, recoveryconfcontents->len); 1332 1333 if (padding) 1334 { 1335 char zerobuf[512]; 1336 1337 MemSet(zerobuf, 0, sizeof(zerobuf)); 1338 WRITE_TAR_DATA(zerobuf, padding); 1339 } 1340 1341 /* skip original file padding */ 1342 is_postgresql_auto_conf = false; 1343 skip_file = true; 1344 filesz += file_padding_len; 1345 1346 found_postgresql_auto_conf = true; 1347 } 1348 else 1349 { 1350 /* 1351 * No more data in the current file, the next piece of 1352 * data (if any) will be a new file header structure. 1353 */ 1354 in_tarhdr = true; 1355 skip_file = false; 1356 is_postgresql_auto_conf = false; 1357 tarhdrsz = 0; 1358 filesz = 0; 1359 } 1360 } 1361 } 1362 } 1363 totaldone += r; 1364 progress_report(rownum, filename, false, false); 1365 } /* while (1) */ 1366 progress_report(rownum, filename, true, false); 1367 1368 if (copybuf != NULL) 1369 PQfreemem(copybuf); 1370 1371 /* 1372 * Do not sync the resulting tar file yet, all files are synced once at 1373 * the end. 1374 */ 1375 } 1376 1377 1378 /* 1379 * Retrieve tablespace path, either relocated or original depending on whether 1380 * -T was passed or not. 1381 */ 1382 static const char * 1383 get_tablespace_mapping(const char *dir) 1384 { 1385 TablespaceListCell *cell; 1386 char canon_dir[MAXPGPATH]; 1387 1388 /* Canonicalize path for comparison consistency */ 1389 strlcpy(canon_dir, dir, sizeof(canon_dir)); 1390 canonicalize_path(canon_dir); 1391 1392 for (cell = tablespace_dirs.head; cell; cell = cell->next) 1393 if (strcmp(canon_dir, cell->old_dir) == 0) 1394 return cell->new_dir; 1395 1396 return dir; 1397 } 1398 1399 1400 /* 1401 * Receive a tar format stream from the connection to the server, and unpack 1402 * the contents of it into a directory. Only files, directories and 1403 * symlinks are supported, no other kinds of special files. 1404 * 1405 * If the data is for the main data directory, it will be restored in the 1406 * specified directory. If it's for another tablespace, it will be restored 1407 * in the original or mapped directory. 1408 */ 1409 static void 1410 ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum) 1411 { 1412 char current_path[MAXPGPATH]; 1413 char filename[MAXPGPATH]; 1414 const char *mapped_tblspc_path; 1415 pgoff_t current_len_left = 0; 1416 int current_padding = 0; 1417 bool basetablespace; 1418 char *copybuf = NULL; 1419 FILE *file = NULL; 1420 1421 basetablespace = PQgetisnull(res, rownum, 0); 1422 if (basetablespace) 1423 strlcpy(current_path, basedir, sizeof(current_path)); 1424 else 1425 strlcpy(current_path, 1426 get_tablespace_mapping(PQgetvalue(res, rownum, 1)), 1427 sizeof(current_path)); 1428 1429 /* 1430 * Get the COPY data 1431 */ 1432 res = PQgetResult(conn); 1433 if (PQresultStatus(res) != PGRES_COPY_OUT) 1434 { 1435 pg_log_error("could not get COPY data stream: %s", 1436 PQerrorMessage(conn)); 1437 exit(1); 1438 } 1439 1440 while (1) 1441 { 1442 int r; 1443 1444 if (copybuf != NULL) 1445 { 1446 PQfreemem(copybuf); 1447 copybuf = NULL; 1448 } 1449 1450 r = PQgetCopyData(conn, ©buf, 0); 1451 1452 if (r == -1) 1453 { 1454 /* 1455 * End of chunk 1456 */ 1457 if (file) 1458 fclose(file); 1459 1460 break; 1461 } 1462 else if (r == -2) 1463 { 1464 pg_log_error("could not read COPY data: %s", 1465 PQerrorMessage(conn)); 1466 exit(1); 1467 } 1468 1469 if (file == NULL) 1470 { 1471 int filemode; 1472 1473 /* 1474 * No current file, so this must be the header for a new file 1475 */ 1476 if (r != 512) 1477 { 1478 pg_log_error("invalid tar block header size: %d", r); 1479 exit(1); 1480 } 1481 totaldone += 512; 1482 1483 current_len_left = read_tar_number(©buf[124], 12); 1484 1485 /* Set permissions on the file */ 1486 filemode = read_tar_number(©buf[100], 8); 1487 1488 /* 1489 * All files are padded up to 512 bytes 1490 */ 1491 current_padding = 1492 ((current_len_left + 511) & ~511) - current_len_left; 1493 1494 /* 1495 * First part of header is zero terminated filename 1496 */ 1497 snprintf(filename, sizeof(filename), "%s/%s", current_path, 1498 copybuf); 1499 if (filename[strlen(filename) - 1] == '/') 1500 { 1501 /* 1502 * Ends in a slash means directory or symlink to directory 1503 */ 1504 if (copybuf[156] == '5') 1505 { 1506 /* 1507 * Directory 1508 */ 1509 filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */ 1510 if (mkdir(filename, pg_dir_create_mode) != 0) 1511 { 1512 /* 1513 * When streaming WAL, pg_wal (or pg_xlog for pre-9.6 1514 * clusters) will have been created by the wal 1515 * receiver process. Also, when the WAL directory 1516 * location was specified, pg_wal (or pg_xlog) has 1517 * already been created as a symbolic link before 1518 * starting the actual backup. So just ignore creation 1519 * failures on related directories. 1520 */ 1521 if (!((pg_str_endswith(filename, "/pg_wal") || 1522 pg_str_endswith(filename, "/pg_xlog") || 1523 pg_str_endswith(filename, "/archive_status")) && 1524 errno == EEXIST)) 1525 { 1526 pg_log_error("could not create directory \"%s\": %m", 1527 filename); 1528 exit(1); 1529 } 1530 } 1531 #ifndef WIN32 1532 if (chmod(filename, (mode_t) filemode)) 1533 pg_log_error("could not set permissions on directory \"%s\": %m", 1534 filename); 1535 #endif 1536 } 1537 else if (copybuf[156] == '2') 1538 { 1539 /* 1540 * Symbolic link 1541 * 1542 * It's most likely a link in pg_tblspc directory, to the 1543 * location of a tablespace. Apply any tablespace mapping 1544 * given on the command line (--tablespace-mapping). (We 1545 * blindly apply the mapping without checking that the 1546 * link really is inside pg_tblspc. We don't expect there 1547 * to be other symlinks in a data directory, but if there 1548 * are, you can call it an undocumented feature that you 1549 * can map them too.) 1550 */ 1551 filename[strlen(filename) - 1] = '\0'; /* Remove trailing slash */ 1552 1553 mapped_tblspc_path = get_tablespace_mapping(©buf[157]); 1554 if (symlink(mapped_tblspc_path, filename) != 0) 1555 { 1556 pg_log_error("could not create symbolic link from \"%s\" to \"%s\": %m", 1557 filename, mapped_tblspc_path); 1558 exit(1); 1559 } 1560 } 1561 else 1562 { 1563 pg_log_error("unrecognized link indicator \"%c\"", 1564 copybuf[156]); 1565 exit(1); 1566 } 1567 continue; /* directory or link handled */ 1568 } 1569 1570 /* 1571 * regular file 1572 */ 1573 file = fopen(filename, "wb"); 1574 if (!file) 1575 { 1576 pg_log_error("could not create file \"%s\": %m", filename); 1577 exit(1); 1578 } 1579 1580 #ifndef WIN32 1581 if (chmod(filename, (mode_t) filemode)) 1582 pg_log_error("could not set permissions on file \"%s\": %m", 1583 filename); 1584 #endif 1585 1586 if (current_len_left == 0) 1587 { 1588 /* 1589 * Done with this file, next one will be a new tar header 1590 */ 1591 fclose(file); 1592 file = NULL; 1593 continue; 1594 } 1595 } /* new file */ 1596 else 1597 { 1598 /* 1599 * Continuing blocks in existing file 1600 */ 1601 if (current_len_left == 0 && r == current_padding) 1602 { 1603 /* 1604 * Received the padding block for this file, ignore it and 1605 * close the file, then move on to the next tar header. 1606 */ 1607 fclose(file); 1608 file = NULL; 1609 totaldone += r; 1610 continue; 1611 } 1612 1613 errno = 0; 1614 if (fwrite(copybuf, r, 1, file) != 1) 1615 { 1616 /* if write didn't set errno, assume problem is no disk space */ 1617 if (errno == 0) 1618 errno = ENOSPC; 1619 pg_log_error("could not write to file \"%s\": %m", filename); 1620 exit(1); 1621 } 1622 totaldone += r; 1623 progress_report(rownum, filename, false, false); 1624 1625 current_len_left -= r; 1626 if (current_len_left == 0 && current_padding == 0) 1627 { 1628 /* 1629 * Received the last block, and there is no padding to be 1630 * expected. Close the file and move on to the next tar 1631 * header. 1632 */ 1633 fclose(file); 1634 file = NULL; 1635 continue; 1636 } 1637 } /* continuing data in existing file */ 1638 } /* loop over all data blocks */ 1639 progress_report(rownum, filename, true, false); 1640 1641 if (file != NULL) 1642 { 1643 pg_log_error("COPY stream ended before last file was finished"); 1644 exit(1); 1645 } 1646 1647 if (copybuf != NULL) 1648 PQfreemem(copybuf); 1649 1650 if (basetablespace && writerecoveryconf) 1651 WriteRecoveryConf(); 1652 1653 /* 1654 * No data is synced here, everything is done for all tablespaces at the 1655 * end. 1656 */ 1657 } 1658 1659 /* 1660 * Escape a string so that it can be used as a value in a key-value pair 1661 * a configuration file. 1662 */ 1663 static char * 1664 escape_quotes(const char *src) 1665 { 1666 char *result = escape_single_quotes_ascii(src); 1667 1668 if (!result) 1669 { 1670 pg_log_error("out of memory"); 1671 exit(1); 1672 } 1673 return result; 1674 } 1675 1676 /* 1677 * Create a configuration file in memory using a PQExpBuffer 1678 */ 1679 static void 1680 GenerateRecoveryConf(PGconn *conn) 1681 { 1682 PQconninfoOption *connOptions; 1683 PQconninfoOption *option; 1684 PQExpBufferData conninfo_buf; 1685 char *escaped; 1686 1687 recoveryconfcontents = createPQExpBuffer(); 1688 if (!recoveryconfcontents) 1689 { 1690 pg_log_error("out of memory"); 1691 exit(1); 1692 } 1693 1694 /* 1695 * In PostgreSQL 12 and newer versions, standby_mode is gone, replaced by 1696 * standby.signal to trigger a standby state at recovery. 1697 */ 1698 if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) 1699 appendPQExpBufferStr(recoveryconfcontents, "standby_mode = 'on'\n"); 1700 1701 connOptions = PQconninfo(conn); 1702 if (connOptions == NULL) 1703 { 1704 pg_log_error("out of memory"); 1705 exit(1); 1706 } 1707 1708 initPQExpBuffer(&conninfo_buf); 1709 for (option = connOptions; option && option->keyword; option++) 1710 { 1711 /* Omit empty settings and those libpqwalreceiver overrides. */ 1712 if (strcmp(option->keyword, "replication") == 0 || 1713 strcmp(option->keyword, "dbname") == 0 || 1714 strcmp(option->keyword, "fallback_application_name") == 0 || 1715 (option->val == NULL) || 1716 (option->val != NULL && option->val[0] == '\0')) 1717 continue; 1718 1719 /* Separate key-value pairs with spaces */ 1720 if (conninfo_buf.len != 0) 1721 appendPQExpBufferChar(&conninfo_buf, ' '); 1722 1723 /* 1724 * Write "keyword=value" pieces, the value string is escaped and/or 1725 * quoted if necessary. 1726 */ 1727 appendPQExpBuffer(&conninfo_buf, "%s=", option->keyword); 1728 appendConnStrVal(&conninfo_buf, option->val); 1729 } 1730 1731 /* 1732 * Escape the connection string, so that it can be put in the config file. 1733 * Note that this is different from the escaping of individual connection 1734 * options above! 1735 */ 1736 escaped = escape_quotes(conninfo_buf.data); 1737 appendPQExpBuffer(recoveryconfcontents, "primary_conninfo = '%s'\n", escaped); 1738 free(escaped); 1739 1740 if (replication_slot) 1741 { 1742 /* unescaped: ReplicationSlotValidateName allows [a-z0-9_] only */ 1743 appendPQExpBuffer(recoveryconfcontents, "primary_slot_name = '%s'\n", 1744 replication_slot); 1745 } 1746 1747 if (PQExpBufferBroken(recoveryconfcontents) || 1748 PQExpBufferDataBroken(conninfo_buf)) 1749 { 1750 pg_log_error("out of memory"); 1751 exit(1); 1752 } 1753 1754 termPQExpBuffer(&conninfo_buf); 1755 1756 PQconninfoFree(connOptions); 1757 } 1758 1759 1760 /* 1761 * Write the configuration file into the directory specified in basedir, 1762 * with the contents already collected in memory appended. Then write 1763 * the signal file into the basedir. If the server does not support 1764 * recovery parameters as GUCs, the signal file is not necessary, and 1765 * configuration is written to recovery.conf. 1766 */ 1767 static void 1768 WriteRecoveryConf(void) 1769 { 1770 char filename[MAXPGPATH]; 1771 FILE *cf; 1772 bool is_recovery_guc_supported = true; 1773 1774 if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_RECOVERY_GUC) 1775 is_recovery_guc_supported = false; 1776 1777 snprintf(filename, MAXPGPATH, "%s/%s", basedir, 1778 is_recovery_guc_supported ? "postgresql.auto.conf" : "recovery.conf"); 1779 1780 cf = fopen(filename, is_recovery_guc_supported ? "a" : "w"); 1781 if (cf == NULL) 1782 { 1783 pg_log_error("could not open file \"%s\": %m", filename); 1784 exit(1); 1785 } 1786 1787 if (fwrite(recoveryconfcontents->data, recoveryconfcontents->len, 1, cf) != 1) 1788 { 1789 pg_log_error("could not write to file \"%s\": %m", filename); 1790 exit(1); 1791 } 1792 1793 fclose(cf); 1794 1795 if (is_recovery_guc_supported) 1796 { 1797 snprintf(filename, MAXPGPATH, "%s/%s", basedir, "standby.signal"); 1798 cf = fopen(filename, "w"); 1799 if (cf == NULL) 1800 { 1801 pg_log_error("could not create file \"%s\": %m", filename); 1802 exit(1); 1803 } 1804 1805 fclose(cf); 1806 } 1807 } 1808 1809 1810 static void 1811 BaseBackup(void) 1812 { 1813 PGresult *res; 1814 char *sysidentifier; 1815 TimeLineID latesttli; 1816 TimeLineID starttli; 1817 char *basebkp; 1818 char escaped_label[MAXPGPATH]; 1819 char *maxrate_clause = NULL; 1820 int i; 1821 char xlogstart[64]; 1822 char xlogend[64]; 1823 int minServerMajor, 1824 maxServerMajor; 1825 int serverVersion, 1826 serverMajor; 1827 1828 Assert(conn != NULL); 1829 1830 /* 1831 * Check server version. BASE_BACKUP command was introduced in 9.1, so we 1832 * can't work with servers older than 9.1. 1833 */ 1834 minServerMajor = 901; 1835 maxServerMajor = PG_VERSION_NUM / 100; 1836 serverVersion = PQserverVersion(conn); 1837 serverMajor = serverVersion / 100; 1838 if (serverMajor < minServerMajor || serverMajor > maxServerMajor) 1839 { 1840 const char *serverver = PQparameterStatus(conn, "server_version"); 1841 1842 pg_log_error("incompatible server version %s", 1843 serverver ? serverver : "'unknown'"); 1844 exit(1); 1845 } 1846 1847 /* 1848 * If WAL streaming was requested, also check that the server is new 1849 * enough for that. 1850 */ 1851 if (includewal == STREAM_WAL && !CheckServerVersionForStreaming(conn)) 1852 { 1853 /* 1854 * Error message already written in CheckServerVersionForStreaming(), 1855 * but add a hint about using -X none. 1856 */ 1857 pg_log_info("HINT: use -X none or -X fetch to disable log streaming"); 1858 exit(1); 1859 } 1860 1861 /* 1862 * Build contents of configuration file if requested 1863 */ 1864 if (writerecoveryconf) 1865 GenerateRecoveryConf(conn); 1866 1867 /* 1868 * Run IDENTIFY_SYSTEM so we can get the timeline 1869 */ 1870 if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL)) 1871 exit(1); 1872 1873 /* 1874 * Start the actual backup 1875 */ 1876 PQescapeStringConn(conn, escaped_label, label, sizeof(escaped_label), &i); 1877 1878 if (maxrate > 0) 1879 maxrate_clause = psprintf("MAX_RATE %u", maxrate); 1880 1881 if (verbose) 1882 pg_log_info("initiating base backup, waiting for checkpoint to complete"); 1883 1884 if (showprogress && !verbose) 1885 { 1886 fprintf(stderr, "waiting for checkpoint"); 1887 if (isatty(fileno(stderr))) 1888 fprintf(stderr, "\r"); 1889 else 1890 fprintf(stderr, "\n"); 1891 } 1892 1893 basebkp = 1894 psprintf("BASE_BACKUP LABEL '%s' %s %s %s %s %s %s %s", 1895 escaped_label, 1896 showprogress ? "PROGRESS" : "", 1897 includewal == FETCH_WAL ? "WAL" : "", 1898 fastcheckpoint ? "FAST" : "", 1899 includewal == NO_WAL ? "" : "NOWAIT", 1900 maxrate_clause ? maxrate_clause : "", 1901 format == 't' ? "TABLESPACE_MAP" : "", 1902 verify_checksums ? "" : "NOVERIFY_CHECKSUMS"); 1903 1904 if (PQsendQuery(conn, basebkp) == 0) 1905 { 1906 pg_log_error("could not send replication command \"%s\": %s", 1907 "BASE_BACKUP", PQerrorMessage(conn)); 1908 exit(1); 1909 } 1910 1911 /* 1912 * Get the starting WAL location 1913 */ 1914 res = PQgetResult(conn); 1915 if (PQresultStatus(res) != PGRES_TUPLES_OK) 1916 { 1917 pg_log_error("could not initiate base backup: %s", 1918 PQerrorMessage(conn)); 1919 exit(1); 1920 } 1921 if (PQntuples(res) != 1) 1922 { 1923 pg_log_error("server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields", 1924 PQntuples(res), PQnfields(res), 1, 2); 1925 exit(1); 1926 } 1927 1928 strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart)); 1929 1930 if (verbose) 1931 pg_log_info("checkpoint completed"); 1932 1933 /* 1934 * 9.3 and later sends the TLI of the starting point. With older servers, 1935 * assume it's the same as the latest timeline reported by 1936 * IDENTIFY_SYSTEM. 1937 */ 1938 if (PQnfields(res) >= 2) 1939 starttli = atoi(PQgetvalue(res, 0, 1)); 1940 else 1941 starttli = latesttli; 1942 PQclear(res); 1943 MemSet(xlogend, 0, sizeof(xlogend)); 1944 1945 if (verbose && includewal != NO_WAL) 1946 pg_log_info("write-ahead log start point: %s on timeline %u", 1947 xlogstart, starttli); 1948 1949 /* 1950 * Get the header 1951 */ 1952 res = PQgetResult(conn); 1953 if (PQresultStatus(res) != PGRES_TUPLES_OK) 1954 { 1955 pg_log_error("could not get backup header: %s", 1956 PQerrorMessage(conn)); 1957 exit(1); 1958 } 1959 if (PQntuples(res) < 1) 1960 { 1961 pg_log_error("no data returned from server"); 1962 exit(1); 1963 } 1964 1965 /* 1966 * Sum up the total size, for progress reporting 1967 */ 1968 totalsize = totaldone = 0; 1969 tablespacecount = PQntuples(res); 1970 for (i = 0; i < PQntuples(res); i++) 1971 { 1972 totalsize += atol(PQgetvalue(res, i, 2)); 1973 1974 /* 1975 * Verify tablespace directories are empty. Don't bother with the 1976 * first once since it can be relocated, and it will be checked before 1977 * we do anything anyway. 1978 */ 1979 if (format == 'p' && !PQgetisnull(res, i, 1)) 1980 { 1981 char *path = unconstify(char *, get_tablespace_mapping(PQgetvalue(res, i, 1))); 1982 1983 verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs); 1984 } 1985 } 1986 1987 /* 1988 * When writing to stdout, require a single tablespace 1989 */ 1990 if (format == 't' && strcmp(basedir, "-") == 0 && PQntuples(res) > 1) 1991 { 1992 pg_log_error("can only write single tablespace to stdout, database has %d", 1993 PQntuples(res)); 1994 exit(1); 1995 } 1996 1997 /* 1998 * If we're streaming WAL, start the streaming session before we start 1999 * receiving the actual data chunks. 2000 */ 2001 if (includewal == STREAM_WAL) 2002 { 2003 if (verbose) 2004 pg_log_info("starting background WAL receiver"); 2005 StartLogStreamer(xlogstart, starttli, sysidentifier); 2006 } 2007 2008 /* 2009 * Start receiving chunks 2010 */ 2011 for (i = 0; i < PQntuples(res); i++) 2012 { 2013 if (format == 't') 2014 ReceiveTarFile(conn, res, i); 2015 else 2016 ReceiveAndUnpackTarFile(conn, res, i); 2017 } /* Loop over all tablespaces */ 2018 2019 if (showprogress) 2020 progress_report(PQntuples(res), NULL, true, true); 2021 2022 PQclear(res); 2023 2024 /* 2025 * Get the stop position 2026 */ 2027 res = PQgetResult(conn); 2028 if (PQresultStatus(res) != PGRES_TUPLES_OK) 2029 { 2030 pg_log_error("could not get write-ahead log end position from server: %s", 2031 PQerrorMessage(conn)); 2032 exit(1); 2033 } 2034 if (PQntuples(res) != 1) 2035 { 2036 pg_log_error("no write-ahead log end position returned from server"); 2037 exit(1); 2038 } 2039 strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend)); 2040 if (verbose && includewal != NO_WAL) 2041 pg_log_info("write-ahead log end point: %s", xlogend); 2042 PQclear(res); 2043 2044 res = PQgetResult(conn); 2045 if (PQresultStatus(res) != PGRES_COMMAND_OK) 2046 { 2047 const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE); 2048 2049 if (sqlstate && 2050 strcmp(sqlstate, ERRCODE_DATA_CORRUPTED) == 0) 2051 { 2052 pg_log_error("checksum error occurred"); 2053 checksum_failure = true; 2054 } 2055 else 2056 { 2057 pg_log_error("final receive failed: %s", 2058 PQerrorMessage(conn)); 2059 } 2060 exit(1); 2061 } 2062 2063 if (bgchild > 0) 2064 { 2065 #ifndef WIN32 2066 int status; 2067 pid_t r; 2068 #else 2069 DWORD status; 2070 2071 /* 2072 * get a pointer sized version of bgchild to avoid warnings about 2073 * casting to a different size on WIN64. 2074 */ 2075 intptr_t bgchild_handle = bgchild; 2076 uint32 hi, 2077 lo; 2078 #endif 2079 2080 if (verbose) 2081 pg_log_info("waiting for background process to finish streaming ..."); 2082 2083 #ifndef WIN32 2084 if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend)) 2085 { 2086 pg_log_info("could not send command to background pipe: %m"); 2087 exit(1); 2088 } 2089 2090 /* Just wait for the background process to exit */ 2091 r = waitpid(bgchild, &status, 0); 2092 if (r == (pid_t) -1) 2093 { 2094 pg_log_error("could not wait for child process: %m"); 2095 exit(1); 2096 } 2097 if (r != bgchild) 2098 { 2099 pg_log_error("child %d died, expected %d", (int) r, (int) bgchild); 2100 exit(1); 2101 } 2102 if (status != 0) 2103 { 2104 pg_log_error("%s", wait_result_to_str(status)); 2105 exit(1); 2106 } 2107 /* Exited normally, we're happy! */ 2108 #else /* WIN32 */ 2109 2110 /* 2111 * On Windows, since we are in the same process, we can just store the 2112 * value directly in the variable, and then set the flag that says 2113 * it's there. 2114 */ 2115 if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2) 2116 { 2117 pg_log_error("could not parse write-ahead log location \"%s\"", 2118 xlogend); 2119 exit(1); 2120 } 2121 xlogendptr = ((uint64) hi) << 32 | lo; 2122 InterlockedIncrement(&has_xlogendptr); 2123 2124 /* First wait for the thread to exit */ 2125 if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) != 2126 WAIT_OBJECT_0) 2127 { 2128 _dosmaperr(GetLastError()); 2129 pg_log_error("could not wait for child thread: %m"); 2130 exit(1); 2131 } 2132 if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0) 2133 { 2134 _dosmaperr(GetLastError()); 2135 pg_log_error("could not get child thread exit status: %m"); 2136 exit(1); 2137 } 2138 if (status != 0) 2139 { 2140 pg_log_error("child thread exited with error %u", 2141 (unsigned int) status); 2142 exit(1); 2143 } 2144 /* Exited normally, we're happy */ 2145 #endif 2146 } 2147 2148 /* Free the configuration file contents */ 2149 destroyPQExpBuffer(recoveryconfcontents); 2150 2151 /* 2152 * End of copy data. Final result is already checked inside the loop. 2153 */ 2154 PQclear(res); 2155 PQfinish(conn); 2156 conn = NULL; 2157 2158 /* 2159 * Make data persistent on disk once backup is completed. For tar format 2160 * sync the parent directory and all its contents as each tar file was not 2161 * synced after being completed. In plain format, all the data of the 2162 * base directory is synced, taking into account all the tablespaces. 2163 * Errors are not considered fatal. 2164 */ 2165 if (do_sync) 2166 { 2167 if (verbose) 2168 pg_log_info("syncing data to disk ..."); 2169 if (format == 't') 2170 { 2171 if (strcmp(basedir, "-") != 0) 2172 (void) fsync_dir_recurse(basedir); 2173 } 2174 else 2175 { 2176 (void) fsync_pgdata(basedir, serverVersion); 2177 } 2178 } 2179 2180 if (verbose) 2181 pg_log_info("base backup completed"); 2182 } 2183 2184 2185 int 2186 main(int argc, char **argv) 2187 { 2188 static struct option long_options[] = { 2189 {"help", no_argument, NULL, '?'}, 2190 {"version", no_argument, NULL, 'V'}, 2191 {"pgdata", required_argument, NULL, 'D'}, 2192 {"format", required_argument, NULL, 'F'}, 2193 {"checkpoint", required_argument, NULL, 'c'}, 2194 {"create-slot", no_argument, NULL, 'C'}, 2195 {"max-rate", required_argument, NULL, 'r'}, 2196 {"write-recovery-conf", no_argument, NULL, 'R'}, 2197 {"slot", required_argument, NULL, 'S'}, 2198 {"tablespace-mapping", required_argument, NULL, 'T'}, 2199 {"wal-method", required_argument, NULL, 'X'}, 2200 {"gzip", no_argument, NULL, 'z'}, 2201 {"compress", required_argument, NULL, 'Z'}, 2202 {"label", required_argument, NULL, 'l'}, 2203 {"no-clean", no_argument, NULL, 'n'}, 2204 {"no-sync", no_argument, NULL, 'N'}, 2205 {"dbname", required_argument, NULL, 'd'}, 2206 {"host", required_argument, NULL, 'h'}, 2207 {"port", required_argument, NULL, 'p'}, 2208 {"username", required_argument, NULL, 'U'}, 2209 {"no-password", no_argument, NULL, 'w'}, 2210 {"password", no_argument, NULL, 'W'}, 2211 {"status-interval", required_argument, NULL, 's'}, 2212 {"verbose", no_argument, NULL, 'v'}, 2213 {"progress", no_argument, NULL, 'P'}, 2214 {"waldir", required_argument, NULL, 1}, 2215 {"no-slot", no_argument, NULL, 2}, 2216 {"no-verify-checksums", no_argument, NULL, 3}, 2217 {NULL, 0, NULL, 0} 2218 }; 2219 int c; 2220 2221 int option_index; 2222 2223 pg_logging_init(argv[0]); 2224 progname = get_progname(argv[0]); 2225 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup")); 2226 2227 if (argc > 1) 2228 { 2229 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0) 2230 { 2231 usage(); 2232 exit(0); 2233 } 2234 else if (strcmp(argv[1], "-V") == 0 2235 || strcmp(argv[1], "--version") == 0) 2236 { 2237 puts("pg_basebackup (PostgreSQL) " PG_VERSION); 2238 exit(0); 2239 } 2240 } 2241 2242 atexit(cleanup_directories_atexit); 2243 2244 while ((c = getopt_long(argc, argv, "CD:F:r:RS:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP", 2245 long_options, &option_index)) != -1) 2246 { 2247 switch (c) 2248 { 2249 case 'C': 2250 create_slot = true; 2251 break; 2252 case 'D': 2253 basedir = pg_strdup(optarg); 2254 break; 2255 case 'F': 2256 if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0) 2257 format = 'p'; 2258 else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0) 2259 format = 't'; 2260 else 2261 { 2262 pg_log_error("invalid output format \"%s\", must be \"plain\" or \"tar\"", 2263 optarg); 2264 exit(1); 2265 } 2266 break; 2267 case 'r': 2268 maxrate = parse_max_rate(optarg); 2269 break; 2270 case 'R': 2271 writerecoveryconf = true; 2272 break; 2273 case 'S': 2274 2275 /* 2276 * When specifying replication slot name, use a permanent 2277 * slot. 2278 */ 2279 replication_slot = pg_strdup(optarg); 2280 temp_replication_slot = false; 2281 break; 2282 case 2: 2283 no_slot = true; 2284 break; 2285 case 'T': 2286 tablespace_list_append(optarg); 2287 break; 2288 case 'X': 2289 if (strcmp(optarg, "n") == 0 || 2290 strcmp(optarg, "none") == 0) 2291 { 2292 includewal = NO_WAL; 2293 } 2294 else if (strcmp(optarg, "f") == 0 || 2295 strcmp(optarg, "fetch") == 0) 2296 { 2297 includewal = FETCH_WAL; 2298 } 2299 else if (strcmp(optarg, "s") == 0 || 2300 strcmp(optarg, "stream") == 0) 2301 { 2302 includewal = STREAM_WAL; 2303 } 2304 else 2305 { 2306 pg_log_error("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"", 2307 optarg); 2308 exit(1); 2309 } 2310 break; 2311 case 1: 2312 xlog_dir = pg_strdup(optarg); 2313 break; 2314 case 'l': 2315 label = pg_strdup(optarg); 2316 break; 2317 case 'n': 2318 noclean = true; 2319 break; 2320 case 'N': 2321 do_sync = false; 2322 break; 2323 case 'z': 2324 #ifdef HAVE_LIBZ 2325 compresslevel = Z_DEFAULT_COMPRESSION; 2326 #else 2327 compresslevel = 1; /* will be rejected below */ 2328 #endif 2329 break; 2330 case 'Z': 2331 compresslevel = atoi(optarg); 2332 if (compresslevel < 0 || compresslevel > 9) 2333 { 2334 pg_log_error("invalid compression level \"%s\"", optarg); 2335 exit(1); 2336 } 2337 break; 2338 case 'c': 2339 if (pg_strcasecmp(optarg, "fast") == 0) 2340 fastcheckpoint = true; 2341 else if (pg_strcasecmp(optarg, "spread") == 0) 2342 fastcheckpoint = false; 2343 else 2344 { 2345 pg_log_error("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"", 2346 optarg); 2347 exit(1); 2348 } 2349 break; 2350 case 'd': 2351 connection_string = pg_strdup(optarg); 2352 break; 2353 case 'h': 2354 dbhost = pg_strdup(optarg); 2355 break; 2356 case 'p': 2357 dbport = pg_strdup(optarg); 2358 break; 2359 case 'U': 2360 dbuser = pg_strdup(optarg); 2361 break; 2362 case 'w': 2363 dbgetpassword = -1; 2364 break; 2365 case 'W': 2366 dbgetpassword = 1; 2367 break; 2368 case 's': 2369 standby_message_timeout = atoi(optarg) * 1000; 2370 if (standby_message_timeout < 0) 2371 { 2372 pg_log_error("invalid status interval \"%s\"", optarg); 2373 exit(1); 2374 } 2375 break; 2376 case 'v': 2377 verbose++; 2378 break; 2379 case 'P': 2380 showprogress = true; 2381 break; 2382 case 3: 2383 verify_checksums = false; 2384 break; 2385 default: 2386 2387 /* 2388 * getopt_long already emitted a complaint 2389 */ 2390 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2391 progname); 2392 exit(1); 2393 } 2394 } 2395 2396 /* 2397 * Any non-option arguments? 2398 */ 2399 if (optind < argc) 2400 { 2401 pg_log_error("too many command-line arguments (first is \"%s\")", 2402 argv[optind]); 2403 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2404 progname); 2405 exit(1); 2406 } 2407 2408 /* 2409 * Required arguments 2410 */ 2411 if (basedir == NULL) 2412 { 2413 pg_log_error("no target directory specified"); 2414 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2415 progname); 2416 exit(1); 2417 } 2418 2419 /* 2420 * Mutually exclusive arguments 2421 */ 2422 if (format == 'p' && compresslevel != 0) 2423 { 2424 pg_log_error("only tar mode backups can be compressed"); 2425 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2426 progname); 2427 exit(1); 2428 } 2429 2430 if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0) 2431 { 2432 pg_log_error("cannot stream write-ahead logs in tar mode to stdout"); 2433 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2434 progname); 2435 exit(1); 2436 } 2437 2438 if (replication_slot && includewal != STREAM_WAL) 2439 { 2440 pg_log_error("replication slots can only be used with WAL streaming"); 2441 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2442 progname); 2443 exit(1); 2444 } 2445 2446 if (no_slot) 2447 { 2448 if (replication_slot) 2449 { 2450 pg_log_error("--no-slot cannot be used with slot name"); 2451 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2452 progname); 2453 exit(1); 2454 } 2455 temp_replication_slot = false; 2456 } 2457 2458 if (create_slot) 2459 { 2460 if (!replication_slot) 2461 { 2462 pg_log_error("%s needs a slot to be specified using --slot", 2463 "--create-slot"); 2464 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2465 progname); 2466 exit(1); 2467 } 2468 2469 if (no_slot) 2470 { 2471 pg_log_error("--create-slot and --no-slot are incompatible options"); 2472 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2473 progname); 2474 exit(1); 2475 } 2476 } 2477 2478 if (xlog_dir) 2479 { 2480 if (format != 'p') 2481 { 2482 pg_log_error("WAL directory location can only be specified in plain mode"); 2483 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2484 progname); 2485 exit(1); 2486 } 2487 2488 /* clean up xlog directory name, check it's absolute */ 2489 canonicalize_path(xlog_dir); 2490 if (!is_absolute_path(xlog_dir)) 2491 { 2492 pg_log_error("WAL directory location must be an absolute path"); 2493 fprintf(stderr, _("Try \"%s --help\" for more information.\n"), 2494 progname); 2495 exit(1); 2496 } 2497 } 2498 2499 #ifndef HAVE_LIBZ 2500 if (compresslevel != 0) 2501 { 2502 pg_log_error("this build does not support compression"); 2503 exit(1); 2504 } 2505 #endif 2506 2507 /* connection in replication mode to server */ 2508 conn = GetConnection(); 2509 if (!conn) 2510 { 2511 /* Error message already written in GetConnection() */ 2512 exit(1); 2513 } 2514 atexit(disconnect_atexit); 2515 2516 /* 2517 * Set umask so that directories/files are created with the same 2518 * permissions as directories/files in the source data directory. 2519 * 2520 * pg_mode_mask is set to owner-only by default and then updated in 2521 * GetConnection() where we get the mode from the server-side with 2522 * RetrieveDataDirCreatePerm() and then call SetDataDirectoryCreatePerm(). 2523 */ 2524 umask(pg_mode_mask); 2525 2526 /* 2527 * Verify that the target directory exists, or create it. For plaintext 2528 * backups, always require the directory. For tar backups, require it 2529 * unless we are writing to stdout. 2530 */ 2531 if (format == 'p' || strcmp(basedir, "-") != 0) 2532 verify_dir_is_empty_or_create(basedir, &made_new_pgdata, &found_existing_pgdata); 2533 2534 /* determine remote server's xlog segment size */ 2535 if (!RetrieveWalSegSize(conn)) 2536 exit(1); 2537 2538 /* Create pg_wal symlink, if required */ 2539 if (xlog_dir) 2540 { 2541 char *linkloc; 2542 2543 verify_dir_is_empty_or_create(xlog_dir, &made_new_xlogdir, &found_existing_xlogdir); 2544 2545 /* 2546 * Form name of the place where the symlink must go. pg_xlog has been 2547 * renamed to pg_wal in post-10 clusters. 2548 */ 2549 linkloc = psprintf("%s/%s", basedir, 2550 PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ? 2551 "pg_xlog" : "pg_wal"); 2552 2553 #ifdef HAVE_SYMLINK 2554 if (symlink(xlog_dir, linkloc) != 0) 2555 { 2556 pg_log_error("could not create symbolic link \"%s\": %m", linkloc); 2557 exit(1); 2558 } 2559 #else 2560 pg_log_error("symlinks are not supported on this platform"); 2561 exit(1); 2562 #endif 2563 free(linkloc); 2564 } 2565 2566 BaseBackup(); 2567 2568 success = true; 2569 return 0; 2570 } 2571