41#define ERRCODE_DATA_CORRUPTED "XX001"
86#define MINIMUM_VERSION_FOR_PG_WAL 100000
91#define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
96#define MINIMUM_VERSION_FOR_MANIFESTS 130000
102#define MINIMUM_VERSION_FOR_TERMINATED_TARFILE 150000
107#define MINIMUM_VERSION_FOR_WAL_SUMMARIES 170000
134static char *
label =
"pg_basebackup base backup";
197static void usage(
void);
200static void progress_report(
int tablespacenum,
bool force,
bool finished);
204 bool is_recovery_guc_supported,
205 bool expect_unterminated_tarfile,
208 void *callback_data);
219 void *callback_data);
222 void *callback_data);
226 char *incremental_manifest);
229 bool segment_finished);
253 pg_log_error(
"failed to remove contents of data directory");
266 pg_log_error(
"failed to remove contents of WAL directory");
279 pg_log_info(
"changes to tablespace directories will not be undone");
328 for (arg_ptr =
arg; *arg_ptr; arg_ptr++)
331 pg_fatal(
"directory name too long");
333 if (*arg_ptr ==
'\\' && *(arg_ptr + 1) ==
'=')
335 else if (*arg_ptr ==
'=' && (arg_ptr ==
arg || *(arg_ptr - 1) !=
'\\'))
338 pg_fatal(
"multiple \"=\" signs in tablespace mapping");
343 *dst_ptr++ = *arg_ptr;
347 pg_fatal(
"invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"",
arg);
366 pg_fatal(
"old directory is not an absolute path in tablespace mapping: %s",
370 pg_fatal(
"new directory is not an absolute path in tablespace mapping: %s",
392 printf(
_(
"%s takes a base backup of a running PostgreSQL server.\n\n"),
396 printf(
_(
"\nOptions controlling the output:\n"));
397 printf(
_(
" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
398 printf(
_(
" -F, --format=p|t output format (plain (default), tar)\n"));
399 printf(
_(
" -i, --incremental=OLDMANIFEST\n"
400 " take incremental backup\n"));
401 printf(
_(
" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
402 " (in kB/s, or use suffix \"k\" or \"M\")\n"));
403 printf(
_(
" -R, --write-recovery-conf\n"
404 " write configuration for replication\n"));
405 printf(
_(
" -t, --target=TARGET[:DETAIL]\n"
406 " backup target (if other than client)\n"));
407 printf(
_(
" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
408 " relocate tablespace in OLDDIR to NEWDIR\n"));
409 printf(
_(
" --waldir=WALDIR location for the write-ahead log directory\n"));
410 printf(
_(
" -X, --wal-method=none|fetch|stream\n"
411 " include required WAL files with specified method\n"));
412 printf(
_(
" -z, --gzip compress tar output\n"));
413 printf(
_(
" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
414 " compress on client or server as specified\n"));
415 printf(
_(
" -Z, --compress=none do not compress tar output\n"));
416 printf(
_(
"\nGeneral options:\n"));
417 printf(
_(
" -c, --checkpoint=fast|spread\n"
418 " set fast or spread (default) checkpointing\n"));
419 printf(
_(
" -C, --create-slot create replication slot\n"));
420 printf(
_(
" -l, --label=LABEL set backup label\n"));
421 printf(
_(
" -n, --no-clean do not clean up after errors\n"));
422 printf(
_(
" -N, --no-sync do not wait for changes to be written safely to disk\n"));
423 printf(
_(
" -P, --progress show progress information\n"));
424 printf(
_(
" -S, --slot=SLOTNAME replication slot to use\n"));
425 printf(
_(
" -v, --verbose output verbose messages\n"));
426 printf(
_(
" -V, --version output version information, then exit\n"));
427 printf(
_(
" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
428 " use algorithm for manifest checksums\n"));
429 printf(
_(
" --manifest-force-encode\n"
430 " hex encode all file names in manifest\n"));
431 printf(
_(
" --no-estimate-size do not estimate backup size in server side\n"));
432 printf(
_(
" --no-manifest suppress generation of backup manifest\n"));
433 printf(
_(
" --no-slot prevent creation of temporary replication slot\n"));
434 printf(
_(
" --no-verify-checksums\n"
435 " do not verify checksums\n"));
436 printf(
_(
" --sync-method=METHOD\n"
437 " set method for syncing files to disk\n"));
438 printf(
_(
" -?, --help show this help, then exit\n"));
439 printf(
_(
"\nConnection options:\n"));
440 printf(
_(
" -d, --dbname=CONNSTR connection string\n"));
441 printf(
_(
" -h, --host=HOSTNAME database server host or socket directory\n"));
442 printf(
_(
" -p, --port=PORT database server port number\n"));
443 printf(
_(
" -s, --status-interval=INTERVAL\n"
444 " time between status packets sent to server (in seconds)\n"));
445 printf(
_(
" -U, --username=NAME connect as specified database user\n"));
446 printf(
_(
" -w, --no-password never prompt for password\n"));
447 printf(
_(
" -W, --password force password prompt (should happen automatically)\n"));
448 printf(
_(
"\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
449 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
463 bool segment_finished)
469 struct timeval tv = {0};
482 char xlogend[64] = {0};
486 r =
read(
bgpipe[0], xlogend,
sizeof(xlogend) - 1);
488 pg_fatal(
"could not read from ready pipe: %m");
490 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
491 pg_fatal(
"could not parse write-ahead log location \"%s\"",
618 int wal_compress_level)
632 if (sscanf(
startpos,
"%X/%X", &hi, &lo) != 2)
633 pg_fatal(
"could not parse write-ahead log location \"%s\"",
642 pg_fatal(
"could not create pipe for background process: %m");
655 "pg_xlog" :
"pg_wal");
677 pg_log_info(
"created temporary replication slot \"%s\"",
693 snprintf(statusdir,
sizeof(statusdir),
"%s/%s/archive_status",
696 "pg_xlog" :
"pg_wal");
699 pg_fatal(
"could not create directory \"%s\": %m", statusdir);
708 snprintf(summarydir,
sizeof(summarydir),
"%s/%s/summaries",
713 pg_fatal(
"could not create directory \"%s\": %m", summarydir);
729 pg_fatal(
"could not create background process: %m");
738 pg_fatal(
"could not create background thread: %m");
758 pg_fatal(
"could not create directory \"%s\": %m", dirname);
777 pg_fatal(
"directory \"%s\" exists but is not empty", dirname);
783 pg_fatal(
"could not access directory \"%s\": %m", dirname);
820 char totaldone_str[32];
821 char totalsize_str[32];
849#define VERBOSE_FILENAME_LENGTH 35
859 ngettext(
"%*s/%s kB (100%%), %d/%d tablespace %*s",
860 "%*s/%s kB (100%%), %d/%d tablespaces %*s",
862 (
int) strlen(totalsize_str),
863 totaldone_str, totalsize_str,
871 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
872 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
874 (
int) strlen(totalsize_str),
875 totaldone_str, totalsize_str, percent,
878 truncate ?
"..." :
"",
887 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace",
888 "%*s/%s kB (%d%%), %d/%d tablespaces",
890 (
int) strlen(totalsize_str),
891 totaldone_str, totalsize_str, percent,
898 fputc((!finished && isatty(fileno(stderr))) ?
'\r' :
'\n', stderr);
909 result = strtod(src, &after_num);
910 if (src == after_num)
911 pg_fatal(
"transfer rate \"%s\" is not a valid value", src);
913 pg_fatal(
"invalid transfer rate \"%s\": %m", src);
920 pg_fatal(
"transfer rate must be greater than zero");
927 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
930 if (*after_num !=
'\0')
933 if (*after_num ==
'k')
938 else if (*after_num ==
'M')
946 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
949 if (*after_num !=
'\0')
950 pg_fatal(
"invalid --max-rate unit: \"%s\"", suffix);
954 pg_fatal(
"transfer rate \"%s\" exceeds integer range", src);
961 pg_fatal(
"transfer rate \"%s\" is out of range", src);
963 return (
int32) result;
993 if (strncmp(
option,
"server-", 7) == 0)
998 else if (strncmp(
option,
"client-", 7) == 0)
1016 void *callback_data)
1023 pg_fatal(
"could not get COPY data stream: %s",
1040 pg_fatal(
"could not read COPY data: %s",
1044 pg_fatal(
"background process terminated unexpectedly");
1046 (*callback) (r,
copybuf, callback_data);
1064 bool is_recovery_guc_supported,
1065 bool expect_unterminated_tarfile,
1069 astreamer *manifest_inject_streamer = NULL;
1070 bool inject_manifest;
1076 bool must_parse_archive;
1077 int archive_name_len = strlen(archive_name);
1087 is_tar = (archive_name_len > 4 &&
1088 strcmp(archive_name + archive_name_len - 4,
".tar") == 0);
1091 is_tar_gz = (archive_name_len > 7 &&
1092 strcmp(archive_name + archive_name_len - 7,
".tar.gz") == 0);
1095 is_tar_lz4 = (archive_name_len > 8 &&
1096 strcmp(archive_name + archive_name_len - 8,
".tar.lz4") == 0);
1099 is_tar_zstd = (archive_name_len > 8 &&
1100 strcmp(archive_name + archive_name_len - 8,
".tar.zst") == 0);
1103 is_compressed_tar = is_tar_gz || is_tar_lz4 || is_tar_zstd;
1113 if (inject_manifest && is_compressed_tar)
1115 pg_log_error(
"cannot inject manifest into a compressed tar file");
1116 pg_log_error_hint(
"Use client-side compression, send the output to a directory rather than standard output, or use %s.",
1126 must_parse_archive = (
format ==
'p' || inject_manifest ||
1130 if (must_parse_archive && !is_tar && !is_compressed_tar)
1132 pg_log_error(
"cannot parse archive \"%s\"", archive_name);
1136 if (inject_manifest)
1137 pg_log_error_detail(
"Using - as the output directory requires pg_basebackup to parse the archive.");
1158 if (spclocation == NULL)
1179 if (strcmp(
basedir,
"-") == 0)
1181 snprintf(archive_filename,
sizeof(archive_filename),
"-");
1186 snprintf(archive_filename,
sizeof(archive_filename),
1187 "%s/%s",
basedir, archive_name);
1188 archive_file = NULL;
1196 strlcat(archive_filename,
".gz",
sizeof(archive_filename));
1198 archive_file, compress);
1202 strlcat(archive_filename,
".lz4",
sizeof(archive_filename));
1209 strlcat(archive_filename,
".zst",
sizeof(archive_filename));
1225 if (must_parse_archive)
1235 if (inject_manifest)
1236 manifest_inject_streamer = streamer;
1244 Assert(must_parse_archive);
1246 is_recovery_guc_supported,
1256 if (must_parse_archive)
1258 else if (expect_unterminated_tarfile)
1269 else if (is_tar_lz4)
1271 else if (is_tar_zstd)
1276 *manifest_inject_streamer_p = manifest_inject_streamer;
1291 state.tablespacenum = -1;
1292 state.compress = compress;
1298 if (
state.manifest_file !=NULL)
1300 fclose(
state.manifest_file);
1301 state.manifest_file = NULL;
1308 if (
state.manifest_inject_streamer != NULL &&
1309 state.manifest_buffer != NULL)
1313 state.manifest_buffer->data,
1314 state.manifest_buffer->len);
1316 state.manifest_buffer = NULL;
1320 if (
state.streamer != NULL)
1324 state.streamer = NULL;
1352 if (++
state->tablespacenum > 0)
1356 if (
state->manifest_buffer != NULL ||
1357 state->manifest_file !=NULL)
1358 pg_fatal(
"archives must precede manifest");
1370 if (archive_name[0] ==
'\0' || archive_name[0] ==
'.' ||
1371 strchr(archive_name,
'/') != NULL ||
1372 strchr(archive_name,
'\\') != NULL)
1373 pg_fatal(
"invalid archive name: \"%s\"",
1381 if (spclocation[0] ==
'\0')
1385 if (
state->streamer != NULL)
1389 state->streamer = NULL;
1406 &
state->manifest_inject_streamer,
1416 if (
state->manifest_buffer != NULL)
1422 else if (
state->manifest_file !=NULL)
1425 if (fwrite(
copybuf + 1, r - 1, 1,
1426 state->manifest_file) != 1)
1434 pg_fatal(
"could not write to file \"%s\": %m",
1435 state->manifest_filename);
1438 else if (
state->streamer != NULL)
1445 pg_fatal(
"unexpected payload data");
1488 if (
state->manifest_inject_streamer != NULL)
1493 sizeof(
state->manifest_filename),
1494 "%s/backup_manifest.tmp",
basedir);
1495 state->manifest_file =
1496 fopen(
state->manifest_filename,
"wb");
1497 if (
state->manifest_file == NULL)
1498 pg_fatal(
"could not create file \"%s\": %m",
1499 state->manifest_filename);
1590 pg_fatal(
"malformed COPY message of type %d, length %zu",
1605 bool is_recovery_guc_supported;
1606 bool expect_unterminated_tarfile;
1610 is_recovery_guc_supported =
1612 expect_unterminated_tarfile =
1615 &manifest_inject_streamer,
1616 is_recovery_guc_supported,
1617 expect_unterminated_tarfile,
1619 state.tablespacenum = tablespacenum;
1629 if (manifest_inject_streamer != NULL)
1685 strlcpy(canon_dir, dir,
sizeof(canon_dir));
1689 if (strcmp(canon_dir, cell->
old_dir) == 0)
1704 "%s/backup_manifest.tmp",
basedir);
1706 if (
state.file == NULL)
1707 pg_fatal(
"could not create file \"%s\": %m",
state.filename);
1728 pg_fatal(
"could not write to file \"%s\": %m",
state->filename);
1746 void *callback_data)
1757 char *incremental_manifest)
1760 char *sysidentifier;
1766 char xlogend[64] = {0};
1771 int writing_to_stdout;
1772 bool use_new_option_syntax =
false;
1782 minServerMajor = 901;
1783 maxServerMajor = PG_VERSION_NUM / 100;
1785 serverMajor = serverVersion / 100;
1786 if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1790 pg_fatal(
"incompatible server version %s",
1791 serverver ? serverver :
"'unknown'");
1793 if (serverMajor >= 1500)
1794 use_new_option_syntax =
true;
1834 if (incremental_manifest != NULL)
1842 pg_fatal(
"server does not support incremental backup");
1845 fd = open(incremental_manifest, O_RDONLY |
PG_BINARY, 0);
1847 pg_fatal(
"could not open file \"%s\": %m", incremental_manifest);
1851 pg_fatal(
"could not send replication command \"%s\": %s",
1857 pg_fatal(
"could not upload manifest: %s",
1860 pg_fatal(
"could not upload manifest: unexpected status %s",
1865 while ((nbytes =
read(
fd, mbuf,
sizeof mbuf)) > 0)
1868 pg_fatal(
"could not send COPY data: %s",
1874 pg_fatal(
"could not read file \"%s\": %m", incremental_manifest);
1878 pg_fatal(
"could not send end-of-COPY: %s",
1884 pg_fatal(
"could not upload manifest: %s",
1887 pg_fatal(
"could not upload manifest: unexpected status %s",
1893 pg_fatal(
"unexpected extra result while sending manifest");
1909 if (use_new_option_syntax)
1911 "CHECKPOINT",
"fast");
1917 if (use_new_option_syntax)
1929 if (use_new_option_syntax)
1931 "VERIFY_CHECKSUMS", 0);
1934 "NOVERIFY_CHECKSUMS");
1950 if (serverMajor < 1500)
1951 pg_fatal(
"backup targets are not supported by this server version");
1954 pg_fatal(
"recovery configuration cannot be written when a backup target is used");
1971 "TARGET_DETAIL",
colon + 1);
1974 else if (serverMajor >= 1500)
1976 "TARGET",
"client");
1980 if (!use_new_option_syntax)
1981 pg_fatal(
"server does not support server-side compression");
1984 if (compression_detail != NULL)
1986 "COMPRESSION_DETAIL",
1987 compression_detail);
1991 pg_log_info(
"initiating base backup, waiting for checkpoint to complete");
1995 fprintf(stderr,
_(
"waiting for checkpoint"));
1996 if (isatty(fileno(stderr)))
2002 if (use_new_option_syntax &&
buf.len > 0)
2009 pg_fatal(
"could not send replication command \"%s\": %s",
2017 pg_fatal(
"could not initiate base backup: %s",
2020 pg_fatal(
"server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
2036 starttli = latesttli;
2040 pg_log_info(
"write-ahead log start point: %s on timeline %u",
2041 xlogstart, starttli);
2048 pg_fatal(
"could not get backup header: %s",
2051 pg_fatal(
"no data returned from server");
2093 if (writing_to_stdout &&
PQntuples(res) > 1)
2094 pg_fatal(
"can only write single tablespace to stdout, database has %d",
2104 int wal_compress_level;
2112 wal_compress_level = client_compress->
level;
2117 wal_compress_level = 0;
2121 wal_compress_algorithm,
2122 wal_compress_level);
2125 if (serverMajor >= 1500)
2148 strlcpy(archive_name,
"base.tar",
sizeof(archive_name));
2153 snprintf(archive_name,
sizeof(archive_name),
2173 if (!writing_to_stdout &&
manifest)
2193 pg_fatal(
"no write-ahead log end position returned from server");
2196 pg_log_info(
"write-ahead log end point: %s", xlogend);
2230 intptr_t bgchild_handle =
bgchild;
2236 pg_log_info(
"waiting for background process to finish streaming ...");
2239 if (
write(
bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2240 pg_fatal(
"could not send command to background pipe: %m");
2243 r = waitpid(
bgchild, &status, 0);
2244 if (r == (pid_t) -1)
2245 pg_fatal(
"could not wait for child process: %m");
2258 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
2259 pg_fatal(
"could not parse write-ahead log location \"%s\"",
2265 if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2269 pg_fatal(
"could not wait for child thread: %m");
2271 if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2274 pg_fatal(
"could not get child thread exit status: %m");
2277 pg_fatal(
"child thread exited with error %u",
2278 (
unsigned int) status);
2309 if (strcmp(
basedir,
"-") != 0)
2331 pg_log_info(
"renaming backup_manifest.tmp to backup_manifest");
2344 if (rename(tmp_filename,
filename) != 0)
2345 pg_fatal(
"could not rename file \"%s\" to \"%s\": %m",
2358 static struct option long_options[] = {
2400 char *compression_detail = NULL;
2401 char *incremental_manifest = NULL;
2411 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
2416 else if (strcmp(argv[1],
"-V") == 0
2417 || strcmp(argv[1],
"--version") == 0)
2419 puts(
"pg_basebackup (PostgreSQL) " PG_VERSION);
2426 while ((
c =
getopt_long(argc, argv,
"c:Cd:D:F:h:i:l:nNp:Pr:Rs:S:t:T:U:vwWX:zZ:",
2427 long_options, &option_index)) != -1)
2437 pg_fatal(
"invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2450 if (strcmp(
optarg,
"p") == 0 || strcmp(
optarg,
"plain") == 0)
2452 else if (strcmp(
optarg,
"t") == 0 || strcmp(
optarg,
"tar") == 0)
2455 pg_fatal(
"invalid output format \"%s\", must be \"plain\" or \"tar\"",
2520 if (strcmp(
optarg,
"n") == 0 ||
2521 strcmp(
optarg,
"none") == 0)
2525 else if (strcmp(
optarg,
"f") == 0 ||
2526 strcmp(
optarg,
"fetch") == 0)
2530 else if (strcmp(
optarg,
"s") == 0 ||
2531 strcmp(
optarg,
"stream") == 0)
2536 pg_fatal(
"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2541 compression_detail = NULL;
2546 &compression_detail, &compressloc);
2585 pg_log_error(
"too many command-line arguments (first is \"%s\")",
2608 pg_log_error(
"cannot specify both format and backup target");
2620 pg_log_error(
"must specify output directory or backup target");
2626 pg_log_error(
"cannot specify both output directory and backup target");
2656 pg_fatal(
"unrecognized compression algorithm: \"%s\"",
2661 if (error_detail != NULL)
2662 pg_fatal(
"invalid compression specification: %s",
2678 pg_log_error(
"client-side compression is not possible when a backup target is specified");
2689 pg_log_error(
"only tar mode backups can be compressed");
2699 pg_log_error(
"WAL cannot be streamed when a backup target is specified");
2705 pg_log_error(
"cannot stream write-ahead logs in tar mode to stdout");
2712 pg_log_error(
"replication slots can only be used with WAL streaming");
2724 pg_log_error(
"--no-slot cannot be used with slot name");
2735 pg_log_error(
"%s needs a slot to be specified using --slot",
2744 "--create-slot",
"--no-slot");
2757 pg_log_error(
"WAL directory location cannot be specified along with a backup target");
2763 pg_log_error(
"WAL directory location can only be specified in plain mode");
2772 pg_log_error(
"WAL directory location must be an absolute path");
2784 "--progress",
"--no-estimate-size");
2795 "--no-manifest",
"--manifest-checksums");
2803 "--no-manifest",
"--manifest-force-encode");
2869 "pg_xlog" :
"pg_wal");
2872 pg_fatal(
"could not create symbolic link \"%s\": %m", linkloc);
2877 &client_compress, incremental_manifest);
static void astreamer_free(astreamer *streamer)
static void astreamer_content(astreamer *streamer, astreamer_member *member, const char *data, int len, astreamer_archive_context context)
static void astreamer_finalize(astreamer *streamer)
astreamer * astreamer_plain_writer_new(char *pathname, FILE *file)
astreamer * astreamer_extractor_new(const char *basepath, const char *(*link_map)(const char *), void(*report_output_file)(const char *))
astreamer * astreamer_gzip_decompressor_new(astreamer *next)
astreamer * astreamer_gzip_writer_new(char *pathname, FILE *file, pg_compress_specification *compress)
astreamer * astreamer_recovery_injector_new(astreamer *next, bool is_recovery_guc_supported, PQExpBuffer recoveryconfcontents)
void astreamer_inject_file(astreamer *streamer, char *pathname, char *data, int len)
astreamer * astreamer_lz4_compressor_new(astreamer *next, pg_compress_specification *compress)
astreamer * astreamer_lz4_decompressor_new(astreamer *next)
astreamer * astreamer_tar_parser_new(astreamer *next)
astreamer * astreamer_tar_terminator_new(astreamer *next)
astreamer * astreamer_tar_archiver_new(astreamer *next)
astreamer * astreamer_zstd_compressor_new(astreamer *next, pg_compress_specification *compress)
astreamer * astreamer_zstd_decompressor_new(astreamer *next)
Datum now(PG_FUNCTION_ARGS)
#define unconstify(underlying_type, expr)
#define ngettext(s, p, n)
#define PG_TEXTDOMAIN(domain)
void set_pglocale_pgservice(const char *argv0, const char *app)
char * validate_compress_specification(pg_compress_specification *spec)
bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm)
void parse_compress_specification(pg_compress_algorithm algorithm, char *specification, pg_compress_specification *result)
void parse_compress_options(const char *option, char **algorithm, char **detail)
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
#define fprintf(file, fmt, msg)
int durable_rename(const char *oldfile, const char *newfile, int elevel)
int PQserverVersion(const PGconn *conn)
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
void PQfinish(PGconn *conn)
int PQbackendPID(const PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
void PQfreemem(void *ptr)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
PGresult * PQgetResult(PGconn *conn)
ExecStatusType PQresultStatus(const PGresult *res)
void PQclear(PGresult *res)
int PQputCopyEnd(PGconn *conn, const char *errormsg)
int PQntuples(const PGresult *res)
int PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
char * PQresultErrorField(const PGresult *res, int fieldcode)
int PQsendQuery(PGconn *conn, const char *query)
char * PQresStatus(ExecStatusType status)
int PQnfields(const PGresult *res)
int PQgetCopyData(PGconn *conn, char **buffer, int async)
char * pg_strdup(const char *in)
void * pg_malloc0(size_t size)
@ DATA_DIR_SYNC_METHOD_FSYNC
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
#define required_argument
Assert(PointerIsAligned(start, uint64))
void pg_logging_init(const char *argv0)
#define pg_log_error(...)
#define pg_log_error_hint(...)
#define pg_log_error_detail(...)
char * pnstrdup(const char *in, Size len)
bool option_parse_int(const char *optarg, const char *optname, int min_range, int max_range, int *result)
bool parse_sync_method(const char *optarg, DataDirSyncMethod *sync_method)
static void BaseBackup(char *compression_algorithm, char *compression_detail, CompressionLocation compressloc, pg_compress_specification *client_compress, char *incremental_manifest)
static void ReceiveArchiveStreamChunk(size_t r, char *copybuf, void *callback_data)
static bool checksum_failure
void(* WriteDataCallback)(size_t nbytes, char *buf, void *callback_data)
static bool found_existing_pgdata
static bool found_existing_xlogdir
#define MINIMUM_VERSION_FOR_TEMP_SLOTS
static void ReceiveTarFile(PGconn *conn, char *archive_name, char *spclocation, bool tablespacenum, pg_compress_specification *compress)
static char * backup_target
static void ReceiveCopyData(PGconn *conn, WriteDataCallback callback, void *callback_data)
static void StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier, pg_compress_algorithm wal_compress_algorithm, int wal_compress_level)
static void ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
int main(int argc, char **argv)
static char * GetCopyDataString(size_t r, char *copybuf, size_t *cursor)
static int32 parse_max_rate(char *src)
static volatile sig_atomic_t bgchild_exited
static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
static int LogStreamerMain(logstreamer_param *param)
static void ReceiveArchiveStream(PGconn *conn, pg_compress_specification *compress)
static void backup_parse_compress_options(char *option, char **algorithm, char **detail, CompressionLocation *locationres)
static PQExpBuffer recoveryconfcontents
static int tablespacecount
static void progress_update_filename(const char *filename)
@ COMPRESS_LOCATION_UNSPECIFIED
@ COMPRESS_LOCATION_CLIENT
@ COMPRESS_LOCATION_SERVER
static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finished)
static int has_xlogendptr
static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
static char * progress_filename
static uint64 totalsize_kb
struct WriteTarState WriteTarState
static pg_time_t last_progress_report
static bool verify_checksums
static char * replication_slot
static void GetCopyDataEnd(size_t r, char *copybuf, size_t cursor)
static void ReceiveBackupManifest(PGconn *conn)
static void progress_report(int tablespacenum, bool force, bool finished)
static bool manifest_force_encode
static char * manifest_checksums
static astreamer * CreateBackupStreamer(char *archive_name, char *spclocation, astreamer **manifest_inject_streamer_p, bool is_recovery_guc_supported, bool expect_unterminated_tarfile, pg_compress_specification *compress)
#define MINIMUM_VERSION_FOR_TERMINATED_TARFILE
static TablespaceList tablespace_dirs
static bool found_tablespace_dirs
static bool in_log_streamer
static bool made_new_xlogdir
struct TablespaceList TablespaceList
static IncludeWal includewal
static void ReportCopyDataParseError(size_t r, char *copybuf)
struct ArchiveStreamState ArchiveStreamState
static bool writerecoveryconf
static void cleanup_directories_atexit(void)
static bool temp_replication_slot
#define MINIMUM_VERSION_FOR_MANIFESTS
static bool made_tablespace_dirs
static char GetCopyDataByte(size_t r, char *copybuf, size_t *cursor)
#define VERBOSE_FILENAME_LENGTH
static uint64 GetCopyDataUInt64(size_t r, char *copybuf, size_t *cursor)
static bool fastcheckpoint
struct WriteManifestState WriteManifestState
static bool made_new_pgdata
static void kill_bgchild_atexit(void)
static DataDirSyncMethod sync_method
struct TablespaceListCell TablespaceListCell
#define ERRCODE_DATA_CORRUPTED
static void ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf, void *callback_data)
static void tablespace_list_append(const char *arg)
static const char * get_tablespace_mapping(const char *dir)
static void disconnect_atexit(void)
static void ReceiveBackupManifestInMemory(PGconn *conn, PQExpBuffer buf)
static XLogRecPtr xlogendptr
#define MINIMUM_VERSION_FOR_PG_WAL
static int standby_message_timeout
#define MINIMUM_VERSION_FOR_WAL_SUMMARIES
static void sigchld_handler(SIGNAL_ARGS)
PGDLLIMPORT char * optarg
static pg_compress_algorithm compression_algorithm
static XLogRecPtr startpos
int pg_mkdir_p(char *path, int omode)
#define is_absolute_path(filename)
int pg_strcasecmp(const char *s1, const char *s2)
void canonicalize_path(char *path)
int pg_check_dir(const char *dir)
const char * get_progname(const char *argv0)
#define is_windows_absolute_path(filename)
size_t strlcat(char *dst, const char *src, size_t siz)
size_t strlcpy(char *dst, const char *src, size_t siz)
#define is_nonwindows_absolute_path(filename)
PQExpBuffer createPQExpBuffer(void)
void initPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void termPQExpBuffer(PQExpBuffer str)
#define PQExpBufferDataBroken(buf)
static int fd(const char *x, int i)
char * psprintf(const char *fmt,...)
bool ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
bool CheckServerVersionForStreaming(PGconn *conn)
PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, const char *replication_slot, char *dbname)
char * GetDbnameFromConnectionOptions(const char *connstr)
#define MINIMUM_VERSION_FOR_RECOVERY_GUC
bool rmtree(const char *path, bool rmtopdir)
void AppendIntegerCommandOption(PQExpBuffer buf, bool use_new_option_syntax, char *option_name, int32 option_value)
bool RetrieveWalSegSize(PGconn *conn)
void AppendPlainCommandOption(PQExpBuffer buf, bool use_new_option_syntax, char *option_name)
void AppendStringCommandOption(PQExpBuffer buf, bool use_new_option_syntax, char *option_name, char *option_value)
bool RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli, XLogRecPtr *startpos, char **db_name)
char manifest_filename[MAXPGPATH]
pg_compress_specification * compress
astreamer * manifest_inject_streamer
PQExpBuffer manifest_buffer
stream_stop_callback stream_stop
int standby_message_timeout
WalWriteMethod * walmethod
struct TablespaceListCell * next
TablespaceListCell * tail
TablespaceListCell * head
void(* free)(WalWriteMethod *wwmethod)
bool(* finish)(WalWriteMethod *wwmethod)
const WalWriteMethodOps * ops
pg_compress_algorithm wal_compress_algorithm
pg_compress_algorithm algorithm
static StringInfo copybuf
static void callback(struct sockaddr *addr, struct sockaddr *mask, void *unused)
char * wait_result_to_str(int exitstatus)
WalWriteMethod * CreateWalTarMethod(const char *tarbase, pg_compress_algorithm compression_algorithm, int compression_level, bool sync)
WalWriteMethod * CreateWalDirectoryMethod(const char *basedir, pg_compress_algorithm compression_algorithm, int compression_level, bool sync)
static void CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
void _dosmaperr(unsigned long)
#define symlink(oldpath, newpath)
#define select(n, r, w, e, timeout)
#define XLogSegmentOffset(xlogptr, wal_segsz_bytes)
static const char * directory