staticvoid
disconnect_atexit(void)
{ if (conn != NULL)
PQfinish(conn);
}
staticvoid
usage(void)
{
printf(_("%s receives PostgreSQL streaming write-ahead logs.\n\n"),
progname);
printf(_("Usage:\n"));
printf(_(" %s [OPTION]...\n"), progname);
printf(_("\nOptions:\n"));
printf(_(" -D, --directory=DIR receive write-ahead log files into this directory\n"));
printf(_(" -E, --endpos=LSN exit after receiving the specified LSN\n"));
printf(_(" --if-not-exists do not error if slot already exists when creating a slot\n"));
printf(_(" -n, --no-loop do not loop on connection lost\n"));
printf(_(" --no-sync do not wait for changes to be written safely to disk\n"));
printf(_(" -s, --status-interval=SECS\n" " time between status packets sent to server (default: %d)\n"), (standby_message_timeout / 1000));
printf(_(" -S, --slot=SLOTNAME replication slot to use\n"));
printf(_(" --synchronous flush write-ahead log immediately after writing\n"));
printf(_(" -v, --verbose output verbose messages\n"));
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -Z, --compress=METHOD[:DETAIL]\n" " compress as specified\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(_(" -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(_("\nOptional actions:\n"));
printf(_(" --create-slot create a new replication slot (for the slot's name see --slot)\n"));
printf(_(" --drop-slot drop the replication slot (for the slot's name see --slot)\n"));
printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
}
/* we assume that we get called once at the end of each segment */ if (verbose && segment_finished)
pg_log_info("finished segment at %X/%X (timeline %u)",
LSN_FORMAT_ARGS(xlogpos),
timeline);
if (!XLogRecPtrIsInvalid(endpos) && endpos < xlogpos)
{ if (verbose)
pg_log_info("stopped log streaming at %X/%X (timeline %u)",
LSN_FORMAT_ARGS(xlogpos),
timeline);
time_to_stop = true; returntrue;
}
/* *Notethatwereporttheprevious,notcurrent,positionhere.Aftera *timelineswitch,xlogpospointstothebeginningofthesegmentbecause *that'swherewealwaysbeginstreaming.Reportingtheendofprevious *timelineisn'ttotallyaccurate,becausethenexttimelinecanbegin *slightlybeforetheendoftheWALthatwereceivedontheprevious *timeline,butit'scloseenoughforreportingpurposes.
*/ if (verbose && prevtimeline != 0 && prevtimeline != timeline)
pg_log_info("switched to timeline %u at %X/%X",
timeline,
LSN_FORMAT_ARGS(prevpos));
prevtimeline = timeline;
prevpos = xlogpos;
if (time_to_stop)
{ if (verbose)
pg_log_info("received interrupt signal, exiting"); returntrue;
} returnfalse;
}
/* *Getdestinationdirectory.
*/ static DIR *
get_destination_dir(char *dest_folder)
{
DIR *dir;
Assert(dest_folder != NULL);
dir = opendir(dest_folder); if (dir == NULL)
pg_fatal("could not open directory \"%s\": %m", dest_folder);
return dir;
}
/* *Closeexistingdirectory.
*/ staticvoid
close_destination_dir(DIR *dest_dir, char *dest_folder)
{
Assert(dest_dir != NULL && dest_folder != NULL); if (closedir(dest_dir))
pg_fatal("could not close directory \"%s\": %m", dest_folder);
}
fd = open(fullpath, O_RDONLY | PG_BINARY, 0); if (fd < 0)
pg_fatal("could not open file \"%s\": %m", fullpath);
status = LZ4F_createDecompressionContext(&ctx, LZ4F_VERSION); if (LZ4F_isError(status))
pg_fatal("could not create LZ4 decompression context: %s",
LZ4F_getErrorName(status));
/* *Noneedtocontinuereadingthefilewhenthe *uncompressed_sizeexceedsWalSegSz,eveniftherearestill *datalefttoread.However,ifuncompressed_sizeisequal *toWalSegSz,itshouldverifythatthereisnomoredatato *read.
*/
} while (uncompressed_size <= WalSegSz && r > 0);
close(fd);
pg_free(outbuf);
pg_free(readbuf);
status = LZ4F_freeDecompressionContext(ctx); if (LZ4F_isError(status))
pg_fatal("could not free LZ4 decompression context: %s",
LZ4F_getErrorName(status));
if (uncompressed_size != WalSegSz)
{
pg_log_warning("compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping",
dirent->d_name, uncompressed_size); continue;
} #else
pg_log_error("cannot check file \"%s\": compression with %s not supported by this build",
dirent->d_name, "LZ4"); exit(1); #endif
}
/* Looks like a valid segment. Remember that we saw it. */ if ((segno > high_segno) ||
(segno == high_segno && tli > high_tli) ||
(segno == high_segno && tli == high_tli && high_ispartial && !ispartial))
{
high_segno = segno;
high_tli = tli;
high_ispartial = ispartial;
}
}
if (errno)
pg_fatal("could not read directory \"%s\": %m", basedir);
close_destination_dir(dir, basedir);
if (high_segno > 0)
{
XLogRecPtr high_ptr;
/* *Movethestartingpointertothestartofthenextsegment,ifthe *highestonewesawwascompleted.Otherwisestartstreamingfrom *thebeginningofthe.partialsegment.
*/ if (!high_ispartial)
high_segno++;
/* *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);
}
if (do_drop_slot && do_create_slot)
{
pg_log_error("cannot use --create-slot together with --drop-slot");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
if (replication_slot == NULL && (do_drop_slot || do_create_slot))
{ /* translator: second %s is an option name */
pg_log_error("%s needs a slot to be specified using --slot",
do_drop_slot ? "--drop-slot" : "--create-slot");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
if (synchronous && !do_sync)
{
pg_log_error("cannot use --synchronous together with --no-sync");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
/* *Requiredarguments
*/ if (basedir == NULL && !do_drop_slot && !do_create_slot)
{
pg_log_error("no target directory specified");
pg_log_error_hint("Try \"%s --help\" for more information.", progname); exit(1);
}
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.