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
134 static char *
label =
"pg_basebackup base backup";
197 static void usage(
void);
200 static 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\"",
635 param->
startptr = ((uint64) hi) << 32 | lo;
642 pg_fatal(
"could not create pipe for background process: %m");
655 "pg_xlog" :
"pg_wal");
676 pg_log_info(
"created temporary replication slot \"%s\"",
692 snprintf(statusdir,
sizeof(statusdir),
"%s/%s/archive_status",
695 "pg_xlog" :
"pg_wal");
698 pg_fatal(
"could not create directory \"%s\": %m", statusdir);
707 snprintf(summarydir,
sizeof(summarydir),
"%s/%s/summaries",
712 pg_fatal(
"could not create directory \"%s\": %m", summarydir);
728 pg_fatal(
"could not create background process: %m");
737 pg_fatal(
"could not create background thread: %m");
757 pg_fatal(
"could not create directory \"%s\": %m", dirname);
776 pg_fatal(
"directory \"%s\" exists but is not empty", dirname);
782 pg_fatal(
"could not access directory \"%s\": %m", dirname);
819 char totaldone_str[32];
820 char totalsize_str[32];
848 #define VERBOSE_FILENAME_LENGTH 35
858 ngettext(
"%*s/%s kB (100%%), %d/%d tablespace %*s",
859 "%*s/%s kB (100%%), %d/%d tablespaces %*s",
861 (
int) strlen(totalsize_str),
862 totaldone_str, totalsize_str,
870 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
871 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
873 (
int) strlen(totalsize_str),
874 totaldone_str, totalsize_str, percent,
877 truncate ?
"..." :
"",
886 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace",
887 "%*s/%s kB (%d%%), %d/%d tablespaces",
889 (
int) strlen(totalsize_str),
890 totaldone_str, totalsize_str, percent,
897 fputc((!finished && isatty(fileno(stderr))) ?
'\r' :
'\n', stderr);
908 result = strtod(src, &after_num);
909 if (src == after_num)
910 pg_fatal(
"transfer rate \"%s\" is not a valid value", src);
912 pg_fatal(
"invalid transfer rate \"%s\": %m", src);
919 pg_fatal(
"transfer rate must be greater than zero");
926 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
929 if (*after_num !=
'\0')
932 if (*after_num ==
'k')
937 else if (*after_num ==
'M')
945 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
948 if (*after_num !=
'\0')
949 pg_fatal(
"invalid --max-rate unit: \"%s\"", suffix);
952 if ((uint64) result != (uint64) ((
uint32) result))
953 pg_fatal(
"transfer rate \"%s\" exceeds integer range", src);
960 pg_fatal(
"transfer rate \"%s\" is out of range", src);
962 return (
int32) result;
992 if (strncmp(
option,
"server-", 7) == 0)
997 else if (strncmp(
option,
"client-", 7) == 0)
1015 void *callback_data)
1022 pg_fatal(
"could not get COPY data stream: %s",
1039 pg_fatal(
"could not read COPY data: %s",
1043 pg_fatal(
"background process terminated unexpectedly");
1045 (*callback) (r,
copybuf, callback_data);
1063 bool is_recovery_guc_supported,
1064 bool expect_unterminated_tarfile,
1069 bool inject_manifest;
1075 bool must_parse_archive;
1076 int archive_name_len = strlen(archive_name);
1086 is_tar = (archive_name_len > 4 &&
1087 strcmp(archive_name + archive_name_len - 4,
".tar") == 0);
1090 is_tar_gz = (archive_name_len > 7 &&
1091 strcmp(archive_name + archive_name_len - 7,
".tar.gz") == 0);
1094 is_tar_lz4 = (archive_name_len > 8 &&
1095 strcmp(archive_name + archive_name_len - 8,
".tar.lz4") == 0);
1098 is_tar_zstd = (archive_name_len > 8 &&
1099 strcmp(archive_name + archive_name_len - 8,
".tar.zst") == 0);
1102 is_compressed_tar = is_tar_gz || is_tar_lz4 || is_tar_zstd;
1112 if (inject_manifest && is_compressed_tar)
1114 pg_log_error(
"cannot inject manifest into a compressed tar file");
1115 pg_log_error_hint(
"Use client-side compression, send the output to a directory rather than standard output, or use %s.",
1125 must_parse_archive = (
format ==
'p' || inject_manifest ||
1129 if (must_parse_archive && !is_tar && !is_compressed_tar)
1131 pg_log_error(
"cannot parse archive \"%s\"", archive_name);
1135 if (inject_manifest)
1136 pg_log_error_detail(
"Using - as the output directory requires pg_basebackup to parse the archive.");
1157 if (spclocation == NULL)
1178 if (strcmp(
basedir,
"-") == 0)
1180 snprintf(archive_filename,
sizeof(archive_filename),
"-");
1185 snprintf(archive_filename,
sizeof(archive_filename),
1186 "%s/%s",
basedir, archive_name);
1187 archive_file = NULL;
1195 strlcat(archive_filename,
".gz",
sizeof(archive_filename));
1197 archive_file, compress);
1201 strlcat(archive_filename,
".lz4",
sizeof(archive_filename));
1208 strlcat(archive_filename,
".zst",
sizeof(archive_filename));
1224 if (must_parse_archive)
1234 if (inject_manifest)
1235 manifest_inject_streamer = streamer;
1243 Assert(must_parse_archive);
1245 is_recovery_guc_supported,
1255 if (must_parse_archive)
1257 else if (expect_unterminated_tarfile)
1268 else if (is_tar_lz4)
1270 else if (is_tar_zstd)
1275 *manifest_inject_streamer_p = manifest_inject_streamer;
1290 state.tablespacenum = -1;
1291 state.compress = compress;
1297 if (
state.manifest_file !=NULL)
1299 fclose(
state.manifest_file);
1300 state.manifest_file = NULL;
1307 if (
state.manifest_inject_streamer != NULL &&
1308 state.manifest_buffer != NULL)
1312 state.manifest_buffer->data,
1313 state.manifest_buffer->len);
1315 state.manifest_buffer = NULL;
1319 if (
state.streamer != NULL)
1323 state.streamer = NULL;
1351 if (++
state->tablespacenum > 0)
1355 if (
state->manifest_buffer != NULL ||
1356 state->manifest_file !=NULL)
1357 pg_fatal(
"archives must precede manifest");
1369 if (archive_name[0] ==
'\0' || archive_name[0] ==
'.' ||
1370 strchr(archive_name,
'/') != NULL ||
1371 strchr(archive_name,
'\\') != NULL)
1372 pg_fatal(
"invalid archive name: \"%s\"",
1380 if (spclocation[0] ==
'\0')
1384 if (
state->streamer != NULL)
1388 state->streamer = NULL;
1405 &
state->manifest_inject_streamer,
1415 if (
state->manifest_buffer != NULL)
1421 else if (
state->manifest_file !=NULL)
1424 if (fwrite(
copybuf + 1, r - 1, 1,
1425 state->manifest_file) != 1)
1433 pg_fatal(
"could not write to file \"%s\": %m",
1434 state->manifest_filename);
1437 else if (
state->streamer != NULL)
1444 pg_fatal(
"unexpected payload data");
1487 if (
state->manifest_inject_streamer != NULL)
1492 sizeof(
state->manifest_filename),
1493 "%s/backup_manifest.tmp",
basedir);
1494 state->manifest_file =
1495 fopen(
state->manifest_filename,
"wb");
1496 if (
state->manifest_file == NULL)
1497 pg_fatal(
"could not create file \"%s\": %m",
1498 state->manifest_filename);
1558 if (*
cursor +
sizeof(uint64) > r)
1561 *
cursor +=
sizeof(uint64);
1589 pg_fatal(
"malformed COPY message of type %d, length %zu",
1604 bool is_recovery_guc_supported;
1605 bool expect_unterminated_tarfile;
1609 is_recovery_guc_supported =
1611 expect_unterminated_tarfile =
1614 &manifest_inject_streamer,
1615 is_recovery_guc_supported,
1616 expect_unterminated_tarfile,
1618 state.tablespacenum = tablespacenum;
1628 if (manifest_inject_streamer != NULL)
1684 strlcpy(canon_dir, dir,
sizeof(canon_dir));
1688 if (strcmp(canon_dir, cell->
old_dir) == 0)
1703 "%s/backup_manifest.tmp",
basedir);
1705 if (
state.file == NULL)
1706 pg_fatal(
"could not create file \"%s\": %m",
state.filename);
1727 pg_fatal(
"could not write to file \"%s\": %m",
state->filename);
1745 void *callback_data)
1756 char *incremental_manifest)
1759 char *sysidentifier;
1765 char xlogend[64] = {0};
1770 int writing_to_stdout;
1771 bool use_new_option_syntax =
false;
1781 minServerMajor = 901;
1782 maxServerMajor = PG_VERSION_NUM / 100;
1784 serverMajor = serverVersion / 100;
1785 if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1789 pg_fatal(
"incompatible server version %s",
1790 serverver ? serverver :
"'unknown'");
1792 if (serverMajor >= 1500)
1793 use_new_option_syntax =
true;
1825 if (incremental_manifest != NULL)
1833 pg_fatal(
"server does not support incremental backup");
1836 fd = open(incremental_manifest, O_RDONLY |
PG_BINARY, 0);
1838 pg_fatal(
"could not open file \"%s\": %m", incremental_manifest);
1842 pg_fatal(
"could not send replication command \"%s\": %s",
1848 pg_fatal(
"could not upload manifest: %s",
1851 pg_fatal(
"could not upload manifest: unexpected status %s",
1856 while ((nbytes =
read(
fd, mbuf,
sizeof mbuf)) > 0)
1859 pg_fatal(
"could not send COPY data: %s",
1865 pg_fatal(
"could not read file \"%s\": %m", incremental_manifest);
1869 pg_fatal(
"could not send end-of-COPY: %s",
1875 pg_fatal(
"could not upload manifest: %s",
1878 pg_fatal(
"could not upload manifest: unexpected status %s",
1884 pg_fatal(
"unexpected extra result while sending manifest");
1900 if (use_new_option_syntax)
1902 "CHECKPOINT",
"fast");
1908 if (use_new_option_syntax)
1920 if (use_new_option_syntax)
1922 "VERIFY_CHECKSUMS", 0);
1925 "NOVERIFY_CHECKSUMS");
1941 if (serverMajor < 1500)
1942 pg_fatal(
"backup targets are not supported by this server version");
1945 pg_fatal(
"recovery configuration cannot be written when a backup target is used");
1962 "TARGET_DETAIL",
colon + 1);
1965 else if (serverMajor >= 1500)
1967 "TARGET",
"client");
1971 if (!use_new_option_syntax)
1972 pg_fatal(
"server does not support server-side compression");
1975 if (compression_detail != NULL)
1977 "COMPRESSION_DETAIL",
1978 compression_detail);
1982 pg_log_info(
"initiating base backup, waiting for checkpoint to complete");
1986 fprintf(stderr,
_(
"waiting for checkpoint"));
1987 if (isatty(fileno(stderr)))
1993 if (use_new_option_syntax &&
buf.len > 0)
2000 pg_fatal(
"could not send replication command \"%s\": %s",
2008 pg_fatal(
"could not initiate base backup: %s",
2011 pg_fatal(
"server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
2027 starttli = latesttli;
2031 pg_log_info(
"write-ahead log start point: %s on timeline %u",
2032 xlogstart, starttli);
2039 pg_fatal(
"could not get backup header: %s",
2042 pg_fatal(
"no data returned from server");
2085 pg_fatal(
"can only write single tablespace to stdout, database has %d",
2095 int wal_compress_level;
2103 wal_compress_level = client_compress->
level;
2108 wal_compress_level = 0;
2112 wal_compress_algorithm,
2113 wal_compress_level);
2116 if (serverMajor >= 1500)
2139 strlcpy(archive_name,
"base.tar",
sizeof(archive_name));
2144 snprintf(archive_name,
sizeof(archive_name),
2164 if (!writing_to_stdout &&
manifest)
2184 pg_fatal(
"no write-ahead log end position returned from server");
2187 pg_log_info(
"write-ahead log end point: %s", xlogend);
2221 intptr_t bgchild_handle =
bgchild;
2227 pg_log_info(
"waiting for background process to finish streaming ...");
2230 if (
write(
bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2231 pg_fatal(
"could not send command to background pipe: %m");
2234 r = waitpid(
bgchild, &status, 0);
2235 if (r == (pid_t) -1)
2236 pg_fatal(
"could not wait for child process: %m");
2249 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
2250 pg_fatal(
"could not parse write-ahead log location \"%s\"",
2256 if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2260 pg_fatal(
"could not wait for child thread: %m");
2262 if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2265 pg_fatal(
"could not get child thread exit status: %m");
2268 pg_fatal(
"child thread exited with error %u",
2269 (
unsigned int) status);
2300 if (strcmp(
basedir,
"-") != 0)
2322 pg_log_info(
"renaming backup_manifest.tmp to backup_manifest");
2335 if (rename(tmp_filename,
filename) != 0)
2336 pg_fatal(
"could not rename file \"%s\" to \"%s\": %m",
2349 static struct option long_options[] = {
2391 char *compression_detail = NULL;
2392 char *incremental_manifest = NULL;
2402 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
2407 else if (strcmp(argv[1],
"-V") == 0
2408 || strcmp(argv[1],
"--version") == 0)
2410 puts(
"pg_basebackup (PostgreSQL) " PG_VERSION);
2417 while ((
c =
getopt_long(argc, argv,
"c:Cd:D:F:h:i:l:nNp:Pr:Rs:S:t:T:U:vwWX:zZ:",
2418 long_options, &option_index)) != -1)
2428 pg_fatal(
"invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2441 if (strcmp(
optarg,
"p") == 0 || strcmp(
optarg,
"plain") == 0)
2443 else if (strcmp(
optarg,
"t") == 0 || strcmp(
optarg,
"tar") == 0)
2446 pg_fatal(
"invalid output format \"%s\", must be \"plain\" or \"tar\"",
2511 if (strcmp(
optarg,
"n") == 0 ||
2512 strcmp(
optarg,
"none") == 0)
2516 else if (strcmp(
optarg,
"f") == 0 ||
2517 strcmp(
optarg,
"fetch") == 0)
2521 else if (strcmp(
optarg,
"s") == 0 ||
2522 strcmp(
optarg,
"stream") == 0)
2527 pg_fatal(
"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2532 compression_detail = NULL;
2537 &compression_detail, &compressloc);
2576 pg_log_error(
"too many command-line arguments (first is \"%s\")",
2599 pg_log_error(
"cannot specify both format and backup target");
2611 pg_log_error(
"must specify output directory or backup target");
2617 pg_log_error(
"cannot specify both output directory and backup target");
2647 pg_fatal(
"unrecognized compression algorithm: \"%s\"",
2652 if (error_detail != NULL)
2653 pg_fatal(
"invalid compression specification: %s",
2669 pg_log_error(
"client-side compression is not possible when a backup target is specified");
2680 pg_log_error(
"only tar mode backups can be compressed");
2690 pg_log_error(
"WAL cannot be streamed when a backup target is specified");
2696 pg_log_error(
"cannot stream write-ahead logs in tar mode to stdout");
2703 pg_log_error(
"replication slots can only be used with WAL streaming");
2715 pg_log_error(
"--no-slot cannot be used with slot name");
2726 pg_log_error(
"%s needs a slot to be specified using --slot",
2735 "--create-slot",
"--no-slot");
2748 pg_log_error(
"WAL directory location cannot be specified along with a backup target");
2754 pg_log_error(
"WAL directory location can only be specified in plain mode");
2763 pg_log_error(
"WAL directory location must be an absolute path");
2775 "--progress",
"--no-estimate-size");
2786 "--no-manifest",
"--manifest-checksums");
2794 "--no-manifest",
"--manifest-force-encode");
2860 "pg_xlog" :
"pg_wal");
2863 pg_fatal(
"could not create symbolic link \"%s\": %m", linkloc);
2868 &client_compress, incremental_manifest);
Datum now(PG_FUNCTION_ARGS)
bbstreamer * bbstreamer_gzip_writer_new(char *pathname, FILE *file, pg_compress_specification *compress)
bbstreamer * bbstreamer_zstd_compressor_new(bbstreamer *next, pg_compress_specification *compress)
static void bbstreamer_content(bbstreamer *streamer, bbstreamer_member *member, const char *data, int len, bbstreamer_archive_context context)
static void bbstreamer_finalize(bbstreamer *streamer)
bbstreamer * bbstreamer_tar_terminator_new(bbstreamer *next)
bbstreamer * bbstreamer_lz4_compressor_new(bbstreamer *next, pg_compress_specification *compress)
bbstreamer * bbstreamer_tar_parser_new(bbstreamer *next)
bbstreamer * bbstreamer_lz4_decompressor_new(bbstreamer *next)
static void bbstreamer_free(bbstreamer *streamer)
bbstreamer * bbstreamer_recovery_injector_new(bbstreamer *next, bool is_recovery_guc_supported, PQExpBuffer recoveryconfcontents)
bbstreamer * bbstreamer_tar_archiver_new(bbstreamer *next)
bbstreamer * bbstreamer_zstd_decompressor_new(bbstreamer *next)
bbstreamer * bbstreamer_plain_writer_new(char *pathname, FILE *file)
bbstreamer * bbstreamer_extractor_new(const char *basepath, const char *(*link_map)(const char *), void(*report_output_file)(const char *))
bbstreamer * bbstreamer_gzip_decompressor_new(bbstreamer *next)
void bbstreamer_inject_file(bbstreamer *streamer, char *pathname, char *data, int len)
#define unconstify(underlying_type, expr)
#define ngettext(s, p, n)
#define PG_TEXTDOMAIN(domain)
void set_pglocale_pgservice(const char *argv0, const char *app)
bool parse_compress_algorithm(char *name, pg_compress_algorithm *algorithm)
void parse_compress_specification(pg_compress_algorithm algorithm, char *specification, pg_compress_specification *result)
char * validate_compress_specification(pg_compress_specification *spec)
void parse_compress_options(const char *option, char **algorithm, char **detail)
PGconn * GetConnection(UserMapping *user, bool will_prep_stmt, PgFdwConnState **state)
static void PGresult * res
int durable_rename(const char *oldfile, const char *newfile, int elevel)
const char * PQparameterStatus(const PGconn *conn, const char *paramName)
int PQserverVersion(const PGconn *conn)
char * PQerrorMessage(const PGconn *conn)
void PQfinish(PGconn *conn)
int PQbackendPID(const PGconn *conn)
void PQfreemem(void *ptr)
ExecStatusType PQresultStatus(const PGresult *res)
int PQputCopyEnd(PGconn *conn, const char *errormsg)
int PQntuples(const PGresult *res)
int PQputCopyData(PGconn *conn, const char *buffer, int nbytes)
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
int PQsendQuery(PGconn *conn, const char *query)
char * PQresStatus(ExecStatusType status)
char * PQresultErrorField(const PGresult *res, int fieldcode)
int PQnfields(const PGresult *res)
PGresult * PQgetResult(PGconn *conn)
int PQgetCopyData(PGconn *conn, char **buffer, int async)
void * pg_malloc0(size_t size)
char * pg_strdup(const char *in)
@ 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(fmt[strlen(fmt) - 1] !='\n')
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
#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 bbstreamer * CreateBackupStreamer(char *archive_name, char *spclocation, bbstreamer **manifest_inject_streamer_p, bool is_recovery_guc_supported, bool expect_unterminated_tarfile, pg_compress_specification *compress)
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)
pqsigfunc pqsignal(int signo, pqsigfunc func)
#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)
#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
bbstreamer * 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 * CreateWalDirectoryMethod(const char *basedir, pg_compress_algorithm compression_algorithm, int compression_level, bool sync)
WalWriteMethod * CreateWalTarMethod(const char *tarbase, 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