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
129 static char *
label =
"pg_basebackup base backup";
191 static void usage(
void);
194 static void progress_report(
int tablespacenum,
bool force,
bool finished);
198 bool is_recovery_guc_supported,
199 bool expect_unterminated_tarfile,
202 void *callback_data);
213 void *callback_data);
216 void *callback_data);
222 bool segment_finished);
246 pg_log_error(
"failed to remove contents of data directory");
259 pg_log_error(
"failed to remove contents of WAL directory");
272 pg_log_info(
"changes to tablespace directories will not be undone");
321 for (arg_ptr =
arg; *arg_ptr; arg_ptr++)
324 pg_fatal(
"directory name too long");
326 if (*arg_ptr ==
'\\' && *(arg_ptr + 1) ==
'=')
328 else if (*arg_ptr ==
'=' && (arg_ptr ==
arg || *(arg_ptr - 1) !=
'\\'))
331 pg_fatal(
"multiple \"=\" signs in tablespace mapping");
336 *dst_ptr++ = *arg_ptr;
340 pg_fatal(
"invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"",
arg);
359 pg_fatal(
"old directory is not an absolute path in tablespace mapping: %s",
363 pg_fatal(
"new directory is not an absolute path in tablespace mapping: %s",
385 printf(
_(
"%s takes a base backup of a running PostgreSQL server.\n\n"),
389 printf(
_(
"\nOptions controlling the output:\n"));
390 printf(
_(
" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
391 printf(
_(
" -F, --format=p|t output format (plain (default), tar)\n"));
392 printf(
_(
" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
393 " (in kB/s, or use suffix \"k\" or \"M\")\n"));
394 printf(
_(
" -R, --write-recovery-conf\n"
395 " write configuration for replication\n"));
396 printf(
_(
" -t, --target=TARGET[:DETAIL]\n"
397 " backup target (if other than client)\n"));
398 printf(
_(
" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
399 " relocate tablespace in OLDDIR to NEWDIR\n"));
400 printf(
_(
" --waldir=WALDIR location for the write-ahead log directory\n"));
401 printf(
_(
" -X, --wal-method=none|fetch|stream\n"
402 " include required WAL files with specified method\n"));
403 printf(
_(
" -z, --gzip compress tar output\n"));
404 printf(
_(
" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
405 " compress on client or server as specified\n"));
406 printf(
_(
" -Z, --compress=none do not compress tar output\n"));
407 printf(
_(
"\nGeneral options:\n"));
408 printf(
_(
" -c, --checkpoint=fast|spread\n"
409 " set fast or spread checkpointing\n"));
410 printf(
_(
" -C, --create-slot create replication slot\n"));
411 printf(
_(
" -l, --label=LABEL set backup label\n"));
412 printf(
_(
" -n, --no-clean do not clean up after errors\n"));
413 printf(
_(
" -N, --no-sync do not wait for changes to be written safely to disk\n"));
414 printf(
_(
" -P, --progress show progress information\n"));
415 printf(
_(
" -S, --slot=SLOTNAME replication slot to use\n"));
416 printf(
_(
" -v, --verbose output verbose messages\n"));
417 printf(
_(
" -V, --version output version information, then exit\n"));
418 printf(
_(
" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
419 " use algorithm for manifest checksums\n"));
420 printf(
_(
" --manifest-force-encode\n"
421 " hex encode all file names in manifest\n"));
422 printf(
_(
" --no-estimate-size do not estimate backup size in server side\n"));
423 printf(
_(
" --no-manifest suppress generation of backup manifest\n"));
424 printf(
_(
" --no-slot prevent creation of temporary replication slot\n"));
425 printf(
_(
" --no-verify-checksums\n"
426 " do not verify checksums\n"));
427 printf(
_(
" -?, --help show this help, then exit\n"));
428 printf(
_(
"\nConnection options:\n"));
429 printf(
_(
" -d, --dbname=CONNSTR connection string\n"));
430 printf(
_(
" -h, --host=HOSTNAME database server host or socket directory\n"));
431 printf(
_(
" -p, --port=PORT database server port number\n"));
432 printf(
_(
" -s, --status-interval=INTERVAL\n"
433 " time between status packets sent to server (in seconds)\n"));
434 printf(
_(
" -U, --username=NAME connect as specified database user\n"));
435 printf(
_(
" -w, --no-password never prompt for password\n"));
436 printf(
_(
" -W, --password force password prompt (should happen automatically)\n"));
437 printf(
_(
"\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
438 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
452 bool segment_finished)
458 struct timeval tv = {0};
471 char xlogend[64] = {0};
475 r =
read(
bgpipe[0], xlogend,
sizeof(xlogend) - 1);
477 pg_fatal(
"could not read from ready pipe: %m");
479 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
480 pg_fatal(
"could not parse write-ahead log location \"%s\"",
607 int wal_compress_level)
621 if (sscanf(
startpos,
"%X/%X", &hi, &lo) != 2)
622 pg_fatal(
"could not parse write-ahead log location \"%s\"",
624 param->
startptr = ((uint64) hi) << 32 | lo;
631 pg_fatal(
"could not create pipe for background process: %m");
644 "pg_xlog" :
"pg_wal");
664 pg_log_info(
"created temporary replication slot \"%s\"",
680 snprintf(statusdir,
sizeof(statusdir),
"%s/%s/archive_status",
683 "pg_xlog" :
"pg_wal");
686 pg_fatal(
"could not create directory \"%s\": %m", statusdir);
701 pg_fatal(
"could not create background process: %m");
710 pg_fatal(
"could not create background thread: %m");
730 pg_fatal(
"could not create directory \"%s\": %m", dirname);
749 pg_fatal(
"directory \"%s\" exists but is not empty", dirname);
755 pg_fatal(
"could not access directory \"%s\": %m", dirname);
792 char totaldone_str[32];
793 char totalsize_str[32];
821 #define VERBOSE_FILENAME_LENGTH 35
831 ngettext(
"%*s/%s kB (100%%), %d/%d tablespace %*s",
832 "%*s/%s kB (100%%), %d/%d tablespaces %*s",
834 (
int) strlen(totalsize_str),
835 totaldone_str, totalsize_str,
843 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
844 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
846 (
int) strlen(totalsize_str),
847 totaldone_str, totalsize_str, percent,
850 truncate ?
"..." :
"",
859 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace",
860 "%*s/%s kB (%d%%), %d/%d tablespaces",
862 (
int) strlen(totalsize_str),
863 totaldone_str, totalsize_str, percent,
870 fputc((!finished && isatty(fileno(stderr))) ?
'\r' :
'\n', stderr);
881 result = strtod(src, &after_num);
882 if (src == after_num)
883 pg_fatal(
"transfer rate \"%s\" is not a valid value", src);
885 pg_fatal(
"invalid transfer rate \"%s\": %m", src);
892 pg_fatal(
"transfer rate must be greater than zero");
899 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
902 if (*after_num !=
'\0')
905 if (*after_num ==
'k')
910 else if (*after_num ==
'M')
918 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
921 if (*after_num !=
'\0')
922 pg_fatal(
"invalid --max-rate unit: \"%s\"", suffix);
925 if ((uint64) result != (uint64) ((
uint32) result))
926 pg_fatal(
"transfer rate \"%s\" exceeds integer range", src);
933 pg_fatal(
"transfer rate \"%s\" is out of range", src);
935 return (
int32) result;
965 if (strncmp(
option,
"server-", 7) == 0)
970 else if (strncmp(
option,
"client-", 7) == 0)
995 pg_fatal(
"could not get COPY data stream: %s",
1012 pg_fatal(
"could not read COPY data: %s",
1016 pg_fatal(
"background process terminated unexpectedly");
1018 (*callback) (r,
copybuf, callback_data);
1036 bool is_recovery_guc_supported,
1037 bool expect_unterminated_tarfile,
1042 bool inject_manifest;
1048 bool must_parse_archive;
1049 int archive_name_len = strlen(archive_name);
1059 is_tar = (archive_name_len > 4 &&
1060 strcmp(archive_name + archive_name_len - 4,
".tar") == 0);
1063 is_tar_gz = (archive_name_len > 7 &&
1064 strcmp(archive_name + archive_name_len - 7,
".tar.gz") == 0);
1067 is_tar_lz4 = (archive_name_len > 8 &&
1068 strcmp(archive_name + archive_name_len - 8,
".tar.lz4") == 0);
1071 is_tar_zstd = (archive_name_len > 8 &&
1072 strcmp(archive_name + archive_name_len - 8,
".tar.zst") == 0);
1075 is_compressed_tar = is_tar_gz || is_tar_lz4 || is_tar_zstd;
1085 if (inject_manifest && is_compressed_tar)
1087 pg_log_error(
"cannot inject manifest into a compressed tar file");
1088 pg_log_error_hint(
"Use client-side compression, send the output to a directory rather than standard output, or use %s.",
1098 must_parse_archive = (
format ==
'p' || inject_manifest ||
1102 if (must_parse_archive && !is_tar && !is_compressed_tar)
1104 pg_log_error(
"cannot parse archive \"%s\"", archive_name);
1108 if (inject_manifest)
1109 pg_log_error_detail(
"Using - as the output directory requires pg_basebackup to parse the archive.");
1143 if (strcmp(
basedir,
"-") == 0)
1145 snprintf(archive_filename,
sizeof(archive_filename),
"-");
1150 snprintf(archive_filename,
sizeof(archive_filename),
1151 "%s/%s",
basedir, archive_name);
1152 archive_file = NULL;
1160 strlcat(archive_filename,
".gz",
sizeof(archive_filename));
1162 archive_file, compress);
1166 strlcat(archive_filename,
".lz4",
sizeof(archive_filename));
1173 strlcat(archive_filename,
".zst",
sizeof(archive_filename));
1189 if (must_parse_archive)
1199 if (inject_manifest)
1200 manifest_inject_streamer = streamer;
1208 Assert(must_parse_archive);
1210 is_recovery_guc_supported,
1220 if (must_parse_archive)
1222 else if (expect_unterminated_tarfile)
1233 else if (is_tar_lz4)
1235 else if (is_tar_zstd)
1240 *manifest_inject_streamer_p = manifest_inject_streamer;
1255 state.tablespacenum = -1;
1256 state.compress = compress;
1262 if (
state.manifest_file !=NULL)
1264 fclose(
state.manifest_file);
1265 state.manifest_file = NULL;
1272 if (
state.manifest_inject_streamer != NULL &&
1273 state.manifest_buffer != NULL)
1277 state.manifest_buffer->data,
1278 state.manifest_buffer->len);
1280 state.manifest_buffer = NULL;
1284 if (
state.streamer != NULL)
1288 state.streamer = NULL;
1316 if (++
state->tablespacenum > 0)
1320 if (
state->manifest_buffer != NULL ||
1321 state->manifest_file !=NULL)
1322 pg_fatal(
"archives must precede manifest");
1334 if (archive_name[0] ==
'\0' || archive_name[0] ==
'.' ||
1335 strchr(archive_name,
'/') != NULL ||
1336 strchr(archive_name,
'\\') != NULL)
1337 pg_fatal(
"invalid archive name: \"%s\"",
1345 if (spclocation[0] ==
'\0')
1349 if (
state->streamer != NULL)
1353 state->streamer = NULL;
1370 &
state->manifest_inject_streamer,
1380 if (
state->manifest_buffer != NULL)
1386 else if (
state->manifest_file !=NULL)
1389 if (fwrite(
copybuf + 1, r - 1, 1,
1390 state->manifest_file) != 1)
1398 pg_fatal(
"could not write to file \"%s\": %m",
1399 state->manifest_filename);
1402 else if (
state->streamer != NULL)
1409 pg_fatal(
"unexpected payload data");
1452 if (
state->manifest_inject_streamer != NULL)
1457 sizeof(
state->manifest_filename),
1458 "%s/backup_manifest.tmp",
basedir);
1459 state->manifest_file =
1460 fopen(
state->manifest_filename,
"wb");
1461 if (
state->manifest_file == NULL)
1462 pg_fatal(
"could not create file \"%s\": %m",
1463 state->manifest_filename);
1523 if (*
cursor +
sizeof(uint64) > r)
1526 *
cursor +=
sizeof(uint64);
1554 pg_fatal(
"malformed COPY message of type %d, length %zu",
1569 bool is_recovery_guc_supported;
1570 bool expect_unterminated_tarfile;
1574 is_recovery_guc_supported =
1576 expect_unterminated_tarfile =
1579 &manifest_inject_streamer,
1580 is_recovery_guc_supported,
1581 expect_unterminated_tarfile,
1583 state.tablespacenum = tablespacenum;
1593 if (manifest_inject_streamer != NULL)
1649 strlcpy(canon_dir, dir,
sizeof(canon_dir));
1653 if (strcmp(canon_dir, cell->
old_dir) == 0)
1668 "%s/backup_manifest.tmp",
basedir);
1670 if (
state.file == NULL)
1671 pg_fatal(
"could not create file \"%s\": %m",
state.filename);
1692 pg_fatal(
"could not write to file \"%s\": %m",
state->filename);
1710 void *callback_data)
1722 char *sysidentifier;
1728 char xlogend[64] = {0};
1733 int writing_to_stdout;
1734 bool use_new_option_syntax =
false;
1744 minServerMajor = 901;
1745 maxServerMajor = PG_VERSION_NUM / 100;
1747 serverMajor = serverVersion / 100;
1748 if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1752 pg_fatal(
"incompatible server version %s",
1753 serverver ? serverver :
"'unknown'");
1755 if (serverMajor >= 1500)
1756 use_new_option_syntax =
true;
1794 if (use_new_option_syntax)
1796 "CHECKPOINT",
"fast");
1802 if (use_new_option_syntax)
1814 if (use_new_option_syntax)
1816 "VERIFY_CHECKSUMS", 0);
1819 "NOVERIFY_CHECKSUMS");
1835 if (serverMajor < 1500)
1836 pg_fatal(
"backup targets are not supported by this server version");
1839 pg_fatal(
"recovery configuration cannot be written when a backup target is used");
1856 "TARGET_DETAIL",
colon + 1);
1859 else if (serverMajor >= 1500)
1861 "TARGET",
"client");
1865 if (!use_new_option_syntax)
1866 pg_fatal(
"server does not support server-side compression");
1869 if (compression_detail != NULL)
1871 "COMPRESSION_DETAIL",
1872 compression_detail);
1876 pg_log_info(
"initiating base backup, waiting for checkpoint to complete");
1880 fprintf(stderr,
_(
"waiting for checkpoint"));
1881 if (isatty(fileno(stderr)))
1887 if (use_new_option_syntax &&
buf.len > 0)
1893 pg_fatal(
"could not send replication command \"%s\": %s",
1901 pg_fatal(
"could not initiate base backup: %s",
1904 pg_fatal(
"server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
1920 starttli = latesttli;
1924 pg_log_info(
"write-ahead log start point: %s on timeline %u",
1925 xlogstart, starttli);
1932 pg_fatal(
"could not get backup header: %s",
1935 pg_fatal(
"no data returned from server");
1970 pg_fatal(
"can only write single tablespace to stdout, database has %d",
1980 int wal_compress_level;
1988 wal_compress_level = client_compress->
level;
1993 wal_compress_level = 0;
1997 wal_compress_algorithm,
1998 wal_compress_level);
2001 if (serverMajor >= 1500)
2024 strlcpy(archive_name,
"base.tar",
sizeof(archive_name));
2029 snprintf(archive_name,
sizeof(archive_name),
2049 if (!writing_to_stdout &&
manifest)
2069 pg_fatal(
"no write-ahead log end position returned from server");
2072 pg_log_info(
"write-ahead log end point: %s", xlogend);
2106 intptr_t bgchild_handle =
bgchild;
2112 pg_log_info(
"waiting for background process to finish streaming ...");
2115 if (
write(
bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2116 pg_fatal(
"could not send command to background pipe: %m");
2119 r = waitpid(
bgchild, &status, 0);
2120 if (r == (pid_t) -1)
2121 pg_fatal(
"could not wait for child process: %m");
2134 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
2135 pg_fatal(
"could not parse write-ahead log location \"%s\"",
2141 if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2145 pg_fatal(
"could not wait for child thread: %m");
2147 if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2150 pg_fatal(
"could not get child thread exit status: %m");
2153 pg_fatal(
"child thread exited with error %u",
2154 (
unsigned int) status);
2185 if (strcmp(
basedir,
"-") != 0)
2186 (void) fsync_dir_recurse(
basedir);
2190 (void) fsync_pgdata(
basedir, serverVersion);
2207 pg_log_info(
"renaming backup_manifest.tmp to backup_manifest");
2220 if (rename(tmp_filename,
filename) != 0)
2221 pg_fatal(
"could not rename file \"%s\" to \"%s\": %m",
2234 static struct option long_options[] = {
2274 char *compression_detail = NULL;
2284 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
2289 else if (strcmp(argv[1],
"-V") == 0
2290 || strcmp(argv[1],
"--version") == 0)
2292 puts(
"pg_basebackup (PostgreSQL) " PG_VERSION);
2299 while ((
c =
getopt_long(argc, argv,
"c:Cd:D:F:h:l:nNp:Pr:Rs:S:t:T:U:vwWX:zZ:",
2300 long_options, &option_index)) != -1)
2310 pg_fatal(
"invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2323 if (strcmp(
optarg,
"p") == 0 || strcmp(
optarg,
"plain") == 0)
2325 else if (strcmp(
optarg,
"t") == 0 || strcmp(
optarg,
"tar") == 0)
2328 pg_fatal(
"invalid output format \"%s\", must be \"plain\" or \"tar\"",
2390 if (strcmp(
optarg,
"n") == 0 ||
2391 strcmp(
optarg,
"none") == 0)
2395 else if (strcmp(
optarg,
"f") == 0 ||
2396 strcmp(
optarg,
"fetch") == 0)
2400 else if (strcmp(
optarg,
"s") == 0 ||
2401 strcmp(
optarg,
"stream") == 0)
2406 pg_fatal(
"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2411 compression_detail = NULL;
2416 &compression_detail, &compressloc);
2451 pg_log_error(
"too many command-line arguments (first is \"%s\")",
2474 pg_log_error(
"cannot specify both format and backup target");
2486 pg_log_error(
"must specify output directory or backup target");
2492 pg_log_error(
"cannot specify both output directory and backup target");
2522 pg_fatal(
"unrecognized compression algorithm: \"%s\"",
2527 if (error_detail != NULL)
2528 pg_fatal(
"invalid compression specification: %s",
2544 pg_log_error(
"client-side compression is not possible when a backup target is specified");
2555 pg_log_error(
"only tar mode backups can be compressed");
2565 pg_log_error(
"WAL cannot be streamed when a backup target is specified");
2571 pg_log_error(
"cannot stream write-ahead logs in tar mode to stdout");
2578 pg_log_error(
"replication slots can only be used with WAL streaming");
2590 pg_log_error(
"--no-slot cannot be used with slot name");
2601 pg_log_error(
"%s needs a slot to be specified using --slot",
2610 "--create-slot",
"--no-slot");
2623 pg_log_error(
"WAL directory location cannot be specified along with a backup target");
2629 pg_log_error(
"WAL directory location can only be specified in plain mode");
2638 pg_log_error(
"WAL directory location must be an absolute path");
2650 "--progress",
"--no-estimate-size");
2661 "--no-manifest",
"--manifest-checksums");
2669 "--no-manifest",
"--manifest-force-encode");
2735 "pg_xlog" :
"pg_wal");
2738 pg_fatal(
"could not create symbolic link \"%s\": %m", linkloc);
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 PQntuples(const PGresult *res)
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 * 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)
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)
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 void BaseBackup(char *compression_algorithm, char *compression_detail, CompressionLocation compressloc, pg_compress_specification *client_compress)
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)
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
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)
char * psprintf(const char *fmt,...)
bool ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
bool CheckServerVersionForStreaming(PGconn *conn)
PQExpBuffer GenerateRecoveryConfig(PGconn *pgconn, 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