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";
192 static void usage(
void);
195 static void progress_report(
int tablespacenum,
bool force,
bool finished);
199 bool is_recovery_guc_supported,
200 bool expect_unterminated_tarfile,
203 void *callback_data);
214 void *callback_data);
217 void *callback_data);
223 bool segment_finished);
247 pg_log_error(
"failed to remove contents of data directory");
260 pg_log_error(
"failed to remove contents of WAL directory");
273 pg_log_info(
"changes to tablespace directories will not be undone");
322 for (arg_ptr =
arg; *arg_ptr; arg_ptr++)
325 pg_fatal(
"directory name too long");
327 if (*arg_ptr ==
'\\' && *(arg_ptr + 1) ==
'=')
329 else if (*arg_ptr ==
'=' && (arg_ptr ==
arg || *(arg_ptr - 1) !=
'\\'))
332 pg_fatal(
"multiple \"=\" signs in tablespace mapping");
337 *dst_ptr++ = *arg_ptr;
341 pg_fatal(
"invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"",
arg);
360 pg_fatal(
"old directory is not an absolute path in tablespace mapping: %s",
364 pg_fatal(
"new directory is not an absolute path in tablespace mapping: %s",
386 printf(
_(
"%s takes a base backup of a running PostgreSQL server.\n\n"),
390 printf(
_(
"\nOptions controlling the output:\n"));
391 printf(
_(
" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
392 printf(
_(
" -F, --format=p|t output format (plain (default), tar)\n"));
393 printf(
_(
" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
394 " (in kB/s, or use suffix \"k\" or \"M\")\n"));
395 printf(
_(
" -R, --write-recovery-conf\n"
396 " write configuration for replication\n"));
397 printf(
_(
" -t, --target=TARGET[:DETAIL]\n"
398 " backup target (if other than client)\n"));
399 printf(
_(
" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
400 " relocate tablespace in OLDDIR to NEWDIR\n"));
401 printf(
_(
" --waldir=WALDIR location for the write-ahead log directory\n"));
402 printf(
_(
" -X, --wal-method=none|fetch|stream\n"
403 " include required WAL files with specified method\n"));
404 printf(
_(
" -z, --gzip compress tar output\n"));
405 printf(
_(
" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
406 " compress on client or server as specified\n"));
407 printf(
_(
" -Z, --compress=none do not compress tar output\n"));
408 printf(
_(
"\nGeneral options:\n"));
409 printf(
_(
" -c, --checkpoint=fast|spread\n"
410 " set fast or spread checkpointing\n"));
411 printf(
_(
" -C, --create-slot create replication slot\n"));
412 printf(
_(
" -l, --label=LABEL set backup label\n"));
413 printf(
_(
" -n, --no-clean do not clean up after errors\n"));
414 printf(
_(
" -N, --no-sync do not wait for changes to be written safely to disk\n"));
415 printf(
_(
" -P, --progress show progress information\n"));
416 printf(
_(
" -S, --slot=SLOTNAME replication slot to use\n"));
417 printf(
_(
" -v, --verbose output verbose messages\n"));
418 printf(
_(
" -V, --version output version information, then exit\n"));
419 printf(
_(
" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
420 " use algorithm for manifest checksums\n"));
421 printf(
_(
" --manifest-force-encode\n"
422 " hex encode all file names in manifest\n"));
423 printf(
_(
" --no-estimate-size do not estimate backup size in server side\n"));
424 printf(
_(
" --no-manifest suppress generation of backup manifest\n"));
425 printf(
_(
" --no-slot prevent creation of temporary replication slot\n"));
426 printf(
_(
" --no-verify-checksums\n"
427 " do not verify checksums\n"));
428 printf(
_(
" --sync-method=METHOD\n"
429 " set method for syncing files to disk\n"));
430 printf(
_(
" -?, --help show this help, then exit\n"));
431 printf(
_(
"\nConnection options:\n"));
432 printf(
_(
" -d, --dbname=CONNSTR connection string\n"));
433 printf(
_(
" -h, --host=HOSTNAME database server host or socket directory\n"));
434 printf(
_(
" -p, --port=PORT database server port number\n"));
435 printf(
_(
" -s, --status-interval=INTERVAL\n"
436 " time between status packets sent to server (in seconds)\n"));
437 printf(
_(
" -U, --username=NAME connect as specified database user\n"));
438 printf(
_(
" -w, --no-password never prompt for password\n"));
439 printf(
_(
" -W, --password force password prompt (should happen automatically)\n"));
440 printf(
_(
"\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
441 printf(
_(
"%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
455 bool segment_finished)
461 struct timeval tv = {0};
474 char xlogend[64] = {0};
478 r =
read(
bgpipe[0], xlogend,
sizeof(xlogend) - 1);
480 pg_fatal(
"could not read from ready pipe: %m");
482 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
483 pg_fatal(
"could not parse write-ahead log location \"%s\"",
610 int wal_compress_level)
624 if (sscanf(
startpos,
"%X/%X", &hi, &lo) != 2)
625 pg_fatal(
"could not parse write-ahead log location \"%s\"",
627 param->
startptr = ((uint64) hi) << 32 | lo;
634 pg_fatal(
"could not create pipe for background process: %m");
647 "pg_xlog" :
"pg_wal");
668 pg_log_info(
"created temporary replication slot \"%s\"",
684 snprintf(statusdir,
sizeof(statusdir),
"%s/%s/archive_status",
687 "pg_xlog" :
"pg_wal");
690 pg_fatal(
"could not create directory \"%s\": %m", statusdir);
705 pg_fatal(
"could not create background process: %m");
714 pg_fatal(
"could not create background thread: %m");
734 pg_fatal(
"could not create directory \"%s\": %m", dirname);
753 pg_fatal(
"directory \"%s\" exists but is not empty", dirname);
759 pg_fatal(
"could not access directory \"%s\": %m", dirname);
796 char totaldone_str[32];
797 char totalsize_str[32];
825 #define VERBOSE_FILENAME_LENGTH 35
835 ngettext(
"%*s/%s kB (100%%), %d/%d tablespace %*s",
836 "%*s/%s kB (100%%), %d/%d tablespaces %*s",
838 (
int) strlen(totalsize_str),
839 totaldone_str, totalsize_str,
847 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
848 "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
850 (
int) strlen(totalsize_str),
851 totaldone_str, totalsize_str, percent,
854 truncate ?
"..." :
"",
863 ngettext(
"%*s/%s kB (%d%%), %d/%d tablespace",
864 "%*s/%s kB (%d%%), %d/%d tablespaces",
866 (
int) strlen(totalsize_str),
867 totaldone_str, totalsize_str, percent,
874 fputc((!finished && isatty(fileno(stderr))) ?
'\r' :
'\n', stderr);
885 result = strtod(src, &after_num);
886 if (src == after_num)
887 pg_fatal(
"transfer rate \"%s\" is not a valid value", src);
889 pg_fatal(
"invalid transfer rate \"%s\": %m", src);
896 pg_fatal(
"transfer rate must be greater than zero");
903 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
906 if (*after_num !=
'\0')
909 if (*after_num ==
'k')
914 else if (*after_num ==
'M')
922 while (*after_num !=
'\0' && isspace((
unsigned char) *after_num))
925 if (*after_num !=
'\0')
926 pg_fatal(
"invalid --max-rate unit: \"%s\"", suffix);
929 if ((uint64) result != (uint64) ((
uint32) result))
930 pg_fatal(
"transfer rate \"%s\" exceeds integer range", src);
937 pg_fatal(
"transfer rate \"%s\" is out of range", src);
939 return (
int32) result;
969 if (strncmp(
option,
"server-", 7) == 0)
974 else if (strncmp(
option,
"client-", 7) == 0)
999 pg_fatal(
"could not get COPY data stream: %s",
1016 pg_fatal(
"could not read COPY data: %s",
1020 pg_fatal(
"background process terminated unexpectedly");
1022 (*callback) (r,
copybuf, callback_data);
1040 bool is_recovery_guc_supported,
1041 bool expect_unterminated_tarfile,
1046 bool inject_manifest;
1052 bool must_parse_archive;
1053 int archive_name_len = strlen(archive_name);
1063 is_tar = (archive_name_len > 4 &&
1064 strcmp(archive_name + archive_name_len - 4,
".tar") == 0);
1067 is_tar_gz = (archive_name_len > 7 &&
1068 strcmp(archive_name + archive_name_len - 7,
".tar.gz") == 0);
1071 is_tar_lz4 = (archive_name_len > 8 &&
1072 strcmp(archive_name + archive_name_len - 8,
".tar.lz4") == 0);
1075 is_tar_zstd = (archive_name_len > 8 &&
1076 strcmp(archive_name + archive_name_len - 8,
".tar.zst") == 0);
1079 is_compressed_tar = is_tar_gz || is_tar_lz4 || is_tar_zstd;
1089 if (inject_manifest && is_compressed_tar)
1091 pg_log_error(
"cannot inject manifest into a compressed tar file");
1092 pg_log_error_hint(
"Use client-side compression, send the output to a directory rather than standard output, or use %s.",
1102 must_parse_archive = (
format ==
'p' || inject_manifest ||
1106 if (must_parse_archive && !is_tar && !is_compressed_tar)
1108 pg_log_error(
"cannot parse archive \"%s\"", archive_name);
1112 if (inject_manifest)
1113 pg_log_error_detail(
"Using - as the output directory requires pg_basebackup to parse the archive.");
1134 if (spclocation == NULL)
1155 if (strcmp(
basedir,
"-") == 0)
1157 snprintf(archive_filename,
sizeof(archive_filename),
"-");
1162 snprintf(archive_filename,
sizeof(archive_filename),
1163 "%s/%s",
basedir, archive_name);
1164 archive_file = NULL;
1172 strlcat(archive_filename,
".gz",
sizeof(archive_filename));
1174 archive_file, compress);
1178 strlcat(archive_filename,
".lz4",
sizeof(archive_filename));
1185 strlcat(archive_filename,
".zst",
sizeof(archive_filename));
1201 if (must_parse_archive)
1211 if (inject_manifest)
1212 manifest_inject_streamer = streamer;
1220 Assert(must_parse_archive);
1222 is_recovery_guc_supported,
1232 if (must_parse_archive)
1234 else if (expect_unterminated_tarfile)
1245 else if (is_tar_lz4)
1247 else if (is_tar_zstd)
1252 *manifest_inject_streamer_p = manifest_inject_streamer;
1267 state.tablespacenum = -1;
1268 state.compress = compress;
1274 if (
state.manifest_file !=NULL)
1276 fclose(
state.manifest_file);
1277 state.manifest_file = NULL;
1284 if (
state.manifest_inject_streamer != NULL &&
1285 state.manifest_buffer != NULL)
1289 state.manifest_buffer->data,
1290 state.manifest_buffer->len);
1292 state.manifest_buffer = NULL;
1296 if (
state.streamer != NULL)
1300 state.streamer = NULL;
1328 if (++
state->tablespacenum > 0)
1332 if (
state->manifest_buffer != NULL ||
1333 state->manifest_file !=NULL)
1334 pg_fatal(
"archives must precede manifest");
1346 if (archive_name[0] ==
'\0' || archive_name[0] ==
'.' ||
1347 strchr(archive_name,
'/') != NULL ||
1348 strchr(archive_name,
'\\') != NULL)
1349 pg_fatal(
"invalid archive name: \"%s\"",
1357 if (spclocation[0] ==
'\0')
1361 if (
state->streamer != NULL)
1365 state->streamer = NULL;
1382 &
state->manifest_inject_streamer,
1392 if (
state->manifest_buffer != NULL)
1398 else if (
state->manifest_file !=NULL)
1401 if (fwrite(
copybuf + 1, r - 1, 1,
1402 state->manifest_file) != 1)
1410 pg_fatal(
"could not write to file \"%s\": %m",
1411 state->manifest_filename);
1414 else if (
state->streamer != NULL)
1421 pg_fatal(
"unexpected payload data");
1464 if (
state->manifest_inject_streamer != NULL)
1469 sizeof(
state->manifest_filename),
1470 "%s/backup_manifest.tmp",
basedir);
1471 state->manifest_file =
1472 fopen(
state->manifest_filename,
"wb");
1473 if (
state->manifest_file == NULL)
1474 pg_fatal(
"could not create file \"%s\": %m",
1475 state->manifest_filename);
1535 if (*
cursor +
sizeof(uint64) > r)
1538 *
cursor +=
sizeof(uint64);
1566 pg_fatal(
"malformed COPY message of type %d, length %zu",
1581 bool is_recovery_guc_supported;
1582 bool expect_unterminated_tarfile;
1586 is_recovery_guc_supported =
1588 expect_unterminated_tarfile =
1591 &manifest_inject_streamer,
1592 is_recovery_guc_supported,
1593 expect_unterminated_tarfile,
1595 state.tablespacenum = tablespacenum;
1605 if (manifest_inject_streamer != NULL)
1661 strlcpy(canon_dir, dir,
sizeof(canon_dir));
1665 if (strcmp(canon_dir, cell->
old_dir) == 0)
1680 "%s/backup_manifest.tmp",
basedir);
1682 if (
state.file == NULL)
1683 pg_fatal(
"could not create file \"%s\": %m",
state.filename);
1704 pg_fatal(
"could not write to file \"%s\": %m",
state->filename);
1722 void *callback_data)
1734 char *sysidentifier;
1740 char xlogend[64] = {0};
1745 int writing_to_stdout;
1746 bool use_new_option_syntax =
false;
1756 minServerMajor = 901;
1757 maxServerMajor = PG_VERSION_NUM / 100;
1759 serverMajor = serverVersion / 100;
1760 if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
1764 pg_fatal(
"incompatible server version %s",
1765 serverver ? serverver :
"'unknown'");
1767 if (serverMajor >= 1500)
1768 use_new_option_syntax =
true;
1806 if (use_new_option_syntax)
1808 "CHECKPOINT",
"fast");
1814 if (use_new_option_syntax)
1826 if (use_new_option_syntax)
1828 "VERIFY_CHECKSUMS", 0);
1831 "NOVERIFY_CHECKSUMS");
1847 if (serverMajor < 1500)
1848 pg_fatal(
"backup targets are not supported by this server version");
1851 pg_fatal(
"recovery configuration cannot be written when a backup target is used");
1868 "TARGET_DETAIL",
colon + 1);
1871 else if (serverMajor >= 1500)
1873 "TARGET",
"client");
1877 if (!use_new_option_syntax)
1878 pg_fatal(
"server does not support server-side compression");
1881 if (compression_detail != NULL)
1883 "COMPRESSION_DETAIL",
1884 compression_detail);
1888 pg_log_info(
"initiating base backup, waiting for checkpoint to complete");
1892 fprintf(stderr,
_(
"waiting for checkpoint"));
1893 if (isatty(fileno(stderr)))
1899 if (use_new_option_syntax &&
buf.len > 0)
1905 pg_fatal(
"could not send replication command \"%s\": %s",
1913 pg_fatal(
"could not initiate base backup: %s",
1916 pg_fatal(
"server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
1932 starttli = latesttli;
1936 pg_log_info(
"write-ahead log start point: %s on timeline %u",
1937 xlogstart, starttli);
1944 pg_fatal(
"could not get backup header: %s",
1947 pg_fatal(
"no data returned from server");
1990 pg_fatal(
"can only write single tablespace to stdout, database has %d",
2000 int wal_compress_level;
2008 wal_compress_level = client_compress->
level;
2013 wal_compress_level = 0;
2017 wal_compress_algorithm,
2018 wal_compress_level);
2021 if (serverMajor >= 1500)
2044 strlcpy(archive_name,
"base.tar",
sizeof(archive_name));
2049 snprintf(archive_name,
sizeof(archive_name),
2069 if (!writing_to_stdout &&
manifest)
2089 pg_fatal(
"no write-ahead log end position returned from server");
2092 pg_log_info(
"write-ahead log end point: %s", xlogend);
2126 intptr_t bgchild_handle =
bgchild;
2132 pg_log_info(
"waiting for background process to finish streaming ...");
2135 if (
write(
bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
2136 pg_fatal(
"could not send command to background pipe: %m");
2139 r = waitpid(
bgchild, &status, 0);
2140 if (r == (pid_t) -1)
2141 pg_fatal(
"could not wait for child process: %m");
2154 if (sscanf(xlogend,
"%X/%X", &hi, &lo) != 2)
2155 pg_fatal(
"could not parse write-ahead log location \"%s\"",
2161 if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
2165 pg_fatal(
"could not wait for child thread: %m");
2167 if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
2170 pg_fatal(
"could not get child thread exit status: %m");
2173 pg_fatal(
"child thread exited with error %u",
2174 (
unsigned int) status);
2205 if (strcmp(
basedir,
"-") != 0)
2227 pg_log_info(
"renaming backup_manifest.tmp to backup_manifest");
2240 if (rename(tmp_filename,
filename) != 0)
2241 pg_fatal(
"could not rename file \"%s\" to \"%s\": %m",
2254 static struct option long_options[] = {
2295 char *compression_detail = NULL;
2305 if (strcmp(argv[1],
"--help") == 0 || strcmp(argv[1],
"-?") == 0)
2310 else if (strcmp(argv[1],
"-V") == 0
2311 || strcmp(argv[1],
"--version") == 0)
2313 puts(
"pg_basebackup (PostgreSQL) " PG_VERSION);
2320 while ((
c =
getopt_long(argc, argv,
"c:Cd:D:F:h:l:nNp:Pr:Rs:S:t:T:U:vwWX:zZ:",
2321 long_options, &option_index)) != -1)
2331 pg_fatal(
"invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
2344 if (strcmp(
optarg,
"p") == 0 || strcmp(
optarg,
"plain") == 0)
2346 else if (strcmp(
optarg,
"t") == 0 || strcmp(
optarg,
"tar") == 0)
2349 pg_fatal(
"invalid output format \"%s\", must be \"plain\" or \"tar\"",
2411 if (strcmp(
optarg,
"n") == 0 ||
2412 strcmp(
optarg,
"none") == 0)
2416 else if (strcmp(
optarg,
"f") == 0 ||
2417 strcmp(
optarg,
"fetch") == 0)
2421 else if (strcmp(
optarg,
"s") == 0 ||
2422 strcmp(
optarg,
"stream") == 0)
2427 pg_fatal(
"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
2432 compression_detail = NULL;
2437 &compression_detail, &compressloc);
2476 pg_log_error(
"too many command-line arguments (first is \"%s\")",
2499 pg_log_error(
"cannot specify both format and backup target");
2511 pg_log_error(
"must specify output directory or backup target");
2517 pg_log_error(
"cannot specify both output directory and backup target");
2547 pg_fatal(
"unrecognized compression algorithm: \"%s\"",
2552 if (error_detail != NULL)
2553 pg_fatal(
"invalid compression specification: %s",
2569 pg_log_error(
"client-side compression is not possible when a backup target is specified");
2580 pg_log_error(
"only tar mode backups can be compressed");
2590 pg_log_error(
"WAL cannot be streamed when a backup target is specified");
2596 pg_log_error(
"cannot stream write-ahead logs in tar mode to stdout");
2603 pg_log_error(
"replication slots can only be used with WAL streaming");
2615 pg_log_error(
"--no-slot cannot be used with slot name");
2626 pg_log_error(
"%s needs a slot to be specified using --slot",
2635 "--create-slot",
"--no-slot");
2648 pg_log_error(
"WAL directory location cannot be specified along with a backup target");
2654 pg_log_error(
"WAL directory location can only be specified in plain mode");
2663 pg_log_error(
"WAL directory location must be an absolute path");
2675 "--progress",
"--no-estimate-size");
2686 "--no-manifest",
"--manifest-checksums");
2694 "--no-manifest",
"--manifest-force-encode");
2760 "pg_xlog" :
"pg_wal");
2763 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)
@ 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 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)
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
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