staticvoid
cleanup_directories_atexit(void)
{ if (success || in_log_streamer) return;
if (!noclean && !checksum_failure)
{ if (made_new_pgdata)
{
pg_log_info("removing data directory \"%s\"", basedir); if (!rmtree(basedir, true))
pg_log_error("failed to remove data directory");
} elseif (found_existing_pgdata)
{
pg_log_info("removing contents of data directory \"%s\"", basedir); if (!rmtree(basedir, false))
pg_log_error("failed to remove contents of data directory");
}
if (made_new_xlogdir)
{
pg_log_info("removing WAL directory \"%s\"", xlog_dir); if (!rmtree(xlog_dir, true))
pg_log_error("failed to remove WAL directory");
} elseif (found_existing_xlogdir)
{
pg_log_info("removing contents of WAL directory \"%s\"", xlog_dir); if (!rmtree(xlog_dir, false))
pg_log_error("failed to remove contents of WAL directory");
}
} else
{ if ((made_new_pgdata || found_existing_pgdata) && !checksum_failure)
pg_log_info("data directory \"%s\" not removed at user's request", basedir);
if (made_new_xlogdir || found_existing_xlogdir)
pg_log_info("WAL directory \"%s\" not removed at user's request", xlog_dir);
}
if ((made_tablespace_dirs || found_tablespace_dirs) && !checksum_failure)
pg_log_info("changes to tablespace directories will not be undone");
}
staticvoid
disconnect_atexit(void)
{ if (conn != NULL)
PQfinish(conn);
}
staticvoid
usage(void)
{
printf(_("%s takes a base backup of a running PostgreSQL server.\n\n"),
progname);
printf(_("Usage:\n"));
printf(_(" %s [OPTION]...\n"), progname);
printf(_("\nOptions controlling the output:\n"));
printf(_(" -D, --pgdata=DIRECTORY receive base backup into directory\n"));
printf(_(" -F, --format=p|t output format (plain (default), tar)\n"));
printf(_(" -i, --incremental=OLDMANIFEST\n" " take incremental backup\n"));
printf(_(" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n" " (in kB/s, or use suffix \"k\" or \"M\")\n"));
printf(_(" -R, --write-recovery-conf\n" " write configuration for replication\n"));
printf(_(" -t, --target=TARGET[:DETAIL]\n" " backup target (if other than client)\n"));
printf(_(" -T, --tablespace-mapping=OLDDIR=NEWDIR\n" " relocate tablespace in OLDDIR to NEWDIR\n"));
printf(_(" --waldir=WALDIR location for the write-ahead log directory\n"));
printf(_(" -X, --wal-method=none|fetch|stream\n" " include required WAL files with specified method\n"));
printf(_(" -z, --gzip compress tar output\n"));
printf(_(" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n" " compress on client or server as specified\n"));
printf(_(" -Z, --compress=none do not compress tar output\n"));
printf(_("\nGeneral options:\n"));
printf(_(" -c, --checkpoint=fast|spread\n" " set fast or spread (default) checkpointing\n"));
printf(_(" -C, --create-slot create replication slot\n"));
printf(_(" -l, --label=LABEL set backup label\n"));
printf(_(" -n, --no-clean do not clean up after errors\n"));
printf(_(" -N, --no-sync do not wait for changes to be written safely to disk\n"));
printf(_(" -P, --progress show progress information\n"));
printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
printf(_(" -v, --verbose output verbose messages\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n" " use algorithm for manifest checksums\n"));
printf(_(" --manifest-force-encode\n" " hex encode all file names in manifest\n"));
printf(_(" --no-estimate-size do not estimate backup size in server side\n"));
printf(_(" --no-manifest suppress generation of backup manifest\n"));
printf(_(" --no-slot prevent creation of temporary replication slot\n"));
printf(_(" --no-verify-checksums\n" " do not verify checksums\n"));
printf(_(" --sync-method=METHOD\n" " set method for syncing files to disk\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
printf(_(" -d, --dbname=CONNSTR connection string\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n" " time between status packets sent to server (in seconds)\n"));
printf(_(" -U, --username=NAME connect as specified database user\n"));
printf(_(" -w, --no-password never prompt for password\n"));
printf(_(" -W, --password force password prompt (should happen automatically)\n"));
printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
}
/* *Calledinthebackgroundprocesseverytimedataisreceived. *OnUnix,wechecktoseeifthereisanydataonourpipe *(whichwouldmeanwehaveastopposition),andifitis,checkif *itistimetostop. *OnWindows,weareinasingleprocess,sowecanjustcheckifit's *timetostop.
*/ staticbool
reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finished)
{ if (!has_xlogendptr)
{ #ifndef WIN32
fd_set fds; struct timeval tv = {0}; int r;
/* Convert the starting position */ if (sscanf(startpos, "%X/%X", &hi, &lo) != 2)
pg_fatal("could not parse write-ahead log location \"%s\"",
startpos);
param->startptr = ((uint64) hi) << 32 | lo; /* Round off to even segment position */
param->startptr -= XLogSegmentOffset(param->startptr, WalSegSz);
#ifndef WIN32 /* Create our background pipe */ if (pipe(bgpipe) < 0)
pg_fatal("could not create pipe for background process: %m"); #endif
/* Get a second connection */
param->bgconn = GetConnection(); if (!param->bgconn) /* Error message already written in GetConnection() */ exit(1);
/* In post-10 cluster, pg_xlog has been renamed to pg_wal */
snprintf(param->xlog, sizeof(param->xlog), "%s/%s",
basedir,
PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ? "pg_xlog" : "pg_wal");
/* Temporary replication slots are only supported in 10 and newer */ if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_TEMP_SLOTS)
temp_replication_slot = false;
/* *Createreplicationslotifrequested
*/ if (temp_replication_slot && !replication_slot)
replication_slot = psprintf("pg_basebackup_%u",
(unsignedint) PQbackendPID(param->bgconn)); if (temp_replication_slot || create_slot)
{ if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL,
temp_replication_slot, true, true, false, false, false)) exit(1);
if (verbose)
{ if (temp_replication_slot)
pg_log_info("created temporary replication slot \"%s\"",
replication_slot); else
pg_log_info("created replication slot \"%s\"",
replication_slot);
}
}
errno = 0;
result = strtod(src, &after_num); if (src == after_num)
pg_fatal("transfer rate \"%s\" is not a valid value", src); if (errno != 0)
pg_fatal("invalid transfer rate \"%s\": %m", src);
if (result <= 0)
{ /* *Rejectobviouslywrongvalueshere.
*/
pg_fatal("transfer rate must be greater than zero");
}
if (*after_num != '\0')
{
suffix = after_num; if (*after_num == 'k')
{ /* kilobyte is the expected unit. */
after_num++;
} elseif (*after_num == 'M')
{
after_num++;
result *= 1024.0;
}
}
/* The rest can only consist of white space. */ while (*after_num != '\0' && isspace((unsignedchar) *after_num))
after_num++;
if (*after_num != '\0')
pg_fatal("invalid --max-rate unit: \"%s\"", suffix);
/* Valid integer? */ if ((uint64) result != (uint64) ((uint32) result))
pg_fatal("transfer rate \"%s\" exceeds integer range", src);
/* *Therangeischeckedontheserversidetoo,butavoidtheserver *connectionifanonsensicalvaluewaspassed.
*/ if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
pg_fatal("transfer rate \"%s\" is out of range", src);
/* Get the COPY data stream. */
res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_OUT)
pg_fatal("could not get COPY data stream: %s",
PQerrorMessage(conn));
PQclear(res);
/* Loop over chunks until done. */ while (1)
{ int r; char *copybuf;
/* Is this a tar archive? */
is_tar = (archive_name_len > 4 &&
strcmp(archive_name + archive_name_len - 4, ".tar") == 0);
/* Is this a .tar.gz archive? */
is_tar_gz = (archive_name_len > 7 &&
strcmp(archive_name + archive_name_len - 7, ".tar.gz") == 0);
/* Is this a .tar.lz4 archive? */
is_tar_lz4 = (archive_name_len > 8 &&
strcmp(archive_name + archive_name_len - 8, ".tar.lz4") == 0);
/* Is this a .tar.zst archive? */
is_tar_zstd = (archive_name_len > 8 &&
strcmp(archive_name + archive_name_len - 8, ".tar.zst") == 0);
/* Is this any kind of compressed tar? */
is_compressed_tar = is_tar_gz || is_tar_lz4 || is_tar_zstd;
/* *Injectingthemanifestintoacompressedtarfilewouldbepossibleif *wedecompressedit,parsedthetarfile,generatedanewtarfile,and *recompressedit,butcompressinganddecompressingmultipletimesjust *toinjectthemanifestseemsinefficientenoughthatit'sprobablynot *whattheuserwants.So,instead,rejecttherequestandtelltheuser *tospecifysomethingmorereasonable.
*/ if (inject_manifest && is_compressed_tar)
{
pg_log_error("cannot inject manifest into a compressed tar file");
pg_log_error_hint("Use client-side compression, send the output to a directory rather than standard output, or use %s.", "--no-manifest"); exit(1);
}
/* At present, we only know how to parse tar archives. */ if (must_parse_archive && !is_tar && !is_compressed_tar)
{
pg_log_error("cannot parse archive \"%s\"", archive_name);
pg_log_error_detail("Only tar archives can be parsed."); if (format == 'p')
pg_log_error_detail("Plain format requires pg_basebackup to parse the archive."); if (inject_manifest)
pg_log_error_detail("Using - as the output directory requires pg_basebackup to parse the archive."); if (writerecoveryconf)
pg_log_error_detail("The -R option requires pg_basebackup to parse the archive."); exit(1);
}
/* Set up initial state. */
memset(&state, 0, sizeof(state));
state.tablespacenum = -1;
state.compress = compress;
/* All the real work happens in ReceiveArchiveStreamChunk. */
ReceiveCopyData(conn, ReceiveArchiveStreamChunk, &state);
/* If we wrote the backup manifest to a file, close the file. */ if (state.manifest_file !=NULL)
{
fclose(state.manifest_file);
state.manifest_file = NULL;
}
/* If there's still an archive in progress, end processing. */ if (state.streamer != NULL)
{
astreamer_finalize(state.streamer);
astreamer_free(state.streamer);
state.streamer = NULL;
}
}
/* Each CopyData message begins with a type byte. */ switch (GetCopyDataByte(r, copybuf, &cursor))
{ case'n':
{ /* New archive. */ char *archive_name; char *spclocation;
/* End processing of any prior archive. */ if (state->streamer != NULL)
{
astreamer_finalize(state->streamer);
astreamer_free(state->streamer);
state->streamer = NULL;
}
/* Slurp the entire backup manifest into a buffer. */
initPQExpBuffer(&buf);
ReceiveBackupManifestInMemory(conn, &buf); if (PQExpBufferDataBroken(buf))
pg_fatal("out of memory");
/* Inject it into the output tarfile. */
astreamer_inject_file(manifest_inject_streamer, "backup_manifest",
buf.data, buf.len);
errno = 0; if (fwrite(copybuf, r, 1, state->file) != 1)
{ /* if write didn't set errno, assume problem is no disk space */ if (errno == 0)
errno = ENOSPC;
pg_fatal("could not write to file \"%s\": %m", state->filename);
}
}
/* *RunIDENTIFY_SYSTEMsowecangetthetimeline
*/ if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL)) exit(1);
/* *Iftheuserwantsanincrementalbackup,wemustuploadthemanifest *forthepreviousbackupuponwhichitistobebased.
*/ if (incremental_manifest != NULL)
{ int fd; char mbuf[65536]; int nbytes;
/* Reject if server is too old. */ if (serverVersion < MINIMUM_VERSION_FOR_WAL_SUMMARIES)
pg_fatal("server does not support incremental backup");
/* Open the file. */
fd = open(incremental_manifest, O_RDONLY | PG_BINARY, 0); if (fd < 0)
pg_fatal("could not open file \"%s\": %m", incremental_manifest);
/* Tell the server what we want to do. */ if (PQsendQuery(conn, "UPLOAD_MANIFEST") == 0)
pg_fatal("could not send replication command \"%s\": %s", "UPLOAD_MANIFEST", PQerrorMessage(conn));
res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COPY_IN)
{ if (PQresultStatus(res) == PGRES_FATAL_ERROR)
pg_fatal("could not upload manifest: %s",
PQerrorMessage(conn)); else
pg_fatal("could not upload manifest: unexpected status %s",
PQresStatus(PQresultStatus(res)));
}
/* Loop, reading from the file and sending the data to the server. */ while ((nbytes = read(fd, mbuf, sizeof mbuf)) > 0)
{ if (PQputCopyData(conn, mbuf, nbytes) < 0)
pg_fatal("could not send COPY data: %s",
PQerrorMessage(conn));
}
/* Bail out if we exited the loop due to an error. */ if (nbytes < 0)
pg_fatal("could not read file \"%s\": %m", incremental_manifest);
/* End the COPY operation. */ if (PQputCopyEnd(conn, NULL) < 0)
pg_fatal("could not send end-of-COPY: %s",
PQerrorMessage(conn));
/* See whether the server is happy with what we sent. */
res = PQgetResult(conn); if (PQresultStatus(res) == PGRES_FATAL_ERROR)
pg_fatal("could not upload manifest: %s",
PQerrorMessage(conn)); elseif (PQresultStatus(res) != PGRES_COMMAND_OK)
pg_fatal("could not upload manifest: unexpected status %s",
PQresStatus(PQresultStatus(res)));
/* Consume ReadyForQuery message from server. */
res = PQgetResult(conn); if (res != NULL)
pg_fatal("unexpected extra result while sending manifest");
if (compressloc == COMPRESS_LOCATION_SERVER)
{ if (!use_new_option_syntax)
pg_fatal("server does not support server-side compression");
AppendStringCommandOption(&buf, use_new_option_syntax, "COMPRESSION", compression_algorithm); if (compression_detail != NULL)
AppendStringCommandOption(&buf, use_new_option_syntax, "COMPRESSION_DETAIL",
compression_detail);
}
if (verbose)
pg_log_info("initiating base backup, waiting for checkpoint to complete");
if (showprogress && !verbose)
{
fprintf(stderr, _("waiting for checkpoint")); if (isatty(fileno(stderr)))
fprintf(stderr, "\r"); else
fprintf(stderr, "\n");
}
/* OK, try to start the backup. */ if (PQsendQuery(conn, basebkp) == 0)
pg_fatal("could not send replication command \"%s\": %s", "BASE_BACKUP", PQerrorMessage(conn));
/* *GetthestartingWALlocation
*/
res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("could not initiate base backup: %s",
PQerrorMessage(conn)); if (PQntuples(res) != 1)
pg_fatal("server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields",
PQntuples(res), PQnfields(res), 1, 2);
if (verbose && includewal != NO_WAL)
pg_log_info("write-ahead log start point: %s on timeline %u",
xlogstart, starttli);
/* *Gettheheader
*/
res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("could not get backup header: %s",
PQerrorMessage(conn)); if (PQntuples(res) < 1)
pg_fatal("no data returned from server");
/* *Sumupthetotalsize,forprogressreporting
*/
totalsize_kb = totaldone = 0;
tablespacecount = PQntuples(res); for (i = 0; i < PQntuples(res); i++)
{
totalsize_kb += atoll(PQgetvalue(res, i, 2));
/* *Verifytablespacedirectoriesareempty.Don'tbotherwiththe *firstoncesinceitcanberelocated,anditwillbecheckedbefore *wedoanythinganyway. * *Notethatthisisskippedfortarformatbackupsandbackupsthat *theserverisstoringtoatargetlocation,sinceinthatcasewe *won'tbestoringanythingintothesedirectoriesandthusshould *notcreatethem.
*/ if (backup_target == NULL && format == 'p' && !PQgetisnull(res, i, 1))
{ char *path = PQgetvalue(res, i, 1);
if (is_absolute_path(path))
path = unconstify(char *, get_tablespace_mapping(path)); else
{ /* This is an in-place tablespace, so prepend basedir. */
path = psprintf("%s/%s", basedir, path);
}
if (serverMajor >= 1500)
{ /* Receive a single tar stream with everything. */
ReceiveArchiveStream(conn, client_compress);
} else
{ /* Receive a tar file for each tablespace in turn */ for (i = 0; i < PQntuples(res); i++)
{ char archive_name[MAXPGPATH]; char *spclocation;
/* *Ifwewritethedataouttoatarfile,itwillbenamed *base.tarifit'sthemaindatadirectoryor<tablespaceoid>.tar *ifit'sforanothertablespace.CreateBackupStreamer()will *arrangetoaddanextensiontothearchivenameif *pg_basebackupisperformingcompression,dependingonthe *compressiontype.
*/ if (PQgetisnull(res, i, 0))
{
strlcpy(archive_name, "base.tar", sizeof(archive_name));
spclocation = NULL;
} else
{
snprintf(archive_name, sizeof(archive_name), "%s.tar", PQgetvalue(res, i, 0));
spclocation = PQgetvalue(res, i, 1);
}
ReceiveTarFile(conn, archive_name, spclocation, i,
client_compress);
}
if (showprogress)
{
progress_update_filename(NULL);
progress_report(PQntuples(res), true, true);
}
PQclear(res);
/* *Getthestopposition
*/
res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_TUPLES_OK)
pg_fatal("backup failed: %s",
PQerrorMessage(conn)); if (PQntuples(res) != 1)
pg_fatal("no write-ahead log end position returned from server");
strlcpy(xlogend, PQgetvalue(res, 0, 0), sizeof(xlogend)); if (verbose && includewal != NO_WAL)
pg_log_info("write-ahead log end point: %s", xlogend);
PQclear(res);
res = PQgetResult(conn); if (PQresultStatus(res) != PGRES_COMMAND_OK)
{ constchar *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
if (verbose)
pg_log_info("waiting for background process to finish streaming ...");
#ifndef WIN32 if (write(bgpipe[1], xlogend, strlen(xlogend)) != strlen(xlogend))
pg_fatal("could not send command to background pipe: %m");
/* Just wait for the background process to exit */
r = waitpid(bgchild, &status, 0); if (r == (pid_t) -1)
pg_fatal("could not wait for child process: %m"); if (r != bgchild)
pg_fatal("child %d died, expected %d", (int) r, (int) bgchild); if (status != 0)
pg_fatal("%s", wait_result_to_str(status)); /* Exited normally, we're happy! */ #else/* WIN32 */
if (do_sync)
{ /* durable_rename emits its own log message in case of failure */ if (durable_rename(tmp_filename, filename) != 0) exit(1);
} else
{ if (rename(tmp_filename, filename) != 0)
pg_fatal("could not rename file \"%s\" to \"%s\": %m",
tmp_filename, filename);
}
}
if (verbose)
pg_log_info("base backup completed");
}
/* *Anynon-optionarguments?
*/ if (optind < argc)
{
pg_log_error("too many command-line arguments (first is \"%s\")",
argv[optind]);
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *Can'tuse--formatwith--target.Without--target,defaultformatis *tar.
*/ if (backup_target != NULL && format != '\0')
{
pg_log_error("cannot specify both format and backup target");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
} if (format == '\0')
format = 'p';
/* *Eitherdirectoryorbackuptargetshouldbespecified,butnotboth
*/ if (basedir == NULL && backup_target == NULL)
{
pg_log_error("must specify output directory or backup target");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
} if (basedir != NULL && backup_target != NULL)
{
pg_log_error("cannot specify both output directory and backup target");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *Can'tperformclient-sidecompressionifthebackupisnotbeingsent *totheclient.
*/ if (backup_target != NULL && compressloc == COMPRESS_LOCATION_CLIENT)
{
pg_log_error("client-side compression is not possible when a backup target is specified");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *Client-sidecompressiondoesn'tmakesenseunlesstarformatisinuse.
*/ if (format == 'p' && compressloc == COMPRESS_LOCATION_CLIENT &&
client_compress.algorithm != PG_COMPRESSION_NONE)
{
pg_log_error("only tar mode backups can be compressed");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *SanitychecksforWALmethod.
*/ if (backup_target != NULL && includewal == STREAM_WAL)
{
pg_log_error("WAL cannot be streamed when a backup target is specified");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
} if (format == 't' && includewal == STREAM_WAL && strcmp(basedir, "-") == 0)
{
pg_log_error("cannot stream write-ahead logs in tar mode to stdout");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
if (replication_slot && includewal != STREAM_WAL)
{
pg_log_error("replication slots can only be used with WAL streaming");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *Sanitychecksforreplicationslotoptions.
*/ if (no_slot)
{ if (replication_slot)
{
pg_log_error("--no-slot cannot be used with slot name");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
temp_replication_slot = false;
}
if (create_slot)
{ if (!replication_slot)
{
pg_log_error("%s needs a slot to be specified using --slot", "--create-slot");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
if (no_slot)
{
pg_log_error("%s and %s are incompatible options", "--create-slot", "--no-slot");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
}
/* *SanitychecksonWALdirectory.
*/ if (xlog_dir)
{ if (backup_target != NULL)
{
pg_log_error("WAL directory location cannot be specified along with a backup target");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
} if (format != 'p')
{
pg_log_error("WAL directory location can only be specified in plain mode");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* clean up xlog directory name, check it's absolute */
canonicalize_path(xlog_dir); if (!is_absolute_path(xlog_dir))
{
pg_log_error("WAL directory location must be an absolute path");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
}
/* *Sanitychecksforprogressreportingoptions.
*/ if (showprogress && !estimatesize)
{
pg_log_error("%s and %s are incompatible options", "--progress", "--no-estimate-size");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *Sanitychecksforbackupmanifestoptions.
*/ if (!manifest && manifest_checksums != NULL)
{
pg_log_error("%s and %s are incompatible options", "--no-manifest", "--manifest-checksums");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
if (!manifest && manifest_force_encode)
{
pg_log_error("%s and %s are incompatible options", "--no-manifest", "--manifest-force-encode");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* connection in replication mode to server */
conn = GetConnection(); if (!conn)
{ /* Error message already written in GetConnection() */ exit(1);
}
atexit(disconnect_atexit);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.