summaryrefslogtreecommitdiffstats
path: root/src/bin/pg_basebackup
diff options
context:
space:
mode:
Diffstat (limited to 'src/bin/pg_basebackup')
-rw-r--r--src/bin/pg_basebackup/.gitignore5
-rw-r--r--src/bin/pg_basebackup/Makefile84
-rw-r--r--src/bin/pg_basebackup/bbstreamer.h226
-rw-r--r--src/bin/pg_basebackup/bbstreamer_file.c374
-rw-r--r--src/bin/pg_basebackup/bbstreamer_gzip.c364
-rw-r--r--src/bin/pg_basebackup/bbstreamer_inject.c249
-rw-r--r--src/bin/pg_basebackup/bbstreamer_lz4.c422
-rw-r--r--src/bin/pg_basebackup/bbstreamer_tar.c516
-rw-r--r--src/bin/pg_basebackup/bbstreamer_zstd.c355
-rw-r--r--src/bin/pg_basebackup/nls.mk23
-rw-r--r--src/bin/pg_basebackup/pg_basebackup.c2796
-rw-r--r--src/bin/pg_basebackup/pg_receivewal.c992
-rw-r--r--src/bin/pg_basebackup/pg_recvlogical.c1039
-rw-r--r--src/bin/pg_basebackup/po/de.po1812
-rw-r--r--src/bin/pg_basebackup/po/el.po1839
-rw-r--r--src/bin/pg_basebackup/po/es.po1813
-rw-r--r--src/bin/pg_basebackup/po/fr.po2197
-rw-r--r--src/bin/pg_basebackup/po/it.po1937
-rw-r--r--src/bin/pg_basebackup/po/ja.po1813
-rw-r--r--src/bin/pg_basebackup/po/ka.po1997
-rw-r--r--src/bin/pg_basebackup/po/ko.po1917
-rw-r--r--src/bin/pg_basebackup/po/ru.po2178
-rw-r--r--src/bin/pg_basebackup/po/sv.po1805
-rw-r--r--src/bin/pg_basebackup/po/uk.po1759
-rw-r--r--src/bin/pg_basebackup/receivelog.c1276
-rw-r--r--src/bin/pg_basebackup/receivelog.h57
-rw-r--r--src/bin/pg_basebackup/streamutil.c864
-rw-r--r--src/bin/pg_basebackup/streamutil.h68
-rw-r--r--src/bin/pg_basebackup/t/010_pg_basebackup.pl945
-rw-r--r--src/bin/pg_basebackup/t/020_pg_receivewal.pl326
-rw-r--r--src/bin/pg_basebackup/t/030_pg_recvlogical.pl113
-rw-r--r--src/bin/pg_basebackup/walmethods.c1386
-rw-r--r--src/bin/pg_basebackup/walmethods.h107
33 files changed, 33654 insertions, 0 deletions
diff --git a/src/bin/pg_basebackup/.gitignore b/src/bin/pg_basebackup/.gitignore
new file mode 100644
index 0000000..26048bd
--- /dev/null
+++ b/src/bin/pg_basebackup/.gitignore
@@ -0,0 +1,5 @@
+/pg_basebackup
+/pg_receivewal
+/pg_recvlogical
+
+/tmp_check/
diff --git a/src/bin/pg_basebackup/Makefile b/src/bin/pg_basebackup/Makefile
new file mode 100644
index 0000000..0035ebc
--- /dev/null
+++ b/src/bin/pg_basebackup/Makefile
@@ -0,0 +1,84 @@
+#-------------------------------------------------------------------------
+#
+# Makefile for src/bin/pg_basebackup
+#
+# Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+# Portions Copyright (c) 1994, Regents of the University of California
+#
+# src/bin/pg_basebackup/Makefile
+#
+#-------------------------------------------------------------------------
+
+PGFILEDESC = "pg_basebackup/pg_receivewal/pg_recvlogical - streaming WAL and backup receivers"
+PGAPPICON=win32
+
+EXTRA_INSTALL=contrib/test_decoding
+
+subdir = src/bin/pg_basebackup
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+# make these available to TAP test scripts
+export LZ4
+export TAR
+# Note that GZIP cannot be used directly as this environment variable is
+# used by the command "gzip" to pass down options, so stick with a different
+# name.
+export GZIP_PROGRAM=$(GZIP)
+
+override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
+LDFLAGS_INTERNAL += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport)
+
+OBJS = \
+ $(WIN32RES) \
+ receivelog.o \
+ streamutil.o \
+ walmethods.o
+
+# If you add or remove files here, also update Mkvcbuild.pm, which only knows
+# about OBJS, not BBOBJS, and thus has to be manually updated to stay in sync
+# with this list.
+BBOBJS = \
+ pg_basebackup.o \
+ bbstreamer_file.o \
+ bbstreamer_gzip.o \
+ bbstreamer_inject.o \
+ bbstreamer_lz4.o \
+ bbstreamer_zstd.o \
+ bbstreamer_tar.o
+
+all: pg_basebackup pg_receivewal pg_recvlogical
+
+pg_basebackup: $(BBOBJS) $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
+ $(CC) $(CFLAGS) $(BBOBJS) $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+
+pg_receivewal: pg_receivewal.o $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
+ $(CC) $(CFLAGS) pg_receivewal.o $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+
+pg_recvlogical: pg_recvlogical.o $(OBJS) | submake-libpq submake-libpgport submake-libpgfeutils
+ $(CC) $(CFLAGS) pg_recvlogical.o $(OBJS) $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+
+install: all installdirs
+ $(INSTALL_PROGRAM) pg_basebackup$(X) '$(DESTDIR)$(bindir)/pg_basebackup$(X)'
+ $(INSTALL_PROGRAM) pg_receivewal$(X) '$(DESTDIR)$(bindir)/pg_receivewal$(X)'
+ $(INSTALL_PROGRAM) pg_recvlogical$(X) '$(DESTDIR)$(bindir)/pg_recvlogical$(X)'
+
+installdirs:
+ $(MKDIR_P) '$(DESTDIR)$(bindir)'
+
+uninstall:
+ rm -f '$(DESTDIR)$(bindir)/pg_basebackup$(X)'
+ rm -f '$(DESTDIR)$(bindir)/pg_receivewal$(X)'
+ rm -f '$(DESTDIR)$(bindir)/pg_recvlogical$(X)'
+
+clean distclean maintainer-clean:
+ rm -f pg_basebackup$(X) pg_receivewal$(X) pg_recvlogical$(X) \
+ $(BBOBJS) pg_receivewal.o pg_recvlogical.o \
+ $(OBJS)
+ rm -rf tmp_check
+
+check:
+ $(prove_check)
+
+installcheck:
+ $(prove_installcheck)
diff --git a/src/bin/pg_basebackup/bbstreamer.h b/src/bin/pg_basebackup/bbstreamer.h
new file mode 100644
index 0000000..29b48ef
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer.h
@@ -0,0 +1,226 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer.h
+ *
+ * Each tar archive returned by the server is passed to one or more
+ * bbstreamer objects for further processing. The bbstreamer may do
+ * something simple, like write the archive to a file, perhaps after
+ * compressing it, but it can also do more complicated things, like
+ * annotating the byte stream to indicate which parts of the data
+ * correspond to tar headers or trailing padding, vs. which parts are
+ * payload data. A subsequent bbstreamer may use this information to
+ * make further decisions about how to process the data; for example,
+ * it might choose to modify the archive contents.
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer.h
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef BBSTREAMER_H
+#define BBSTREAMER_H
+
+#include "common/compression.h"
+#include "lib/stringinfo.h"
+#include "pqexpbuffer.h"
+
+struct bbstreamer;
+struct bbstreamer_ops;
+typedef struct bbstreamer bbstreamer;
+typedef struct bbstreamer_ops bbstreamer_ops;
+
+/*
+ * Each chunk of archive data passed to a bbstreamer is classified into one
+ * of these categories. When data is first received from the remote server,
+ * each chunk will be categorized as BBSTREAMER_UNKNOWN, and the chunks will
+ * be of whatever size the remote server chose to send.
+ *
+ * If the archive is parsed (e.g. see bbstreamer_tar_parser_new()), then all
+ * chunks should be labelled as one of the other types listed here. In
+ * addition, there should be exactly one BBSTREAMER_MEMBER_HEADER chunk and
+ * exactly one BBSTREAMER_MEMBER_TRAILER chunk per archive member, even if
+ * that means a zero-length call. There can be any number of
+ * BBSTREAMER_MEMBER_CONTENTS chunks in between those calls. There
+ * should exactly BBSTREAMER_ARCHIVE_TRAILER chunk, and it should follow the
+ * last BBSTREAMER_MEMBER_TRAILER chunk.
+ *
+ * In theory, we could need other classifications here, such as a way of
+ * indicating an archive header, but the "tar" format doesn't need anything
+ * else, so for the time being there's no point.
+ */
+typedef enum
+{
+ BBSTREAMER_UNKNOWN,
+ BBSTREAMER_MEMBER_HEADER,
+ BBSTREAMER_MEMBER_CONTENTS,
+ BBSTREAMER_MEMBER_TRAILER,
+ BBSTREAMER_ARCHIVE_TRAILER
+} bbstreamer_archive_context;
+
+/*
+ * Each chunk of data that is classified as BBSTREAMER_MEMBER_HEADER,
+ * BBSTREAMER_MEMBER_CONTENTS, or BBSTREAMER_MEMBER_TRAILER should also
+ * pass a pointer to an instance of this struct. The details are expected
+ * to be present in the archive header and used to fill the struct, after
+ * which all subsequent calls for the same archive member are expected to
+ * pass the same details.
+ */
+typedef struct
+{
+ char pathname[MAXPGPATH];
+ pgoff_t size;
+ mode_t mode;
+ uid_t uid;
+ gid_t gid;
+ bool is_directory;
+ bool is_link;
+ char linktarget[MAXPGPATH];
+} bbstreamer_member;
+
+/*
+ * Generally, each type of bbstreamer will define its own struct, but the
+ * first element should be 'bbstreamer base'. A bbstreamer that does not
+ * require any additional private data could use this structure directly.
+ *
+ * bbs_ops is a pointer to the bbstreamer_ops object which contains the
+ * function pointers appropriate to this type of bbstreamer.
+ *
+ * bbs_next is a pointer to the successor bbstreamer, for those types of
+ * bbstreamer which forward data to a successor. It need not be used and
+ * should be set to NULL when not relevant.
+ *
+ * bbs_buffer is a buffer for accumulating data for temporary storage. Each
+ * type of bbstreamer makes its own decisions about whether and how to use
+ * this buffer.
+ */
+struct bbstreamer
+{
+ const bbstreamer_ops *bbs_ops;
+ bbstreamer *bbs_next;
+ StringInfoData bbs_buffer;
+};
+
+/*
+ * There are three callbacks for a bbstreamer. The 'content' callback is
+ * called repeatedly, as described in the bbstreamer_archive_context comments.
+ * Then, the 'finalize' callback is called once at the end, to give the
+ * bbstreamer a chance to perform cleanup such as closing files. Finally,
+ * because this code is running in a frontend environment where, as of this
+ * writing, there are no memory contexts, the 'free' callback is called to
+ * release memory. These callbacks should always be invoked using the static
+ * inline functions defined below.
+ */
+struct bbstreamer_ops
+{
+ void (*content) (bbstreamer *streamer, bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+ void (*finalize) (bbstreamer *streamer);
+ void (*free) (bbstreamer *streamer);
+};
+
+/* Send some content to a bbstreamer. */
+static inline void
+bbstreamer_content(bbstreamer *streamer, bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ Assert(streamer != NULL);
+ streamer->bbs_ops->content(streamer, member, data, len, context);
+}
+
+/* Finalize a bbstreamer. */
+static inline void
+bbstreamer_finalize(bbstreamer *streamer)
+{
+ Assert(streamer != NULL);
+ streamer->bbs_ops->finalize(streamer);
+}
+
+/* Free a bbstreamer. */
+static inline void
+bbstreamer_free(bbstreamer *streamer)
+{
+ Assert(streamer != NULL);
+ streamer->bbs_ops->free(streamer);
+}
+
+/*
+ * This is a convenience method for use when implementing a bbstreamer; it is
+ * not for use by outside callers. It adds the amount of data specified by
+ * 'nbytes' to the bbstreamer's buffer and adjusts '*len' and '*data'
+ * accordingly.
+ */
+static inline void
+bbstreamer_buffer_bytes(bbstreamer *streamer, const char **data, int *len,
+ int nbytes)
+{
+ Assert(nbytes <= *len);
+
+ appendBinaryStringInfo(&streamer->bbs_buffer, *data, nbytes);
+ *len -= nbytes;
+ *data += nbytes;
+}
+
+/*
+ * This is a convenence method for use when implementing a bbstreamer; it is
+ * not for use by outsider callers. It attempts to add enough data to the
+ * bbstreamer's buffer to reach a length of target_bytes and adjusts '*len'
+ * and '*data' accordingly. It returns true if the target length has been
+ * reached and false otherwise.
+ */
+static inline bool
+bbstreamer_buffer_until(bbstreamer *streamer, const char **data, int *len,
+ int target_bytes)
+{
+ int buflen = streamer->bbs_buffer.len;
+
+ if (buflen >= target_bytes)
+ {
+ /* Target length already reached; nothing to do. */
+ return true;
+ }
+
+ if (buflen + *len < target_bytes)
+ {
+ /* Not enough data to reach target length; buffer all of it. */
+ bbstreamer_buffer_bytes(streamer, data, len, *len);
+ return false;
+ }
+
+ /* Buffer just enough to reach the target length. */
+ bbstreamer_buffer_bytes(streamer, data, len, target_bytes - buflen);
+ return true;
+}
+
+/*
+ * Functions for creating bbstreamer objects of various types. See the header
+ * comments for each of these functions for details.
+ */
+extern bbstreamer *bbstreamer_plain_writer_new(char *pathname, FILE *file);
+extern bbstreamer *bbstreamer_gzip_writer_new(char *pathname, FILE *file,
+ pg_compress_specification *compress);
+extern bbstreamer *bbstreamer_extractor_new(const char *basepath,
+ const char *(*link_map) (const char *),
+ void (*report_output_file) (const char *));
+
+extern bbstreamer *bbstreamer_gzip_decompressor_new(bbstreamer *next);
+extern bbstreamer *bbstreamer_lz4_compressor_new(bbstreamer *next,
+ pg_compress_specification *compress);
+extern bbstreamer *bbstreamer_lz4_decompressor_new(bbstreamer *next);
+extern bbstreamer *bbstreamer_zstd_compressor_new(bbstreamer *next,
+ pg_compress_specification *compress);
+extern bbstreamer *bbstreamer_zstd_decompressor_new(bbstreamer *next);
+extern bbstreamer *bbstreamer_tar_parser_new(bbstreamer *next);
+extern bbstreamer *bbstreamer_tar_terminator_new(bbstreamer *next);
+extern bbstreamer *bbstreamer_tar_archiver_new(bbstreamer *next);
+
+extern bbstreamer *bbstreamer_recovery_injector_new(bbstreamer *next,
+ bool is_recovery_guc_supported,
+ PQExpBuffer recoveryconfcontents);
+extern void bbstreamer_inject_file(bbstreamer *streamer, char *pathname,
+ char *data, int len);
+
+#endif
diff --git a/src/bin/pg_basebackup/bbstreamer_file.c b/src/bin/pg_basebackup/bbstreamer_file.c
new file mode 100644
index 0000000..1a94fb2
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer_file.c
@@ -0,0 +1,374 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer_file.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer_file.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <unistd.h>
+
+#include "bbstreamer.h"
+#include "common/logging.h"
+#include "common/file_perm.h"
+#include "common/string.h"
+
+typedef struct bbstreamer_plain_writer
+{
+ bbstreamer base;
+ char *pathname;
+ FILE *file;
+ bool should_close_file;
+} bbstreamer_plain_writer;
+
+typedef struct bbstreamer_extractor
+{
+ bbstreamer base;
+ char *basepath;
+ const char *(*link_map) (const char *);
+ void (*report_output_file) (const char *);
+ char filename[MAXPGPATH];
+ FILE *file;
+} bbstreamer_extractor;
+
+static void bbstreamer_plain_writer_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_plain_writer_finalize(bbstreamer *streamer);
+static void bbstreamer_plain_writer_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_plain_writer_ops = {
+ .content = bbstreamer_plain_writer_content,
+ .finalize = bbstreamer_plain_writer_finalize,
+ .free = bbstreamer_plain_writer_free
+};
+
+static void bbstreamer_extractor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_extractor_finalize(bbstreamer *streamer);
+static void bbstreamer_extractor_free(bbstreamer *streamer);
+static void extract_directory(const char *filename, mode_t mode);
+static void extract_link(const char *filename, const char *linktarget);
+static FILE *create_file_for_extract(const char *filename, mode_t mode);
+
+const bbstreamer_ops bbstreamer_extractor_ops = {
+ .content = bbstreamer_extractor_content,
+ .finalize = bbstreamer_extractor_finalize,
+ .free = bbstreamer_extractor_free
+};
+
+/*
+ * Create a bbstreamer that just writes data to a file.
+ *
+ * The caller must specify a pathname and may specify a file. The pathname is
+ * used for error-reporting purposes either way. If file is NULL, the pathname
+ * also identifies the file to which the data should be written: it is opened
+ * for writing and closed when done. If file is not NULL, the data is written
+ * there.
+ */
+bbstreamer *
+bbstreamer_plain_writer_new(char *pathname, FILE *file)
+{
+ bbstreamer_plain_writer *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer_plain_writer));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_plain_writer_ops;
+
+ streamer->pathname = pstrdup(pathname);
+ streamer->file = file;
+
+ if (file == NULL)
+ {
+ streamer->file = fopen(pathname, "wb");
+ if (streamer->file == NULL)
+ pg_fatal("could not create file \"%s\": %m", pathname);
+ streamer->should_close_file = true;
+ }
+
+ return &streamer->base;
+}
+
+/*
+ * Write archive content to file.
+ */
+static void
+bbstreamer_plain_writer_content(bbstreamer *streamer,
+ bbstreamer_member *member, const char *data,
+ int len, bbstreamer_archive_context context)
+{
+ bbstreamer_plain_writer *mystreamer;
+
+ mystreamer = (bbstreamer_plain_writer *) streamer;
+
+ if (len == 0)
+ return;
+
+ errno = 0;
+ if (fwrite(data, len, 1, mystreamer->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",
+ mystreamer->pathname);
+ }
+}
+
+/*
+ * End-of-archive processing when writing to a plain file consists of closing
+ * the file if we opened it, but not if the caller provided it.
+ */
+static void
+bbstreamer_plain_writer_finalize(bbstreamer *streamer)
+{
+ bbstreamer_plain_writer *mystreamer;
+
+ mystreamer = (bbstreamer_plain_writer *) streamer;
+
+ if (mystreamer->should_close_file && fclose(mystreamer->file) != 0)
+ pg_fatal("could not close file \"%s\": %m",
+ mystreamer->pathname);
+
+ mystreamer->file = NULL;
+ mystreamer->should_close_file = false;
+}
+
+/*
+ * Free memory associated with this bbstreamer.
+ */
+static void
+bbstreamer_plain_writer_free(bbstreamer *streamer)
+{
+ bbstreamer_plain_writer *mystreamer;
+
+ mystreamer = (bbstreamer_plain_writer *) streamer;
+
+ Assert(!mystreamer->should_close_file);
+ Assert(mystreamer->base.bbs_next == NULL);
+
+ pfree(mystreamer->pathname);
+ pfree(mystreamer);
+}
+
+/*
+ * Create a bbstreamer that extracts an archive.
+ *
+ * All pathnames in the archive are interpreted relative to basepath.
+ *
+ * Unlike e.g. bbstreamer_plain_writer_new() we can't do anything useful here
+ * with untyped chunks; we need typed chunks which follow the rules described
+ * in bbstreamer.h. Assuming we have that, we don't need to worry about the
+ * original archive format; it's enough to just look at the member information
+ * provided and write to the corresponding file.
+ *
+ * 'link_map' is a function that will be applied to the target of any
+ * symbolic link, and which should return a replacement pathname to be used
+ * in its place. If NULL, the symbolic link target is used without
+ * modification.
+ *
+ * 'report_output_file' is a function that will be called each time we open a
+ * new output file. The pathname to that file is passed as an argument. If
+ * NULL, the call is skipped.
+ */
+bbstreamer *
+bbstreamer_extractor_new(const char *basepath,
+ const char *(*link_map) (const char *),
+ void (*report_output_file) (const char *))
+{
+ bbstreamer_extractor *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer_extractor));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_extractor_ops;
+ streamer->basepath = pstrdup(basepath);
+ streamer->link_map = link_map;
+ streamer->report_output_file = report_output_file;
+
+ return &streamer->base;
+}
+
+/*
+ * Extract archive contents to the filesystem.
+ */
+static void
+bbstreamer_extractor_content(bbstreamer *streamer, bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_extractor *mystreamer = (bbstreamer_extractor *) streamer;
+ int fnamelen;
+
+ Assert(member != NULL || context == BBSTREAMER_ARCHIVE_TRAILER);
+ Assert(context != BBSTREAMER_UNKNOWN);
+
+ switch (context)
+ {
+ case BBSTREAMER_MEMBER_HEADER:
+ Assert(mystreamer->file == NULL);
+
+ /* Prepend basepath. */
+ snprintf(mystreamer->filename, sizeof(mystreamer->filename),
+ "%s/%s", mystreamer->basepath, member->pathname);
+
+ /* Remove any trailing slash. */
+ fnamelen = strlen(mystreamer->filename);
+ if (mystreamer->filename[fnamelen - 1] == '/')
+ mystreamer->filename[fnamelen - 1] = '\0';
+
+ /* Dispatch based on file type. */
+ if (member->is_directory)
+ extract_directory(mystreamer->filename, member->mode);
+ else if (member->is_link)
+ {
+ const char *linktarget = member->linktarget;
+
+ if (mystreamer->link_map)
+ linktarget = mystreamer->link_map(linktarget);
+ extract_link(mystreamer->filename, linktarget);
+ }
+ else
+ mystreamer->file =
+ create_file_for_extract(mystreamer->filename,
+ member->mode);
+
+ /* Report output file change. */
+ if (mystreamer->report_output_file)
+ mystreamer->report_output_file(mystreamer->filename);
+ break;
+
+ case BBSTREAMER_MEMBER_CONTENTS:
+ if (mystreamer->file == NULL)
+ break;
+
+ errno = 0;
+ if (len > 0 && fwrite(data, len, 1, mystreamer->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",
+ mystreamer->filename);
+ }
+ break;
+
+ case BBSTREAMER_MEMBER_TRAILER:
+ if (mystreamer->file == NULL)
+ break;
+ fclose(mystreamer->file);
+ mystreamer->file = NULL;
+ break;
+
+ case BBSTREAMER_ARCHIVE_TRAILER:
+ break;
+
+ default:
+ /* Shouldn't happen. */
+ pg_fatal("unexpected state while extracting archive");
+ }
+}
+
+/*
+ * Create a directory.
+ */
+static void
+extract_directory(const char *filename, mode_t mode)
+{
+ if (mkdir(filename, pg_dir_create_mode) != 0)
+ {
+ /*
+ * When streaming WAL, pg_wal (or pg_xlog for pre-9.6 clusters) will
+ * have been created by the wal receiver process. Also, when the WAL
+ * directory location was specified, pg_wal (or pg_xlog) has already
+ * been created as a symbolic link before starting the actual backup.
+ * So just ignore creation failures on related directories.
+ */
+ if (!((pg_str_endswith(filename, "/pg_wal") ||
+ pg_str_endswith(filename, "/pg_xlog") ||
+ pg_str_endswith(filename, "/archive_status")) &&
+ errno == EEXIST))
+ pg_fatal("could not create directory \"%s\": %m",
+ filename);
+ }
+
+#ifndef WIN32
+ if (chmod(filename, mode))
+ pg_fatal("could not set permissions on directory \"%s\": %m",
+ filename);
+#endif
+}
+
+/*
+ * Create a symbolic link.
+ *
+ * It's most likely a link in pg_tblspc directory, to the location of a
+ * tablespace. Apply any tablespace mapping given on the command line
+ * (--tablespace-mapping). (We blindly apply the mapping without checking that
+ * the link really is inside pg_tblspc. We don't expect there to be other
+ * symlinks in a data directory, but if there are, you can call it an
+ * undocumented feature that you can map them too.)
+ */
+static void
+extract_link(const char *filename, const char *linktarget)
+{
+ if (symlink(linktarget, filename) != 0)
+ pg_fatal("could not create symbolic link from \"%s\" to \"%s\": %m",
+ filename, linktarget);
+}
+
+/*
+ * Create a regular file.
+ *
+ * Return the resulting handle so we can write the content to the file.
+ */
+static FILE *
+create_file_for_extract(const char *filename, mode_t mode)
+{
+ FILE *file;
+
+ file = fopen(filename, "wb");
+ if (file == NULL)
+ pg_fatal("could not create file \"%s\": %m", filename);
+
+#ifndef WIN32
+ if (chmod(filename, mode))
+ pg_fatal("could not set permissions on file \"%s\": %m",
+ filename);
+#endif
+
+ return file;
+}
+
+/*
+ * End-of-stream processing for extracting an archive.
+ *
+ * There's nothing to do here but sanity checking.
+ */
+static void
+bbstreamer_extractor_finalize(bbstreamer *streamer)
+{
+ bbstreamer_extractor *mystreamer PG_USED_FOR_ASSERTS_ONLY
+ = (bbstreamer_extractor *) streamer;
+
+ Assert(mystreamer->file == NULL);
+}
+
+/*
+ * Free memory.
+ */
+static void
+bbstreamer_extractor_free(bbstreamer *streamer)
+{
+ bbstreamer_extractor *mystreamer = (bbstreamer_extractor *) streamer;
+
+ pfree(mystreamer->basepath);
+ pfree(mystreamer);
+}
diff --git a/src/bin/pg_basebackup/bbstreamer_gzip.c b/src/bin/pg_basebackup/bbstreamer_gzip.c
new file mode 100644
index 0000000..c3455ff
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer_gzip.c
@@ -0,0 +1,364 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer_gzip.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer_gzip.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <unistd.h>
+
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "bbstreamer.h"
+#include "common/logging.h"
+#include "common/file_perm.h"
+#include "common/string.h"
+
+#ifdef HAVE_LIBZ
+typedef struct bbstreamer_gzip_writer
+{
+ bbstreamer base;
+ char *pathname;
+ gzFile gzfile;
+} bbstreamer_gzip_writer;
+
+typedef struct bbstreamer_gzip_decompressor
+{
+ bbstreamer base;
+ z_stream zstream;
+ size_t bytes_written;
+} bbstreamer_gzip_decompressor;
+
+static void bbstreamer_gzip_writer_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_gzip_writer_finalize(bbstreamer *streamer);
+static void bbstreamer_gzip_writer_free(bbstreamer *streamer);
+static const char *get_gz_error(gzFile gzf);
+
+const bbstreamer_ops bbstreamer_gzip_writer_ops = {
+ .content = bbstreamer_gzip_writer_content,
+ .finalize = bbstreamer_gzip_writer_finalize,
+ .free = bbstreamer_gzip_writer_free
+};
+
+static void bbstreamer_gzip_decompressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_gzip_decompressor_finalize(bbstreamer *streamer);
+static void bbstreamer_gzip_decompressor_free(bbstreamer *streamer);
+static void *gzip_palloc(void *opaque, unsigned items, unsigned size);
+static void gzip_pfree(void *opaque, void *address);
+
+const bbstreamer_ops bbstreamer_gzip_decompressor_ops = {
+ .content = bbstreamer_gzip_decompressor_content,
+ .finalize = bbstreamer_gzip_decompressor_finalize,
+ .free = bbstreamer_gzip_decompressor_free
+};
+#endif
+
+/*
+ * Create a bbstreamer that just compresses data using gzip, and then writes
+ * it to a file.
+ *
+ * As in the case of bbstreamer_plain_writer_new, pathname is always used
+ * for error reporting purposes; if file is NULL, it is also the opened and
+ * closed so that the data may be written there.
+ */
+bbstreamer *
+bbstreamer_gzip_writer_new(char *pathname, FILE *file,
+ pg_compress_specification *compress)
+{
+#ifdef HAVE_LIBZ
+ bbstreamer_gzip_writer *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer_gzip_writer));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_gzip_writer_ops;
+
+ streamer->pathname = pstrdup(pathname);
+
+ if (file == NULL)
+ {
+ streamer->gzfile = gzopen(pathname, "wb");
+ if (streamer->gzfile == NULL)
+ pg_fatal("could not create compressed file \"%s\": %m",
+ pathname);
+ }
+ else
+ {
+ int fd = dup(fileno(file));
+
+ if (fd < 0)
+ pg_fatal("could not duplicate stdout: %m");
+
+ streamer->gzfile = gzdopen(fd, "wb");
+ if (streamer->gzfile == NULL)
+ pg_fatal("could not open output file: %m");
+ }
+
+ if (gzsetparams(streamer->gzfile, compress->level, Z_DEFAULT_STRATEGY) != Z_OK)
+ pg_fatal("could not set compression level %d: %s",
+ compress->level, get_gz_error(streamer->gzfile));
+
+ return &streamer->base;
+#else
+ pg_fatal("this build does not support gzip compression");
+ return NULL; /* keep compiler quiet */
+#endif
+}
+
+#ifdef HAVE_LIBZ
+/*
+ * Write archive content to gzip file.
+ */
+static void
+bbstreamer_gzip_writer_content(bbstreamer *streamer,
+ bbstreamer_member *member, const char *data,
+ int len, bbstreamer_archive_context context)
+{
+ bbstreamer_gzip_writer *mystreamer;
+
+ mystreamer = (bbstreamer_gzip_writer *) streamer;
+
+ if (len == 0)
+ return;
+
+ errno = 0;
+ if (gzwrite(mystreamer->gzfile, data, len) != len)
+ {
+ /* if write didn't set errno, assume problem is no disk space */
+ if (errno == 0)
+ errno = ENOSPC;
+ pg_fatal("could not write to compressed file \"%s\": %s",
+ mystreamer->pathname, get_gz_error(mystreamer->gzfile));
+ }
+}
+
+/*
+ * End-of-archive processing when writing to a gzip file consists of just
+ * calling gzclose.
+ *
+ * It makes no difference whether we opened the file or the caller did it,
+ * because libz provides no way of avoiding a close on the underling file
+ * handle. Notice, however, that bbstreamer_gzip_writer_new() uses dup() to
+ * work around this issue, so that the behavior from the caller's viewpoint
+ * is the same as for bbstreamer_plain_writer.
+ */
+static void
+bbstreamer_gzip_writer_finalize(bbstreamer *streamer)
+{
+ bbstreamer_gzip_writer *mystreamer;
+
+ mystreamer = (bbstreamer_gzip_writer *) streamer;
+
+ errno = 0; /* in case gzclose() doesn't set it */
+ if (gzclose(mystreamer->gzfile) != 0)
+ pg_fatal("could not close compressed file \"%s\": %m",
+ mystreamer->pathname);
+
+ mystreamer->gzfile = NULL;
+}
+
+/*
+ * Free memory associated with this bbstreamer.
+ */
+static void
+bbstreamer_gzip_writer_free(bbstreamer *streamer)
+{
+ bbstreamer_gzip_writer *mystreamer;
+
+ mystreamer = (bbstreamer_gzip_writer *) streamer;
+
+ Assert(mystreamer->base.bbs_next == NULL);
+ Assert(mystreamer->gzfile == NULL);
+
+ pfree(mystreamer->pathname);
+ pfree(mystreamer);
+}
+
+/*
+ * Helper function for libz error reporting.
+ */
+static const char *
+get_gz_error(gzFile gzf)
+{
+ int errnum;
+ const char *errmsg;
+
+ errmsg = gzerror(gzf, &errnum);
+ if (errnum == Z_ERRNO)
+ return strerror(errno);
+ else
+ return errmsg;
+}
+#endif
+
+/*
+ * Create a new base backup streamer that performs decompression of gzip
+ * compressed blocks.
+ */
+bbstreamer *
+bbstreamer_gzip_decompressor_new(bbstreamer *next)
+{
+#ifdef HAVE_LIBZ
+ bbstreamer_gzip_decompressor *streamer;
+ z_stream *zs;
+
+ Assert(next != NULL);
+
+ streamer = palloc0(sizeof(bbstreamer_gzip_decompressor));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_gzip_decompressor_ops;
+
+ streamer->base.bbs_next = next;
+ initStringInfo(&streamer->base.bbs_buffer);
+
+ /* Initialize internal stream state for decompression */
+ zs = &streamer->zstream;
+ zs->zalloc = gzip_palloc;
+ zs->zfree = gzip_pfree;
+ zs->next_out = (uint8 *) streamer->base.bbs_buffer.data;
+ zs->avail_out = streamer->base.bbs_buffer.maxlen;
+
+ /*
+ * Data compression was initialized using deflateInit2 to request a gzip
+ * header. Similarly, we are using inflateInit2 to initialize data
+ * decompression.
+ *
+ * Per the documentation for inflateInit2, the second argument is
+ * "windowBits" and its value must be greater than or equal to the value
+ * provided while compressing the data, so we are using the maximum
+ * possible value for safety.
+ */
+ if (inflateInit2(zs, 15 + 16) != Z_OK)
+ pg_fatal("could not initialize compression library");
+
+ return &streamer->base;
+#else
+ pg_fatal("this build does not support gzip compression");
+ return NULL; /* keep compiler quiet */
+#endif
+}
+
+#ifdef HAVE_LIBZ
+/*
+ * Decompress the input data to output buffer until we run out of input
+ * data. Each time the output buffer is full, pass on the decompressed data
+ * to the next streamer.
+ */
+static void
+bbstreamer_gzip_decompressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_gzip_decompressor *mystreamer;
+ z_stream *zs;
+
+ mystreamer = (bbstreamer_gzip_decompressor *) streamer;
+
+ zs = &mystreamer->zstream;
+ zs->next_in = (uint8 *) data;
+ zs->avail_in = len;
+
+ /* Process the current chunk */
+ while (zs->avail_in > 0)
+ {
+ int res;
+
+ Assert(mystreamer->bytes_written < mystreamer->base.bbs_buffer.maxlen);
+
+ zs->next_out = (uint8 *)
+ mystreamer->base.bbs_buffer.data + mystreamer->bytes_written;
+ zs->avail_out =
+ mystreamer->base.bbs_buffer.maxlen - mystreamer->bytes_written;
+
+ /*
+ * This call decompresses data starting at zs->next_in and updates
+ * zs->next_in * and zs->avail_in. It generates output data starting
+ * at zs->next_out and updates zs->next_out and zs->avail_out
+ * accordingly.
+ */
+ res = inflate(zs, Z_NO_FLUSH);
+
+ if (res == Z_STREAM_ERROR)
+ pg_log_error("could not decompress data: %s", zs->msg);
+
+ mystreamer->bytes_written =
+ mystreamer->base.bbs_buffer.maxlen - zs->avail_out;
+
+ /* If output buffer is full then pass data to next streamer */
+ if (mystreamer->bytes_written >= mystreamer->base.bbs_buffer.maxlen)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->base.bbs_buffer.maxlen, context);
+ mystreamer->bytes_written = 0;
+ }
+ }
+}
+
+/*
+ * End-of-stream processing.
+ */
+static void
+bbstreamer_gzip_decompressor_finalize(bbstreamer *streamer)
+{
+ bbstreamer_gzip_decompressor *mystreamer;
+
+ mystreamer = (bbstreamer_gzip_decompressor *) streamer;
+
+ /*
+ * End of the stream, if there is some pending data in output buffers then
+ * we must forward it to next streamer.
+ */
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->base.bbs_buffer.maxlen,
+ BBSTREAMER_UNKNOWN);
+
+ bbstreamer_finalize(mystreamer->base.bbs_next);
+}
+
+/*
+ * Free memory.
+ */
+static void
+bbstreamer_gzip_decompressor_free(bbstreamer *streamer)
+{
+ bbstreamer_free(streamer->bbs_next);
+ pfree(streamer->bbs_buffer.data);
+ pfree(streamer);
+}
+
+/*
+ * Wrapper function to adjust the signature of palloc to match what libz
+ * expects.
+ */
+static void *
+gzip_palloc(void *opaque, unsigned items, unsigned size)
+{
+ return palloc(items * size);
+}
+
+/*
+ * Wrapper function to adjust the signature of pfree to match what libz
+ * expects.
+ */
+static void
+gzip_pfree(void *opaque, void *address)
+{
+ pfree(address);
+}
+#endif
diff --git a/src/bin/pg_basebackup/bbstreamer_inject.c b/src/bin/pg_basebackup/bbstreamer_inject.c
new file mode 100644
index 0000000..cc804f1
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer_inject.c
@@ -0,0 +1,249 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer_inject.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer_inject.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include "bbstreamer.h"
+#include "common/file_perm.h"
+#include "common/logging.h"
+
+typedef struct bbstreamer_recovery_injector
+{
+ bbstreamer base;
+ bool skip_file;
+ bool is_recovery_guc_supported;
+ bool is_postgresql_auto_conf;
+ bool found_postgresql_auto_conf;
+ PQExpBuffer recoveryconfcontents;
+ bbstreamer_member member;
+} bbstreamer_recovery_injector;
+
+static void bbstreamer_recovery_injector_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_recovery_injector_finalize(bbstreamer *streamer);
+static void bbstreamer_recovery_injector_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_recovery_injector_ops = {
+ .content = bbstreamer_recovery_injector_content,
+ .finalize = bbstreamer_recovery_injector_finalize,
+ .free = bbstreamer_recovery_injector_free
+};
+
+/*
+ * Create a bbstreamer that can edit recoverydata into an archive stream.
+ *
+ * The input should be a series of typed chunks (not BBSTREAMER_UNKNOWN) as
+ * per the conventions described in bbstreamer.h; the chunks forwarded to
+ * the next bbstreamer will be similarly typed, but the
+ * BBSTREAMER_MEMBER_HEADER chunks may be zero-length in cases where we've
+ * edited the archive stream.
+ *
+ * Our goal is to do one of the following three things with the content passed
+ * via recoveryconfcontents: (1) if is_recovery_guc_supported is false, then
+ * put the content into recovery.conf, replacing any existing archive member
+ * by that name; (2) if is_recovery_guc_supported is true and
+ * postgresql.auto.conf exists in the archive, then append the content
+ * provided to the existing file; and (3) if is_recovery_guc_supported is
+ * true but postgresql.auto.conf does not exist in the archive, then create
+ * it with the specified content.
+ *
+ * In addition, if is_recovery_guc_supported is true, then we create a
+ * zero-length standby.signal file, dropping any file with that name from
+ * the archive.
+ */
+extern bbstreamer *
+bbstreamer_recovery_injector_new(bbstreamer *next,
+ bool is_recovery_guc_supported,
+ PQExpBuffer recoveryconfcontents)
+{
+ bbstreamer_recovery_injector *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer_recovery_injector));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_recovery_injector_ops;
+ streamer->base.bbs_next = next;
+ streamer->is_recovery_guc_supported = is_recovery_guc_supported;
+ streamer->recoveryconfcontents = recoveryconfcontents;
+
+ return &streamer->base;
+}
+
+/*
+ * Handle each chunk of tar content while injecting recovery configuration.
+ */
+static void
+bbstreamer_recovery_injector_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_recovery_injector *mystreamer;
+
+ mystreamer = (bbstreamer_recovery_injector *) streamer;
+ Assert(member != NULL || context == BBSTREAMER_ARCHIVE_TRAILER);
+
+ switch (context)
+ {
+ case BBSTREAMER_MEMBER_HEADER:
+ /* Must copy provided data so we have the option to modify it. */
+ memcpy(&mystreamer->member, member, sizeof(bbstreamer_member));
+
+ /*
+ * On v12+, skip standby.signal and edit postgresql.auto.conf; on
+ * older versions, skip recovery.conf.
+ */
+ if (mystreamer->is_recovery_guc_supported)
+ {
+ mystreamer->skip_file =
+ (strcmp(member->pathname, "standby.signal") == 0);
+ mystreamer->is_postgresql_auto_conf =
+ (strcmp(member->pathname, "postgresql.auto.conf") == 0);
+ if (mystreamer->is_postgresql_auto_conf)
+ {
+ /* Remember we saw it so we don't add it again. */
+ mystreamer->found_postgresql_auto_conf = true;
+
+ /* Increment length by data to be injected. */
+ mystreamer->member.size +=
+ mystreamer->recoveryconfcontents->len;
+
+ /*
+ * Zap data and len because the archive header is no
+ * longer valid; some subsequent bbstreamer must
+ * regenerate it if it's necessary.
+ */
+ data = NULL;
+ len = 0;
+ }
+ }
+ else
+ mystreamer->skip_file =
+ (strcmp(member->pathname, "recovery.conf") == 0);
+
+ /* Do not forward if the file is to be skipped. */
+ if (mystreamer->skip_file)
+ return;
+ break;
+
+ case BBSTREAMER_MEMBER_CONTENTS:
+ /* Do not forward if the file is to be skipped. */
+ if (mystreamer->skip_file)
+ return;
+ break;
+
+ case BBSTREAMER_MEMBER_TRAILER:
+ /* Do not forward it the file is to be skipped. */
+ if (mystreamer->skip_file)
+ return;
+
+ /* Append provided content to whatever we already sent. */
+ if (mystreamer->is_postgresql_auto_conf)
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ mystreamer->recoveryconfcontents->data,
+ mystreamer->recoveryconfcontents->len,
+ BBSTREAMER_MEMBER_CONTENTS);
+ break;
+
+ case BBSTREAMER_ARCHIVE_TRAILER:
+ if (mystreamer->is_recovery_guc_supported)
+ {
+ /*
+ * If we didn't already find (and thus modify)
+ * postgresql.auto.conf, inject it as an additional archive
+ * member now.
+ */
+ if (!mystreamer->found_postgresql_auto_conf)
+ bbstreamer_inject_file(mystreamer->base.bbs_next,
+ "postgresql.auto.conf",
+ mystreamer->recoveryconfcontents->data,
+ mystreamer->recoveryconfcontents->len);
+
+ /* Inject empty standby.signal file. */
+ bbstreamer_inject_file(mystreamer->base.bbs_next,
+ "standby.signal", "", 0);
+ }
+ else
+ {
+ /* Inject recovery.conf file with specified contents. */
+ bbstreamer_inject_file(mystreamer->base.bbs_next,
+ "recovery.conf",
+ mystreamer->recoveryconfcontents->data,
+ mystreamer->recoveryconfcontents->len);
+ }
+
+ /* Nothing to do here. */
+ break;
+
+ default:
+ /* Shouldn't happen. */
+ pg_fatal("unexpected state while injecting recovery settings");
+ }
+
+ bbstreamer_content(mystreamer->base.bbs_next, &mystreamer->member,
+ data, len, context);
+}
+
+/*
+ * End-of-stream processing for this bbstreamer.
+ */
+static void
+bbstreamer_recovery_injector_finalize(bbstreamer *streamer)
+{
+ bbstreamer_finalize(streamer->bbs_next);
+}
+
+/*
+ * Free memory associated with this bbstreamer.
+ */
+static void
+bbstreamer_recovery_injector_free(bbstreamer *streamer)
+{
+ bbstreamer_free(streamer->bbs_next);
+ pfree(streamer);
+}
+
+/*
+ * Inject a member into the archive with specified contents.
+ */
+void
+bbstreamer_inject_file(bbstreamer *streamer, char *pathname, char *data,
+ int len)
+{
+ bbstreamer_member member;
+
+ strlcpy(member.pathname, pathname, MAXPGPATH);
+ member.size = len;
+ member.mode = pg_file_create_mode;
+ member.is_directory = false;
+ member.is_link = false;
+ member.linktarget[0] = '\0';
+
+ /*
+ * There seems to be no principled argument for these values, but they are
+ * what PostgreSQL has historically used.
+ */
+ member.uid = 04000;
+ member.gid = 02000;
+
+ /*
+ * We don't know here how to generate valid member headers and trailers
+ * for the archiving format in use, so if those are needed, some successor
+ * bbstreamer will have to generate them using the data from 'member'.
+ */
+ bbstreamer_content(streamer, &member, NULL, 0,
+ BBSTREAMER_MEMBER_HEADER);
+ bbstreamer_content(streamer, &member, data, len,
+ BBSTREAMER_MEMBER_CONTENTS);
+ bbstreamer_content(streamer, &member, NULL, 0,
+ BBSTREAMER_MEMBER_TRAILER);
+}
diff --git a/src/bin/pg_basebackup/bbstreamer_lz4.c b/src/bin/pg_basebackup/bbstreamer_lz4.c
new file mode 100644
index 0000000..ed2aa01
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer_lz4.c
@@ -0,0 +1,422 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer_lz4.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer_lz4.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <unistd.h>
+
+#ifdef USE_LZ4
+#include <lz4frame.h>
+#endif
+
+#include "bbstreamer.h"
+#include "common/logging.h"
+#include "common/file_perm.h"
+#include "common/string.h"
+
+#ifdef USE_LZ4
+typedef struct bbstreamer_lz4_frame
+{
+ bbstreamer base;
+
+ LZ4F_compressionContext_t cctx;
+ LZ4F_decompressionContext_t dctx;
+ LZ4F_preferences_t prefs;
+
+ size_t bytes_written;
+ bool header_written;
+} bbstreamer_lz4_frame;
+
+static void bbstreamer_lz4_compressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_lz4_compressor_finalize(bbstreamer *streamer);
+static void bbstreamer_lz4_compressor_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_lz4_compressor_ops = {
+ .content = bbstreamer_lz4_compressor_content,
+ .finalize = bbstreamer_lz4_compressor_finalize,
+ .free = bbstreamer_lz4_compressor_free
+};
+
+static void bbstreamer_lz4_decompressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_lz4_decompressor_finalize(bbstreamer *streamer);
+static void bbstreamer_lz4_decompressor_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_lz4_decompressor_ops = {
+ .content = bbstreamer_lz4_decompressor_content,
+ .finalize = bbstreamer_lz4_decompressor_finalize,
+ .free = bbstreamer_lz4_decompressor_free
+};
+#endif
+
+/*
+ * Create a new base backup streamer that performs lz4 compression of tar
+ * blocks.
+ */
+bbstreamer *
+bbstreamer_lz4_compressor_new(bbstreamer *next, pg_compress_specification *compress)
+{
+#ifdef USE_LZ4
+ bbstreamer_lz4_frame *streamer;
+ LZ4F_errorCode_t ctxError;
+ LZ4F_preferences_t *prefs;
+
+ Assert(next != NULL);
+
+ streamer = palloc0(sizeof(bbstreamer_lz4_frame));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_lz4_compressor_ops;
+
+ streamer->base.bbs_next = next;
+ initStringInfo(&streamer->base.bbs_buffer);
+ streamer->header_written = false;
+
+ /* Initialize stream compression preferences */
+ prefs = &streamer->prefs;
+ memset(prefs, 0, sizeof(LZ4F_preferences_t));
+ prefs->frameInfo.blockSizeID = LZ4F_max256KB;
+ prefs->compressionLevel = compress->level;
+
+ ctxError = LZ4F_createCompressionContext(&streamer->cctx, LZ4F_VERSION);
+ if (LZ4F_isError(ctxError))
+ pg_log_error("could not create lz4 compression context: %s",
+ LZ4F_getErrorName(ctxError));
+
+ return &streamer->base;
+#else
+ pg_fatal("this build does not support lz4 compression");
+ return NULL; /* keep compiler quiet */
+#endif
+}
+
+#ifdef USE_LZ4
+/*
+ * Compress the input data to output buffer.
+ *
+ * Find out the compression bound based on input data length for each
+ * invocation to make sure that output buffer has enough capacity to
+ * accommodate the compressed data. In case if the output buffer
+ * capacity falls short of compression bound then forward the content
+ * of output buffer to next streamer and empty the buffer.
+ */
+static void
+bbstreamer_lz4_compressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_lz4_frame *mystreamer;
+ uint8 *next_in,
+ *next_out;
+ size_t out_bound,
+ compressed_size,
+ avail_out;
+
+ mystreamer = (bbstreamer_lz4_frame *) streamer;
+ next_in = (uint8 *) data;
+
+ /* Write header before processing the first input chunk. */
+ if (!mystreamer->header_written)
+ {
+ compressed_size = LZ4F_compressBegin(mystreamer->cctx,
+ (uint8 *) mystreamer->base.bbs_buffer.data,
+ mystreamer->base.bbs_buffer.maxlen,
+ &mystreamer->prefs);
+
+ if (LZ4F_isError(compressed_size))
+ pg_log_error("could not write lz4 header: %s",
+ LZ4F_getErrorName(compressed_size));
+
+ mystreamer->bytes_written += compressed_size;
+ mystreamer->header_written = true;
+ }
+
+ /*
+ * Update the offset and capacity of output buffer based on number of
+ * bytes written to output buffer.
+ */
+ next_out = (uint8 *) mystreamer->base.bbs_buffer.data + mystreamer->bytes_written;
+ avail_out = mystreamer->base.bbs_buffer.maxlen - mystreamer->bytes_written;
+
+ /*
+ * Find out the compression bound and make sure that output buffer has the
+ * required capacity for the success of LZ4F_compressUpdate. If needed
+ * forward the content to next streamer and empty the buffer.
+ */
+ out_bound = LZ4F_compressBound(len, &mystreamer->prefs);
+ if (avail_out < out_bound)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->bytes_written,
+ context);
+
+ /* Enlarge buffer if it falls short of out bound. */
+ if (mystreamer->base.bbs_buffer.maxlen < out_bound)
+ enlargeStringInfo(&mystreamer->base.bbs_buffer, out_bound);
+
+ avail_out = mystreamer->base.bbs_buffer.maxlen;
+ mystreamer->bytes_written = 0;
+ next_out = (uint8 *) mystreamer->base.bbs_buffer.data;
+ }
+
+ /*
+ * This call compresses the data starting at next_in and generates the
+ * output starting at next_out. It expects the caller to provide the size
+ * of input buffer and capacity of output buffer by providing parameters
+ * len and avail_out.
+ *
+ * It returns the number of bytes compressed to output buffer.
+ */
+ compressed_size = LZ4F_compressUpdate(mystreamer->cctx,
+ next_out, avail_out,
+ next_in, len, NULL);
+
+ if (LZ4F_isError(compressed_size))
+ pg_log_error("could not compress data: %s",
+ LZ4F_getErrorName(compressed_size));
+
+ mystreamer->bytes_written += compressed_size;
+}
+
+/*
+ * End-of-stream processing.
+ */
+static void
+bbstreamer_lz4_compressor_finalize(bbstreamer *streamer)
+{
+ bbstreamer_lz4_frame *mystreamer;
+ uint8 *next_out;
+ size_t footer_bound,
+ compressed_size,
+ avail_out;
+
+ mystreamer = (bbstreamer_lz4_frame *) streamer;
+
+ /* Find out the footer bound and update the output buffer. */
+ footer_bound = LZ4F_compressBound(0, &mystreamer->prefs);
+ if ((mystreamer->base.bbs_buffer.maxlen - mystreamer->bytes_written) <
+ footer_bound)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->bytes_written,
+ BBSTREAMER_UNKNOWN);
+
+ /* Enlarge buffer if it falls short of footer bound. */
+ if (mystreamer->base.bbs_buffer.maxlen < footer_bound)
+ enlargeStringInfo(&mystreamer->base.bbs_buffer, footer_bound);
+
+ avail_out = mystreamer->base.bbs_buffer.maxlen;
+ mystreamer->bytes_written = 0;
+ next_out = (uint8 *) mystreamer->base.bbs_buffer.data;
+ }
+ else
+ {
+ next_out = (uint8 *) mystreamer->base.bbs_buffer.data + mystreamer->bytes_written;
+ avail_out = mystreamer->base.bbs_buffer.maxlen - mystreamer->bytes_written;
+ }
+
+ /*
+ * Finalize the frame and flush whatever data remaining in compression
+ * context.
+ */
+ compressed_size = LZ4F_compressEnd(mystreamer->cctx,
+ next_out, avail_out, NULL);
+
+ if (LZ4F_isError(compressed_size))
+ pg_log_error("could not end lz4 compression: %s",
+ LZ4F_getErrorName(compressed_size));
+
+ mystreamer->bytes_written += compressed_size;
+
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->bytes_written,
+ BBSTREAMER_UNKNOWN);
+
+ bbstreamer_finalize(mystreamer->base.bbs_next);
+}
+
+/*
+ * Free memory.
+ */
+static void
+bbstreamer_lz4_compressor_free(bbstreamer *streamer)
+{
+ bbstreamer_lz4_frame *mystreamer;
+
+ mystreamer = (bbstreamer_lz4_frame *) streamer;
+ bbstreamer_free(streamer->bbs_next);
+ LZ4F_freeCompressionContext(mystreamer->cctx);
+ pfree(streamer->bbs_buffer.data);
+ pfree(streamer);
+}
+#endif
+
+/*
+ * Create a new base backup streamer that performs decompression of lz4
+ * compressed blocks.
+ */
+bbstreamer *
+bbstreamer_lz4_decompressor_new(bbstreamer *next)
+{
+#ifdef USE_LZ4
+ bbstreamer_lz4_frame *streamer;
+ LZ4F_errorCode_t ctxError;
+
+ Assert(next != NULL);
+
+ streamer = palloc0(sizeof(bbstreamer_lz4_frame));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_lz4_decompressor_ops;
+
+ streamer->base.bbs_next = next;
+ initStringInfo(&streamer->base.bbs_buffer);
+
+ /* Initialize internal stream state for decompression */
+ ctxError = LZ4F_createDecompressionContext(&streamer->dctx, LZ4F_VERSION);
+ if (LZ4F_isError(ctxError))
+ pg_fatal("could not initialize compression library: %s",
+ LZ4F_getErrorName(ctxError));
+
+ return &streamer->base;
+#else
+ pg_fatal("this build does not support lz4 compression");
+ return NULL; /* keep compiler quiet */
+#endif
+}
+
+#ifdef USE_LZ4
+/*
+ * Decompress the input data to output buffer until we run out of input
+ * data. Each time the output buffer is full, pass on the decompressed data
+ * to the next streamer.
+ */
+static void
+bbstreamer_lz4_decompressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_lz4_frame *mystreamer;
+ uint8 *next_in,
+ *next_out;
+ size_t avail_in,
+ avail_out;
+
+ mystreamer = (bbstreamer_lz4_frame *) streamer;
+ next_in = (uint8 *) data;
+ next_out = (uint8 *) mystreamer->base.bbs_buffer.data;
+ avail_in = len;
+ avail_out = mystreamer->base.bbs_buffer.maxlen;
+
+ while (avail_in > 0)
+ {
+ size_t ret,
+ read_size,
+ out_size;
+
+ read_size = avail_in;
+ out_size = avail_out;
+
+ /*
+ * This call decompresses the data starting at next_in and generates
+ * the output data starting at next_out. It expects the caller to
+ * provide size of the input buffer and total capacity of the output
+ * buffer by providing the read_size and out_size parameters
+ * respectively.
+ *
+ * Per the documentation of LZ4, parameters read_size and out_size
+ * behaves as dual parameters. On return, the number of bytes consumed
+ * from the input buffer will be written back to read_size and the
+ * number of bytes decompressed to output buffer will be written back
+ * to out_size respectively.
+ */
+ ret = LZ4F_decompress(mystreamer->dctx,
+ next_out, &out_size,
+ next_in, &read_size, NULL);
+
+ if (LZ4F_isError(ret))
+ pg_log_error("could not decompress data: %s",
+ LZ4F_getErrorName(ret));
+
+ /* Update input buffer based on number of bytes consumed */
+ avail_in -= read_size;
+ next_in += read_size;
+
+ mystreamer->bytes_written += out_size;
+
+ /*
+ * If output buffer is full then forward the content to next streamer
+ * and update the output buffer.
+ */
+ if (mystreamer->bytes_written >= mystreamer->base.bbs_buffer.maxlen)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->base.bbs_buffer.maxlen,
+ context);
+
+ avail_out = mystreamer->base.bbs_buffer.maxlen;
+ mystreamer->bytes_written = 0;
+ next_out = (uint8 *) mystreamer->base.bbs_buffer.data;
+ }
+ else
+ {
+ avail_out = mystreamer->base.bbs_buffer.maxlen - mystreamer->bytes_written;
+ next_out += mystreamer->bytes_written;
+ }
+ }
+}
+
+/*
+ * End-of-stream processing.
+ */
+static void
+bbstreamer_lz4_decompressor_finalize(bbstreamer *streamer)
+{
+ bbstreamer_lz4_frame *mystreamer;
+
+ mystreamer = (bbstreamer_lz4_frame *) streamer;
+
+ /*
+ * End of the stream, if there is some pending data in output buffers then
+ * we must forward it to next streamer.
+ */
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->base.bbs_buffer.maxlen,
+ BBSTREAMER_UNKNOWN);
+
+ bbstreamer_finalize(mystreamer->base.bbs_next);
+}
+
+/*
+ * Free memory.
+ */
+static void
+bbstreamer_lz4_decompressor_free(bbstreamer *streamer)
+{
+ bbstreamer_lz4_frame *mystreamer;
+
+ mystreamer = (bbstreamer_lz4_frame *) streamer;
+ bbstreamer_free(streamer->bbs_next);
+ LZ4F_freeDecompressionContext(mystreamer->dctx);
+ pfree(streamer->bbs_buffer.data);
+ pfree(streamer);
+}
+#endif
diff --git a/src/bin/pg_basebackup/bbstreamer_tar.c b/src/bin/pg_basebackup/bbstreamer_tar.c
new file mode 100644
index 0000000..ef5586c
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer_tar.c
@@ -0,0 +1,516 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer_tar.c
+ *
+ * This module implements three types of tar processing. A tar parser
+ * expects unlabelled chunks of data (e.g. BBSTREAMER_UNKNOWN) and splits
+ * it into labelled chunks (any other value of bbstreamer_archive_context).
+ * A tar archiver does the reverse: it takes a bunch of labelled chunks
+ * and produces a tarfile, optionally replacing member headers and trailers
+ * so that upstream bbstreamer objects can perform surgery on the tarfile
+ * contents without knowing the details of the tar format. A tar terminator
+ * just adds two blocks of NUL bytes to the end of the file, since older
+ * server versions produce files with this terminator omitted.
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer_tar.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <time.h>
+
+#include "bbstreamer.h"
+#include "common/logging.h"
+#include "pgtar.h"
+
+typedef struct bbstreamer_tar_parser
+{
+ bbstreamer base;
+ bbstreamer_archive_context next_context;
+ bbstreamer_member member;
+ size_t file_bytes_sent;
+ size_t pad_bytes_expected;
+} bbstreamer_tar_parser;
+
+typedef struct bbstreamer_tar_archiver
+{
+ bbstreamer base;
+ bool rearchive_member;
+} bbstreamer_tar_archiver;
+
+static void bbstreamer_tar_parser_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_tar_parser_finalize(bbstreamer *streamer);
+static void bbstreamer_tar_parser_free(bbstreamer *streamer);
+static bool bbstreamer_tar_header(bbstreamer_tar_parser *mystreamer);
+
+const bbstreamer_ops bbstreamer_tar_parser_ops = {
+ .content = bbstreamer_tar_parser_content,
+ .finalize = bbstreamer_tar_parser_finalize,
+ .free = bbstreamer_tar_parser_free
+};
+
+static void bbstreamer_tar_archiver_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_tar_archiver_finalize(bbstreamer *streamer);
+static void bbstreamer_tar_archiver_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_tar_archiver_ops = {
+ .content = bbstreamer_tar_archiver_content,
+ .finalize = bbstreamer_tar_archiver_finalize,
+ .free = bbstreamer_tar_archiver_free
+};
+
+static void bbstreamer_tar_terminator_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_tar_terminator_finalize(bbstreamer *streamer);
+static void bbstreamer_tar_terminator_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_tar_terminator_ops = {
+ .content = bbstreamer_tar_terminator_content,
+ .finalize = bbstreamer_tar_terminator_finalize,
+ .free = bbstreamer_tar_terminator_free
+};
+
+/*
+ * Create a bbstreamer that can parse a stream of content as tar data.
+ *
+ * The input should be a series of BBSTREAMER_UNKNOWN chunks; the bbstreamer
+ * specified by 'next' will receive a series of typed chunks, as per the
+ * conventions described in bbstreamer.h.
+ */
+extern bbstreamer *
+bbstreamer_tar_parser_new(bbstreamer *next)
+{
+ bbstreamer_tar_parser *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer_tar_parser));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_tar_parser_ops;
+ streamer->base.bbs_next = next;
+ initStringInfo(&streamer->base.bbs_buffer);
+ streamer->next_context = BBSTREAMER_MEMBER_HEADER;
+
+ return &streamer->base;
+}
+
+/*
+ * Parse unknown content as tar data.
+ */
+static void
+bbstreamer_tar_parser_content(bbstreamer *streamer, bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_tar_parser *mystreamer = (bbstreamer_tar_parser *) streamer;
+ size_t nbytes;
+
+ /* Expect unparsed input. */
+ Assert(member == NULL);
+ Assert(context == BBSTREAMER_UNKNOWN);
+
+ while (len > 0)
+ {
+ switch (mystreamer->next_context)
+ {
+ case BBSTREAMER_MEMBER_HEADER:
+
+ /*
+ * If we're expecting an archive member header, accumulate a
+ * full block of data before doing anything further.
+ */
+ if (!bbstreamer_buffer_until(streamer, &data, &len,
+ TAR_BLOCK_SIZE))
+ return;
+
+ /*
+ * Now we can process the header and get ready to process the
+ * file contents; however, we might find out that what we
+ * thought was the next file header is actually the start of
+ * the archive trailer. Switch modes accordingly.
+ */
+ if (bbstreamer_tar_header(mystreamer))
+ {
+ if (mystreamer->member.size == 0)
+ {
+ /* No content; trailer is zero-length. */
+ bbstreamer_content(mystreamer->base.bbs_next,
+ &mystreamer->member,
+ NULL, 0,
+ BBSTREAMER_MEMBER_TRAILER);
+
+ /* Expect next header. */
+ mystreamer->next_context = BBSTREAMER_MEMBER_HEADER;
+ }
+ else
+ {
+ /* Expect contents. */
+ mystreamer->next_context = BBSTREAMER_MEMBER_CONTENTS;
+ }
+ mystreamer->base.bbs_buffer.len = 0;
+ mystreamer->file_bytes_sent = 0;
+ }
+ else
+ mystreamer->next_context = BBSTREAMER_ARCHIVE_TRAILER;
+ break;
+
+ case BBSTREAMER_MEMBER_CONTENTS:
+
+ /*
+ * Send as much content as we have, but not more than the
+ * remaining file length.
+ */
+ Assert(mystreamer->file_bytes_sent < mystreamer->member.size);
+ nbytes = mystreamer->member.size - mystreamer->file_bytes_sent;
+ nbytes = Min(nbytes, len);
+ Assert(nbytes > 0);
+ bbstreamer_content(mystreamer->base.bbs_next,
+ &mystreamer->member,
+ data, nbytes,
+ BBSTREAMER_MEMBER_CONTENTS);
+ mystreamer->file_bytes_sent += nbytes;
+ data += nbytes;
+ len -= nbytes;
+
+ /*
+ * If we've not yet sent the whole file, then there's more
+ * content to come; otherwise, it's time to expect the file
+ * trailer.
+ */
+ Assert(mystreamer->file_bytes_sent <= mystreamer->member.size);
+ if (mystreamer->file_bytes_sent == mystreamer->member.size)
+ {
+ if (mystreamer->pad_bytes_expected == 0)
+ {
+ /* Trailer is zero-length. */
+ bbstreamer_content(mystreamer->base.bbs_next,
+ &mystreamer->member,
+ NULL, 0,
+ BBSTREAMER_MEMBER_TRAILER);
+
+ /* Expect next header. */
+ mystreamer->next_context = BBSTREAMER_MEMBER_HEADER;
+ }
+ else
+ {
+ /* Trailer is not zero-length. */
+ mystreamer->next_context = BBSTREAMER_MEMBER_TRAILER;
+ }
+ mystreamer->base.bbs_buffer.len = 0;
+ }
+ break;
+
+ case BBSTREAMER_MEMBER_TRAILER:
+
+ /*
+ * If we're expecting an archive member trailer, accumulate
+ * the expected number of padding bytes before sending
+ * anything onward.
+ */
+ if (!bbstreamer_buffer_until(streamer, &data, &len,
+ mystreamer->pad_bytes_expected))
+ return;
+
+ /* OK, now we can send it. */
+ bbstreamer_content(mystreamer->base.bbs_next,
+ &mystreamer->member,
+ data, mystreamer->pad_bytes_expected,
+ BBSTREAMER_MEMBER_TRAILER);
+
+ /* Expect next file header. */
+ mystreamer->next_context = BBSTREAMER_MEMBER_HEADER;
+ mystreamer->base.bbs_buffer.len = 0;
+ break;
+
+ case BBSTREAMER_ARCHIVE_TRAILER:
+
+ /*
+ * We've seen an end-of-archive indicator, so anything more is
+ * buffered and sent as part of the archive trailer. But we
+ * don't expect more than 2 blocks.
+ */
+ bbstreamer_buffer_bytes(streamer, &data, &len, len);
+ if (len > 2 * TAR_BLOCK_SIZE)
+ pg_fatal("tar file trailer exceeds 2 blocks");
+ return;
+
+ default:
+ /* Shouldn't happen. */
+ pg_fatal("unexpected state while parsing tar archive");
+ }
+ }
+}
+
+/*
+ * Parse a file header within a tar stream.
+ *
+ * The return value is true if we found a file header and passed it on to the
+ * next bbstreamer; it is false if we have reached the archive trailer.
+ */
+static bool
+bbstreamer_tar_header(bbstreamer_tar_parser *mystreamer)
+{
+ bool has_nonzero_byte = false;
+ int i;
+ bbstreamer_member *member = &mystreamer->member;
+ char *buffer = mystreamer->base.bbs_buffer.data;
+
+ Assert(mystreamer->base.bbs_buffer.len == TAR_BLOCK_SIZE);
+
+ /* Check whether we've got a block of all zero bytes. */
+ for (i = 0; i < TAR_BLOCK_SIZE; ++i)
+ {
+ if (buffer[i] != '\0')
+ {
+ has_nonzero_byte = true;
+ break;
+ }
+ }
+
+ /*
+ * If the entire block was zeros, this is the end of the archive, not the
+ * start of the next file.
+ */
+ if (!has_nonzero_byte)
+ return false;
+
+ /*
+ * Parse key fields out of the header.
+ *
+ * FIXME: It's terrible that we use hard-coded values here instead of some
+ * more principled approach. It's been like this for a long time, but we
+ * ought to do better.
+ */
+ strlcpy(member->pathname, &buffer[0], MAXPGPATH);
+ if (member->pathname[0] == '\0')
+ pg_fatal("tar member has empty name");
+ member->size = read_tar_number(&buffer[124], 12);
+ member->mode = read_tar_number(&buffer[100], 8);
+ member->uid = read_tar_number(&buffer[108], 8);
+ member->gid = read_tar_number(&buffer[116], 8);
+ member->is_directory = (buffer[156] == '5');
+ member->is_link = (buffer[156] == '2');
+ if (member->is_link)
+ strlcpy(member->linktarget, &buffer[157], 100);
+
+ /* Compute number of padding bytes. */
+ mystreamer->pad_bytes_expected = tarPaddingBytesRequired(member->size);
+
+ /* Forward the entire header to the next bbstreamer. */
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ buffer, TAR_BLOCK_SIZE,
+ BBSTREAMER_MEMBER_HEADER);
+
+ return true;
+}
+
+/*
+ * End-of-stream processing for a tar parser.
+ */
+static void
+bbstreamer_tar_parser_finalize(bbstreamer *streamer)
+{
+ bbstreamer_tar_parser *mystreamer = (bbstreamer_tar_parser *) streamer;
+
+ if (mystreamer->next_context != BBSTREAMER_ARCHIVE_TRAILER &&
+ (mystreamer->next_context != BBSTREAMER_MEMBER_HEADER ||
+ mystreamer->base.bbs_buffer.len > 0))
+ pg_fatal("COPY stream ended before last file was finished");
+
+ /* Send the archive trailer, even if empty. */
+ bbstreamer_content(streamer->bbs_next, NULL,
+ streamer->bbs_buffer.data, streamer->bbs_buffer.len,
+ BBSTREAMER_ARCHIVE_TRAILER);
+
+ /* Now finalize successor. */
+ bbstreamer_finalize(streamer->bbs_next);
+}
+
+/*
+ * Free memory associated with a tar parser.
+ */
+static void
+bbstreamer_tar_parser_free(bbstreamer *streamer)
+{
+ pfree(streamer->bbs_buffer.data);
+ bbstreamer_free(streamer->bbs_next);
+}
+
+/*
+ * Create an bbstreamer that can generate a tar archive.
+ *
+ * This is intended to be usable either for generating a brand-new tar archive
+ * or for modifying one on the fly. The input should be a series of typed
+ * chunks (i.e. not BBSTREAMER_UNKNOWN). See also the comments for
+ * bbstreamer_tar_parser_content.
+ */
+extern bbstreamer *
+bbstreamer_tar_archiver_new(bbstreamer *next)
+{
+ bbstreamer_tar_archiver *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer_tar_archiver));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_tar_archiver_ops;
+ streamer->base.bbs_next = next;
+
+ return &streamer->base;
+}
+
+/*
+ * Fix up the stream of input chunks to create a valid tar file.
+ *
+ * If a BBSTREAMER_MEMBER_HEADER chunk is of size 0, it is replaced with a
+ * newly-constructed tar header. If it is of size TAR_BLOCK_SIZE, it is
+ * passed through without change. Any other size is a fatal error (and
+ * indicates a bug).
+ *
+ * Whenever a new BBSTREAMER_MEMBER_HEADER chunk is constructed, the
+ * corresponding BBSTREAMER_MEMBER_TRAILER chunk is also constructed from
+ * scratch. Specifically, we construct a block of zero bytes sufficient to
+ * pad out to a block boundary, as required by the tar format. Other
+ * BBSTREAMER_MEMBER_TRAILER chunks are passed through without change.
+ *
+ * Any BBSTREAMER_MEMBER_CONTENTS chunks are passed through without change.
+ *
+ * The BBSTREAMER_ARCHIVE_TRAILER chunk is replaced with two
+ * blocks of zero bytes. Not all tar programs require this, but apparently
+ * some do. The server does not supply this trailer. If no archive trailer is
+ * present, one will be added by bbstreamer_tar_parser_finalize.
+ */
+static void
+bbstreamer_tar_archiver_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_tar_archiver *mystreamer = (bbstreamer_tar_archiver *) streamer;
+ char buffer[2 * TAR_BLOCK_SIZE];
+
+ Assert(context != BBSTREAMER_UNKNOWN);
+
+ if (context == BBSTREAMER_MEMBER_HEADER && len != TAR_BLOCK_SIZE)
+ {
+ Assert(len == 0);
+
+ /* Replace zero-length tar header with a newly constructed one. */
+ tarCreateHeader(buffer, member->pathname, NULL,
+ member->size, member->mode, member->uid, member->gid,
+ time(NULL));
+ data = buffer;
+ len = TAR_BLOCK_SIZE;
+
+ /* Also make a note to replace padding, in case size changed. */
+ mystreamer->rearchive_member = true;
+ }
+ else if (context == BBSTREAMER_MEMBER_TRAILER &&
+ mystreamer->rearchive_member)
+ {
+ int pad_bytes = tarPaddingBytesRequired(member->size);
+
+ /* Also replace padding, if we regenerated the header. */
+ memset(buffer, 0, pad_bytes);
+ data = buffer;
+ len = pad_bytes;
+
+ /* Don't do this again unless we replace another header. */
+ mystreamer->rearchive_member = false;
+ }
+ else if (context == BBSTREAMER_ARCHIVE_TRAILER)
+ {
+ /* Trailer should always be two blocks of zero bytes. */
+ memset(buffer, 0, 2 * TAR_BLOCK_SIZE);
+ data = buffer;
+ len = 2 * TAR_BLOCK_SIZE;
+ }
+
+ bbstreamer_content(streamer->bbs_next, member, data, len, context);
+}
+
+/*
+ * End-of-stream processing for a tar archiver.
+ */
+static void
+bbstreamer_tar_archiver_finalize(bbstreamer *streamer)
+{
+ bbstreamer_finalize(streamer->bbs_next);
+}
+
+/*
+ * Free memory associated with a tar archiver.
+ */
+static void
+bbstreamer_tar_archiver_free(bbstreamer *streamer)
+{
+ bbstreamer_free(streamer->bbs_next);
+ pfree(streamer);
+}
+
+/*
+ * Create a bbstreamer that blindly adds two blocks of NUL bytes to the
+ * end of an incomplete tarfile that the server might send us.
+ */
+bbstreamer *
+bbstreamer_tar_terminator_new(bbstreamer *next)
+{
+ bbstreamer *streamer;
+
+ streamer = palloc0(sizeof(bbstreamer));
+ *((const bbstreamer_ops **) &streamer->bbs_ops) =
+ &bbstreamer_tar_terminator_ops;
+ streamer->bbs_next = next;
+
+ return streamer;
+}
+
+/*
+ * Pass all the content through without change.
+ */
+static void
+bbstreamer_tar_terminator_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ /* Expect unparsed input. */
+ Assert(member == NULL);
+ Assert(context == BBSTREAMER_UNKNOWN);
+
+ /* Just forward it. */
+ bbstreamer_content(streamer->bbs_next, member, data, len, context);
+}
+
+/*
+ * At the end, blindly add the two blocks of NUL bytes which the server fails
+ * to supply.
+ */
+static void
+bbstreamer_tar_terminator_finalize(bbstreamer *streamer)
+{
+ char buffer[2 * TAR_BLOCK_SIZE];
+
+ memset(buffer, 0, 2 * TAR_BLOCK_SIZE);
+ bbstreamer_content(streamer->bbs_next, NULL, buffer,
+ 2 * TAR_BLOCK_SIZE, BBSTREAMER_UNKNOWN);
+ bbstreamer_finalize(streamer->bbs_next);
+}
+
+/*
+ * Free memory associated with a tar terminator.
+ */
+static void
+bbstreamer_tar_terminator_free(bbstreamer *streamer)
+{
+ bbstreamer_free(streamer->bbs_next);
+ pfree(streamer);
+}
diff --git a/src/bin/pg_basebackup/bbstreamer_zstd.c b/src/bin/pg_basebackup/bbstreamer_zstd.c
new file mode 100644
index 0000000..1207dd7
--- /dev/null
+++ b/src/bin/pg_basebackup/bbstreamer_zstd.c
@@ -0,0 +1,355 @@
+/*-------------------------------------------------------------------------
+ *
+ * bbstreamer_zstd.c
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/bbstreamer_zstd.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <unistd.h>
+
+#ifdef USE_ZSTD
+#include <zstd.h>
+#endif
+
+#include "bbstreamer.h"
+#include "common/logging.h"
+
+#ifdef USE_ZSTD
+
+typedef struct bbstreamer_zstd_frame
+{
+ bbstreamer base;
+
+ ZSTD_CCtx *cctx;
+ ZSTD_DCtx *dctx;
+ ZSTD_outBuffer zstd_outBuf;
+} bbstreamer_zstd_frame;
+
+static void bbstreamer_zstd_compressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_zstd_compressor_finalize(bbstreamer *streamer);
+static void bbstreamer_zstd_compressor_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_zstd_compressor_ops = {
+ .content = bbstreamer_zstd_compressor_content,
+ .finalize = bbstreamer_zstd_compressor_finalize,
+ .free = bbstreamer_zstd_compressor_free
+};
+
+static void bbstreamer_zstd_decompressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context);
+static void bbstreamer_zstd_decompressor_finalize(bbstreamer *streamer);
+static void bbstreamer_zstd_decompressor_free(bbstreamer *streamer);
+
+const bbstreamer_ops bbstreamer_zstd_decompressor_ops = {
+ .content = bbstreamer_zstd_decompressor_content,
+ .finalize = bbstreamer_zstd_decompressor_finalize,
+ .free = bbstreamer_zstd_decompressor_free
+};
+#endif
+
+/*
+ * Create a new base backup streamer that performs zstd compression of tar
+ * blocks.
+ */
+bbstreamer *
+bbstreamer_zstd_compressor_new(bbstreamer *next, pg_compress_specification *compress)
+{
+#ifdef USE_ZSTD
+ bbstreamer_zstd_frame *streamer;
+ size_t ret;
+
+ Assert(next != NULL);
+
+ streamer = palloc0(sizeof(bbstreamer_zstd_frame));
+
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_zstd_compressor_ops;
+
+ streamer->base.bbs_next = next;
+ initStringInfo(&streamer->base.bbs_buffer);
+ enlargeStringInfo(&streamer->base.bbs_buffer, ZSTD_DStreamOutSize());
+
+ streamer->cctx = ZSTD_createCCtx();
+ if (!streamer->cctx)
+ pg_fatal("could not create zstd compression context");
+
+ /* Set compression level */
+ ret = ZSTD_CCtx_setParameter(streamer->cctx, ZSTD_c_compressionLevel,
+ compress->level);
+ if (ZSTD_isError(ret))
+ pg_fatal("could not set zstd compression level to %d: %s",
+ compress->level, ZSTD_getErrorName(ret));
+
+ /* Set # of workers, if specified */
+ if ((compress->options & PG_COMPRESSION_OPTION_WORKERS) != 0)
+ {
+ /*
+ * On older versions of libzstd, this option does not exist, and
+ * trying to set it will fail. Similarly for newer versions if they
+ * are compiled without threading support.
+ */
+ ret = ZSTD_CCtx_setParameter(streamer->cctx, ZSTD_c_nbWorkers,
+ compress->workers);
+ if (ZSTD_isError(ret))
+ pg_fatal("could not set compression worker count to %d: %s",
+ compress->workers, ZSTD_getErrorName(ret));
+ }
+
+ /* Initialize the ZSTD output buffer. */
+ streamer->zstd_outBuf.dst = streamer->base.bbs_buffer.data;
+ streamer->zstd_outBuf.size = streamer->base.bbs_buffer.maxlen;
+ streamer->zstd_outBuf.pos = 0;
+
+ return &streamer->base;
+#else
+ pg_fatal("this build does not support zstd compression");
+ return NULL; /* keep compiler quiet */
+#endif
+}
+
+#ifdef USE_ZSTD
+/*
+ * Compress the input data to output buffer.
+ *
+ * Find out the compression bound based on input data length for each
+ * invocation to make sure that output buffer has enough capacity to
+ * accommodate the compressed data. In case if the output buffer
+ * capacity falls short of compression bound then forward the content
+ * of output buffer to next streamer and empty the buffer.
+ */
+static void
+bbstreamer_zstd_compressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_zstd_frame *mystreamer = (bbstreamer_zstd_frame *) streamer;
+ ZSTD_inBuffer inBuf = {data, len, 0};
+
+ while (inBuf.pos < inBuf.size)
+ {
+ size_t yet_to_flush;
+ size_t max_needed = ZSTD_compressBound(inBuf.size - inBuf.pos);
+
+ /*
+ * If the output buffer is not left with enough space, send the
+ * compressed bytes to the next streamer, and empty the buffer.
+ */
+ if (mystreamer->zstd_outBuf.size - mystreamer->zstd_outBuf.pos <
+ max_needed)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ mystreamer->zstd_outBuf.dst,
+ mystreamer->zstd_outBuf.pos,
+ context);
+
+ /* Reset the ZSTD output buffer. */
+ mystreamer->zstd_outBuf.dst = mystreamer->base.bbs_buffer.data;
+ mystreamer->zstd_outBuf.size = mystreamer->base.bbs_buffer.maxlen;
+ mystreamer->zstd_outBuf.pos = 0;
+ }
+
+ yet_to_flush =
+ ZSTD_compressStream2(mystreamer->cctx, &mystreamer->zstd_outBuf,
+ &inBuf, ZSTD_e_continue);
+
+ if (ZSTD_isError(yet_to_flush))
+ pg_log_error("could not compress data: %s",
+ ZSTD_getErrorName(yet_to_flush));
+ }
+}
+
+/*
+ * End-of-stream processing.
+ */
+static void
+bbstreamer_zstd_compressor_finalize(bbstreamer *streamer)
+{
+ bbstreamer_zstd_frame *mystreamer = (bbstreamer_zstd_frame *) streamer;
+ size_t yet_to_flush;
+
+ do
+ {
+ ZSTD_inBuffer in = {NULL, 0, 0};
+ size_t max_needed = ZSTD_compressBound(0);
+
+ /*
+ * If the output buffer is not left with enough space, send the
+ * compressed bytes to the next streamer, and empty the buffer.
+ */
+ if (mystreamer->zstd_outBuf.size - mystreamer->zstd_outBuf.pos <
+ max_needed)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->zstd_outBuf.dst,
+ mystreamer->zstd_outBuf.pos,
+ BBSTREAMER_UNKNOWN);
+
+ /* Reset the ZSTD output buffer. */
+ mystreamer->zstd_outBuf.dst = mystreamer->base.bbs_buffer.data;
+ mystreamer->zstd_outBuf.size = mystreamer->base.bbs_buffer.maxlen;
+ mystreamer->zstd_outBuf.pos = 0;
+ }
+
+ yet_to_flush = ZSTD_compressStream2(mystreamer->cctx,
+ &mystreamer->zstd_outBuf,
+ &in, ZSTD_e_end);
+
+ if (ZSTD_isError(yet_to_flush))
+ pg_log_error("could not compress data: %s",
+ ZSTD_getErrorName(yet_to_flush));
+
+ } while (yet_to_flush > 0);
+
+ /* Make sure to pass any remaining bytes to the next streamer. */
+ if (mystreamer->zstd_outBuf.pos > 0)
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->zstd_outBuf.dst,
+ mystreamer->zstd_outBuf.pos,
+ BBSTREAMER_UNKNOWN);
+
+ bbstreamer_finalize(mystreamer->base.bbs_next);
+}
+
+/*
+ * Free memory.
+ */
+static void
+bbstreamer_zstd_compressor_free(bbstreamer *streamer)
+{
+ bbstreamer_zstd_frame *mystreamer = (bbstreamer_zstd_frame *) streamer;
+
+ bbstreamer_free(streamer->bbs_next);
+ ZSTD_freeCCtx(mystreamer->cctx);
+ pfree(streamer->bbs_buffer.data);
+ pfree(streamer);
+}
+#endif
+
+/*
+ * Create a new base backup streamer that performs decompression of zstd
+ * compressed blocks.
+ */
+bbstreamer *
+bbstreamer_zstd_decompressor_new(bbstreamer *next)
+{
+#ifdef USE_ZSTD
+ bbstreamer_zstd_frame *streamer;
+
+ Assert(next != NULL);
+
+ streamer = palloc0(sizeof(bbstreamer_zstd_frame));
+ *((const bbstreamer_ops **) &streamer->base.bbs_ops) =
+ &bbstreamer_zstd_decompressor_ops;
+
+ streamer->base.bbs_next = next;
+ initStringInfo(&streamer->base.bbs_buffer);
+ enlargeStringInfo(&streamer->base.bbs_buffer, ZSTD_DStreamOutSize());
+
+ streamer->dctx = ZSTD_createDCtx();
+ if (!streamer->dctx)
+ pg_fatal("could not create zstd decompression context");
+
+ /* Initialize the ZSTD output buffer. */
+ streamer->zstd_outBuf.dst = streamer->base.bbs_buffer.data;
+ streamer->zstd_outBuf.size = streamer->base.bbs_buffer.maxlen;
+ streamer->zstd_outBuf.pos = 0;
+
+ return &streamer->base;
+#else
+ pg_fatal("this build does not support zstd compression");
+ return NULL; /* keep compiler quiet */
+#endif
+}
+
+#ifdef USE_ZSTD
+/*
+ * Decompress the input data to output buffer until we run out of input
+ * data. Each time the output buffer is full, pass on the decompressed data
+ * to the next streamer.
+ */
+static void
+bbstreamer_zstd_decompressor_content(bbstreamer *streamer,
+ bbstreamer_member *member,
+ const char *data, int len,
+ bbstreamer_archive_context context)
+{
+ bbstreamer_zstd_frame *mystreamer = (bbstreamer_zstd_frame *) streamer;
+ ZSTD_inBuffer inBuf = {data, len, 0};
+
+ while (inBuf.pos < inBuf.size)
+ {
+ size_t ret;
+
+ /*
+ * If output buffer is full then forward the content to next streamer
+ * and update the output buffer.
+ */
+ if (mystreamer->zstd_outBuf.pos >= mystreamer->zstd_outBuf.size)
+ {
+ bbstreamer_content(mystreamer->base.bbs_next, member,
+ mystreamer->zstd_outBuf.dst,
+ mystreamer->zstd_outBuf.pos,
+ context);
+
+ /* Reset the ZSTD output buffer. */
+ mystreamer->zstd_outBuf.dst = mystreamer->base.bbs_buffer.data;
+ mystreamer->zstd_outBuf.size = mystreamer->base.bbs_buffer.maxlen;
+ mystreamer->zstd_outBuf.pos = 0;
+ }
+
+ ret = ZSTD_decompressStream(mystreamer->dctx,
+ &mystreamer->zstd_outBuf, &inBuf);
+
+ if (ZSTD_isError(ret))
+ pg_log_error("could not decompress data: %s",
+ ZSTD_getErrorName(ret));
+ }
+}
+
+/*
+ * End-of-stream processing.
+ */
+static void
+bbstreamer_zstd_decompressor_finalize(bbstreamer *streamer)
+{
+ bbstreamer_zstd_frame *mystreamer = (bbstreamer_zstd_frame *) streamer;
+
+ /*
+ * End of the stream, if there is some pending data in output buffers then
+ * we must forward it to next streamer.
+ */
+ if (mystreamer->zstd_outBuf.pos > 0)
+ bbstreamer_content(mystreamer->base.bbs_next, NULL,
+ mystreamer->base.bbs_buffer.data,
+ mystreamer->base.bbs_buffer.maxlen,
+ BBSTREAMER_UNKNOWN);
+
+ bbstreamer_finalize(mystreamer->base.bbs_next);
+}
+
+/*
+ * Free memory.
+ */
+static void
+bbstreamer_zstd_decompressor_free(bbstreamer *streamer)
+{
+ bbstreamer_zstd_frame *mystreamer = (bbstreamer_zstd_frame *) streamer;
+
+ bbstreamer_free(streamer->bbs_next);
+ ZSTD_freeDCtx(mystreamer->dctx);
+ pfree(streamer->bbs_buffer.data);
+ pfree(streamer);
+}
+#endif
diff --git a/src/bin/pg_basebackup/nls.mk b/src/bin/pg_basebackup/nls.mk
new file mode 100644
index 0000000..d127f18
--- /dev/null
+++ b/src/bin/pg_basebackup/nls.mk
@@ -0,0 +1,23 @@
+# src/bin/pg_basebackup/nls.mk
+CATALOG_NAME = pg_basebackup
+AVAIL_LANGUAGES = de el es fr it ja ka ko ru sv uk
+GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) \
+ bbstreamer_file.c \
+ bbstreamer_gzip.c \
+ bbstreamer_inject.c \
+ bbstreamer_lz4.c \
+ bbstreamer_tar.c \
+ bbstreamer_zstd.c \
+ pg_basebackup.c \
+ pg_receivewal.c \
+ pg_recvlogical.c \
+ receivelog.c \
+ streamutil.c \
+ walmethods.c \
+ ../../common/compression.c \
+ ../../common/fe_memutils.c \
+ ../../common/file_utils.c \
+ ../../fe_utils/option_utils.c \
+ ../../fe_utils/recovery_gen.c
+GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS) simple_prompt tar_set_error
+GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS)
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
new file mode 100644
index 0000000..e1af8c6
--- /dev/null
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -0,0 +1,2796 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_basebackup.c - receive a base backup using streaming replication protocol
+ *
+ * Author: Magnus Hagander <magnus@hagander.net>
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/pg_basebackup.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <unistd.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <time.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "access/xlog_internal.h"
+#include "backup/basebackup.h"
+#include "bbstreamer.h"
+#include "common/compression.h"
+#include "common/file_perm.h"
+#include "common/file_utils.h"
+#include "common/logging.h"
+#include "fe_utils/option_utils.h"
+#include "fe_utils/recovery_gen.h"
+#include "getopt_long.h"
+#include "receivelog.h"
+#include "streamutil.h"
+
+#define ERRCODE_DATA_CORRUPTED "XX001"
+
+typedef struct TablespaceListCell
+{
+ struct TablespaceListCell *next;
+ char old_dir[MAXPGPATH];
+ char new_dir[MAXPGPATH];
+} TablespaceListCell;
+
+typedef struct TablespaceList
+{
+ TablespaceListCell *head;
+ TablespaceListCell *tail;
+} TablespaceList;
+
+typedef struct ArchiveStreamState
+{
+ int tablespacenum;
+ pg_compress_specification *compress;
+ bbstreamer *streamer;
+ bbstreamer *manifest_inject_streamer;
+ PQExpBuffer manifest_buffer;
+ char manifest_filename[MAXPGPATH];
+ FILE *manifest_file;
+} ArchiveStreamState;
+
+typedef struct WriteTarState
+{
+ int tablespacenum;
+ bbstreamer *streamer;
+} WriteTarState;
+
+typedef struct WriteManifestState
+{
+ char filename[MAXPGPATH];
+ FILE *file;
+} WriteManifestState;
+
+typedef void (*WriteDataCallback) (size_t nbytes, char *buf,
+ void *callback_data);
+
+/*
+ * pg_xlog has been renamed to pg_wal in version 10. This version number
+ * should be compared with PQserverVersion().
+ */
+#define MINIMUM_VERSION_FOR_PG_WAL 100000
+
+/*
+ * Temporary replication slots are supported from version 10.
+ */
+#define MINIMUM_VERSION_FOR_TEMP_SLOTS 100000
+
+/*
+ * Backup manifests are supported from version 13.
+ */
+#define MINIMUM_VERSION_FOR_MANIFESTS 130000
+
+/*
+ * Before v15, tar files received from the server will be improperly
+ * terminated.
+ */
+#define MINIMUM_VERSION_FOR_TERMINATED_TARFILE 150000
+
+/*
+ * Different ways to include WAL
+ */
+typedef enum
+{
+ NO_WAL,
+ FETCH_WAL,
+ STREAM_WAL
+} IncludeWal;
+
+/*
+ * Different places to perform compression
+ */
+typedef enum
+{
+ COMPRESS_LOCATION_UNSPECIFIED,
+ COMPRESS_LOCATION_CLIENT,
+ COMPRESS_LOCATION_SERVER
+} CompressionLocation;
+
+/* Global options */
+static char *basedir = NULL;
+static TablespaceList tablespace_dirs = {NULL, NULL};
+static char *xlog_dir = NULL;
+static char format = '\0'; /* p(lain)/t(ar) */
+static char *label = "pg_basebackup base backup";
+static bool noclean = false;
+static bool checksum_failure = false;
+static bool showprogress = false;
+static bool estimatesize = true;
+static int verbose = 0;
+static IncludeWal includewal = STREAM_WAL;
+static bool fastcheckpoint = false;
+static bool writerecoveryconf = false;
+static bool do_sync = true;
+static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
+static pg_time_t last_progress_report = 0;
+static int32 maxrate = 0; /* no limit by default */
+static char *replication_slot = NULL;
+static bool temp_replication_slot = true;
+static char *backup_target = NULL;
+static bool create_slot = false;
+static bool no_slot = false;
+static bool verify_checksums = true;
+static bool manifest = true;
+static bool manifest_force_encode = false;
+static char *manifest_checksums = NULL;
+
+static bool success = false;
+static bool made_new_pgdata = false;
+static bool found_existing_pgdata = false;
+static bool made_new_xlogdir = false;
+static bool found_existing_xlogdir = false;
+static bool made_tablespace_dirs = false;
+static bool found_tablespace_dirs = false;
+
+/* Progress indicators */
+static uint64 totalsize_kb;
+static uint64 totaldone;
+static int tablespacecount;
+static char *progress_filename = NULL;
+
+/* Pipe to communicate with background wal receiver process */
+#ifndef WIN32
+static int bgpipe[2] = {-1, -1};
+#endif
+
+/* Handle to child process */
+static pid_t bgchild = -1;
+static bool in_log_streamer = false;
+
+/* Flag to indicate if child process exited unexpectedly */
+static volatile sig_atomic_t bgchild_exited = false;
+
+/* End position for xlog streaming, empty string if unknown yet */
+static XLogRecPtr xlogendptr;
+
+#ifndef WIN32
+static int has_xlogendptr = 0;
+#else
+static volatile LONG has_xlogendptr = 0;
+#endif
+
+/* Contents of configuration file to be generated */
+static PQExpBuffer recoveryconfcontents = NULL;
+
+/* Function headers */
+static void usage(void);
+static void verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found);
+static void progress_update_filename(const char *filename);
+static void progress_report(int tablespacenum, bool force, bool finished);
+
+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 ReceiveArchiveStreamChunk(size_t r, char *copybuf,
+ void *callback_data);
+static char GetCopyDataByte(size_t r, char *copybuf, size_t *cursor);
+static char *GetCopyDataString(size_t r, char *copybuf, size_t *cursor);
+static uint64 GetCopyDataUInt64(size_t r, char *copybuf, size_t *cursor);
+static void GetCopyDataEnd(size_t r, char *copybuf, size_t cursor);
+static void ReportCopyDataParseError(size_t r, char *copybuf);
+static void ReceiveTarFile(PGconn *conn, char *archive_name, char *spclocation,
+ bool tablespacenum, pg_compress_specification *compress);
+static void ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data);
+static void ReceiveBackupManifest(PGconn *conn);
+static void ReceiveBackupManifestChunk(size_t r, char *copybuf,
+ void *callback_data);
+static void ReceiveBackupManifestInMemory(PGconn *conn, PQExpBuffer buf);
+static void ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf,
+ void *callback_data);
+static void BaseBackup(char *compression_algorithm, char *compression_detail,
+ CompressionLocation compressloc,
+ pg_compress_specification *client_compress);
+
+static bool reached_end_position(XLogRecPtr segendpos, uint32 timeline,
+ bool segment_finished);
+
+static const char *get_tablespace_mapping(const char *dir);
+static void tablespace_list_append(const char *arg);
+
+
+static void
+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");
+ }
+ else if (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");
+ }
+ else if (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");
+}
+
+static void
+disconnect_atexit(void)
+{
+ if (conn != NULL)
+ PQfinish(conn);
+}
+
+#ifndef WIN32
+/*
+ * If the bgchild exits prematurely and raises a SIGCHLD signal, we can abort
+ * processing rather than wait until the backup has finished and error out at
+ * that time. On Windows, we use a background thread which can communicate
+ * without the need for a signal handler.
+ */
+static void
+sigchld_handler(SIGNAL_ARGS)
+{
+ bgchild_exited = true;
+}
+
+/*
+ * On windows, our background thread dies along with the process. But on
+ * Unix, if we have started a subprocess, we want to kill it off so it
+ * doesn't remain running trying to stream data.
+ */
+static void
+kill_bgchild_atexit(void)
+{
+ if (bgchild > 0 && !bgchild_exited)
+ kill(bgchild, SIGTERM);
+}
+#endif
+
+/*
+ * Split argument into old_dir and new_dir and append to tablespace mapping
+ * list.
+ */
+static void
+tablespace_list_append(const char *arg)
+{
+ TablespaceListCell *cell = (TablespaceListCell *) pg_malloc0(sizeof(TablespaceListCell));
+ char *dst;
+ char *dst_ptr;
+ const char *arg_ptr;
+
+ dst_ptr = dst = cell->old_dir;
+ for (arg_ptr = arg; *arg_ptr; arg_ptr++)
+ {
+ if (dst_ptr - dst >= MAXPGPATH)
+ pg_fatal("directory name too long");
+
+ if (*arg_ptr == '\\' && *(arg_ptr + 1) == '=')
+ ; /* skip backslash escaping = */
+ else if (*arg_ptr == '=' && (arg_ptr == arg || *(arg_ptr - 1) != '\\'))
+ {
+ if (*cell->new_dir)
+ pg_fatal("multiple \"=\" signs in tablespace mapping");
+ else
+ dst = dst_ptr = cell->new_dir;
+ }
+ else
+ *dst_ptr++ = *arg_ptr;
+ }
+
+ if (!*cell->old_dir || !*cell->new_dir)
+ pg_fatal("invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\"", arg);
+
+ /*
+ * All tablespaces are created with absolute directories, so specifying a
+ * non-absolute path here would just never match, possibly confusing users.
+ * Since we don't know whether the remote side is Windows or not, and it
+ * might be different than the local side, permit any path that could be
+ * absolute under either set of rules.
+ *
+ * (There is little practical risk of confusion here, because someone
+ * running entirely on Linux isn't likely to have a relative path that
+ * begins with a backslash or something that looks like a drive
+ * specification. If they do, and they also incorrectly believe that
+ * a relative path is acceptable here, we'll silently fail to warn them
+ * of their mistake, and the -T option will just not get applied, same
+ * as if they'd specified -T for a nonexistent tablespace.)
+ */
+ if (!is_nonwindows_absolute_path(cell->old_dir) &&
+ !is_windows_absolute_path(cell->old_dir))
+ pg_fatal("old directory is not an absolute path in tablespace mapping: %s",
+ cell->old_dir);
+
+ if (!is_absolute_path(cell->new_dir))
+ pg_fatal("new directory is not an absolute path in tablespace mapping: %s",
+ cell->new_dir);
+
+ /*
+ * Comparisons done with these values should involve similarly
+ * canonicalized path values. This is particularly sensitive on Windows
+ * where path values may not necessarily use Unix slashes.
+ */
+ canonicalize_path(cell->old_dir);
+ canonicalize_path(cell->new_dir);
+
+ if (tablespace_dirs.tail)
+ tablespace_dirs.tail->next = cell;
+ else
+ tablespace_dirs.head = cell;
+ tablespace_dirs.tail = cell;
+}
+
+
+static void
+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(_(" -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 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(_(" -?, --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);
+}
+
+
+/*
+ * Called in the background process every time data is received.
+ * On Unix, we check to see if there is any data on our pipe
+ * (which would mean we have a stop position), and if it is, check if
+ * it is time to stop.
+ * On Windows, we are in a single process, so we can just check if it's
+ * time to stop.
+ */
+static bool
+reached_end_position(XLogRecPtr segendpos, uint32 timeline,
+ bool segment_finished)
+{
+ if (!has_xlogendptr)
+ {
+#ifndef WIN32
+ fd_set fds;
+ struct timeval tv;
+ int r;
+
+ /*
+ * Don't have the end pointer yet - check our pipe to see if it has
+ * been sent yet.
+ */
+ FD_ZERO(&fds);
+ FD_SET(bgpipe[0], &fds);
+
+ MemSet(&tv, 0, sizeof(tv));
+
+ r = select(bgpipe[0] + 1, &fds, NULL, NULL, &tv);
+ if (r == 1)
+ {
+ char xlogend[64];
+ uint32 hi,
+ lo;
+
+ MemSet(xlogend, 0, sizeof(xlogend));
+ r = read(bgpipe[0], xlogend, sizeof(xlogend) - 1);
+ if (r < 0)
+ pg_fatal("could not read from ready pipe: %m");
+
+ if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
+ pg_fatal("could not parse write-ahead log location \"%s\"",
+ xlogend);
+ xlogendptr = ((uint64) hi) << 32 | lo;
+ has_xlogendptr = 1;
+
+ /*
+ * Fall through to check if we've reached the point further
+ * already.
+ */
+ }
+ else
+ {
+ /*
+ * No data received on the pipe means we don't know the end
+ * position yet - so just say it's not time to stop yet.
+ */
+ return false;
+ }
+#else
+
+ /*
+ * On win32, has_xlogendptr is set by the main thread, so if it's not
+ * set here, we just go back and wait until it shows up.
+ */
+ return false;
+#endif
+ }
+
+ /*
+ * At this point we have an end pointer, so compare it to the current
+ * position to figure out if it's time to stop.
+ */
+ if (segendpos >= xlogendptr)
+ return true;
+
+ /*
+ * Have end pointer, but haven't reached it yet - so tell the caller to
+ * keep streaming.
+ */
+ return false;
+}
+
+typedef struct
+{
+ PGconn *bgconn;
+ XLogRecPtr startptr;
+ char xlog[MAXPGPATH]; /* directory or tarfile depending on mode */
+ char *sysidentifier;
+ int timeline;
+ pg_compress_algorithm wal_compress_algorithm;
+ int wal_compress_level;
+} logstreamer_param;
+
+static int
+LogStreamerMain(logstreamer_param *param)
+{
+ StreamCtl stream;
+
+ in_log_streamer = true;
+
+ MemSet(&stream, 0, sizeof(stream));
+ stream.startpos = param->startptr;
+ stream.timeline = param->timeline;
+ stream.sysidentifier = param->sysidentifier;
+ stream.stream_stop = reached_end_position;
+#ifndef WIN32
+ stream.stop_socket = bgpipe[0];
+#else
+ stream.stop_socket = PGINVALID_SOCKET;
+#endif
+ stream.standby_message_timeout = standby_message_timeout;
+ stream.synchronous = false;
+ /* fsync happens at the end of pg_basebackup for all data */
+ stream.do_sync = false;
+ stream.mark_done = true;
+ stream.partial_suffix = NULL;
+ stream.replication_slot = replication_slot;
+ if (format == 'p')
+ stream.walmethod = CreateWalDirectoryMethod(param->xlog,
+ PG_COMPRESSION_NONE, 0,
+ stream.do_sync);
+ else
+ stream.walmethod = CreateWalTarMethod(param->xlog,
+ param->wal_compress_algorithm,
+ param->wal_compress_level,
+ stream.do_sync);
+
+ if (!ReceiveXlogStream(param->bgconn, &stream))
+ {
+ /*
+ * Any errors will already have been reported in the function process,
+ * but we need to tell the parent that we didn't shutdown in a nice
+ * way.
+ */
+#ifdef WIN32
+ /*
+ * In order to signal the main thread of an ungraceful exit we set the
+ * same flag that we use on Unix to signal SIGCHLD.
+ */
+ bgchild_exited = true;
+#endif
+ return 1;
+ }
+
+ if (!stream.walmethod->finish())
+ {
+ pg_log_error("could not finish writing WAL files: %m");
+#ifdef WIN32
+ bgchild_exited = true;
+#endif
+ return 1;
+ }
+
+ PQfinish(param->bgconn);
+
+ if (format == 'p')
+ FreeWalDirectoryMethod();
+ else
+ FreeWalTarMethod();
+ pg_free(stream.walmethod);
+
+ return 0;
+}
+
+/*
+ * Initiate background process for receiving xlog during the backup.
+ * The background stream will use its own database connection so we can
+ * stream the logfile in parallel with the backups.
+ */
+static void
+StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier,
+ pg_compress_algorithm wal_compress_algorithm,
+ int wal_compress_level)
+{
+ logstreamer_param *param;
+ uint32 hi,
+ lo;
+ char statusdir[MAXPGPATH];
+
+ param = pg_malloc0(sizeof(logstreamer_param));
+ param->timeline = timeline;
+ param->sysidentifier = sysidentifier;
+ param->wal_compress_algorithm = wal_compress_algorithm;
+ param->wal_compress_level = wal_compress_level;
+
+ /* 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;
+
+ /*
+ * Create replication slot if requested
+ */
+ if (temp_replication_slot && !replication_slot)
+ replication_slot = psprintf("pg_basebackup_%d", (int) PQbackendPID(param->bgconn));
+ if (temp_replication_slot || create_slot)
+ {
+ if (!CreateReplicationSlot(param->bgconn, replication_slot, NULL,
+ temp_replication_slot, true, true, 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);
+ }
+ }
+
+ if (format == 'p')
+ {
+ /*
+ * Create pg_wal/archive_status or pg_xlog/archive_status (and thus
+ * pg_wal or pg_xlog) depending on the target server so we can write
+ * to basedir/pg_wal or basedir/pg_xlog as the directory entry in the
+ * tar file may arrive later.
+ */
+ snprintf(statusdir, sizeof(statusdir), "%s/%s/archive_status",
+ basedir,
+ PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
+ "pg_xlog" : "pg_wal");
+
+ if (pg_mkdir_p(statusdir, pg_dir_create_mode) != 0 && errno != EEXIST)
+ pg_fatal("could not create directory \"%s\": %m", statusdir);
+ }
+
+ /*
+ * Start a child process and tell it to start streaming. On Unix, this is
+ * a fork(). On Windows, we create a thread.
+ */
+#ifndef WIN32
+ bgchild = fork();
+ if (bgchild == 0)
+ {
+ /* in child process */
+ exit(LogStreamerMain(param));
+ }
+ else if (bgchild < 0)
+ pg_fatal("could not create background process: %m");
+
+ /*
+ * Else we are in the parent process and all is well.
+ */
+ atexit(kill_bgchild_atexit);
+#else /* WIN32 */
+ bgchild = _beginthreadex(NULL, 0, (void *) LogStreamerMain, param, 0, NULL);
+ if (bgchild == 0)
+ pg_fatal("could not create background thread: %m");
+#endif
+}
+
+/*
+ * Verify that the given directory exists and is empty. If it does not
+ * exist, it is created. If it exists but is not empty, an error will
+ * be given and the process ended.
+ */
+static void
+verify_dir_is_empty_or_create(char *dirname, bool *created, bool *found)
+{
+ switch (pg_check_dir(dirname))
+ {
+ case 0:
+
+ /*
+ * Does not exist, so create
+ */
+ if (pg_mkdir_p(dirname, pg_dir_create_mode) == -1)
+ pg_fatal("could not create directory \"%s\": %m", dirname);
+ if (created)
+ *created = true;
+ return;
+ case 1:
+
+ /*
+ * Exists, empty
+ */
+ if (found)
+ *found = true;
+ return;
+ case 2:
+ case 3:
+ case 4:
+
+ /*
+ * Exists, not empty
+ */
+ pg_fatal("directory \"%s\" exists but is not empty", dirname);
+ case -1:
+
+ /*
+ * Access problem
+ */
+ pg_fatal("could not access directory \"%s\": %m", dirname);
+ }
+}
+
+/*
+ * Callback to update our notion of the current filename.
+ *
+ * No other code should modify progress_filename!
+ */
+static void
+progress_update_filename(const char *filename)
+{
+ /* We needn't maintain this variable if not doing verbose reports. */
+ if (showprogress && verbose)
+ {
+ if (progress_filename)
+ free(progress_filename);
+ if (filename)
+ progress_filename = pg_strdup(filename);
+ else
+ progress_filename = NULL;
+ }
+}
+
+/*
+ * Print a progress report based on the global variables. If verbose output
+ * is enabled, also print the current file name.
+ *
+ * Progress report is written at maximum once per second, unless the force
+ * parameter is set to true.
+ *
+ * If finished is set to true, this is the last progress report. The cursor
+ * is moved to the next line.
+ */
+static void
+progress_report(int tablespacenum, bool force, bool finished)
+{
+ int percent;
+ char totaldone_str[32];
+ char totalsize_str[32];
+ pg_time_t now;
+
+ if (!showprogress)
+ return;
+
+ now = time(NULL);
+ if (now == last_progress_report && !force && !finished)
+ return; /* Max once per second */
+
+ last_progress_report = now;
+ percent = totalsize_kb ? (int) ((totaldone / 1024) * 100 / totalsize_kb) : 0;
+
+ /*
+ * Avoid overflowing past 100% or the full size. This may make the total
+ * size number change as we approach the end of the backup (the estimate
+ * will always be wrong if WAL is included), but that's better than having
+ * the done column be bigger than the total.
+ */
+ if (percent > 100)
+ percent = 100;
+ if (totaldone / 1024 > totalsize_kb)
+ totalsize_kb = totaldone / 1024;
+
+ snprintf(totaldone_str, sizeof(totaldone_str), UINT64_FORMAT,
+ totaldone / 1024);
+ snprintf(totalsize_str, sizeof(totalsize_str), UINT64_FORMAT, totalsize_kb);
+
+#define VERBOSE_FILENAME_LENGTH 35
+ if (verbose)
+ {
+ if (!progress_filename)
+
+ /*
+ * No filename given, so clear the status line (used for last
+ * call)
+ */
+ fprintf(stderr,
+ ngettext("%*s/%s kB (100%%), %d/%d tablespace %*s",
+ "%*s/%s kB (100%%), %d/%d tablespaces %*s",
+ tablespacecount),
+ (int) strlen(totalsize_str),
+ totaldone_str, totalsize_str,
+ tablespacenum, tablespacecount,
+ VERBOSE_FILENAME_LENGTH + 5, "");
+ else
+ {
+ bool truncate = (strlen(progress_filename) > VERBOSE_FILENAME_LENGTH);
+
+ fprintf(stderr,
+ ngettext("%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)",
+ "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)",
+ tablespacecount),
+ (int) strlen(totalsize_str),
+ totaldone_str, totalsize_str, percent,
+ tablespacenum, tablespacecount,
+ /* Prefix with "..." if we do leading truncation */
+ truncate ? "..." : "",
+ truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH,
+ truncate ? VERBOSE_FILENAME_LENGTH - 3 : VERBOSE_FILENAME_LENGTH,
+ /* Truncate filename at beginning if it's too long */
+ truncate ? progress_filename + strlen(progress_filename) - VERBOSE_FILENAME_LENGTH + 3 : progress_filename);
+ }
+ }
+ else
+ fprintf(stderr,
+ ngettext("%*s/%s kB (%d%%), %d/%d tablespace",
+ "%*s/%s kB (%d%%), %d/%d tablespaces",
+ tablespacecount),
+ (int) strlen(totalsize_str),
+ totaldone_str, totalsize_str, percent,
+ tablespacenum, tablespacecount);
+
+ /*
+ * Stay on the same line if reporting to a terminal and we're not done
+ * yet.
+ */
+ fputc((!finished && isatty(fileno(stderr))) ? '\r' : '\n', stderr);
+}
+
+static int32
+parse_max_rate(char *src)
+{
+ double result;
+ char *after_num;
+ char *suffix = NULL;
+
+ 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)
+ {
+ /*
+ * Reject obviously wrong values here.
+ */
+ pg_fatal("transfer rate must be greater than zero");
+ }
+
+ /*
+ * Evaluate suffix, after skipping over possible whitespace. Lack of
+ * suffix means kilobytes.
+ */
+ while (*after_num != '\0' && isspace((unsigned char) *after_num))
+ after_num++;
+
+ if (*after_num != '\0')
+ {
+ suffix = after_num;
+ if (*after_num == 'k')
+ {
+ /* kilobyte is the expected unit. */
+ after_num++;
+ }
+ else if (*after_num == 'M')
+ {
+ after_num++;
+ result *= 1024.0;
+ }
+ }
+
+ /* The rest can only consist of white space. */
+ while (*after_num != '\0' && isspace((unsigned char) *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);
+
+ /*
+ * The range is checked on the server side too, but avoid the server
+ * connection if a nonsensical value was passed.
+ */
+ if (result < MAX_RATE_LOWER || result > MAX_RATE_UPPER)
+ pg_fatal("transfer rate \"%s\" is out of range", src);
+
+ return (int32) result;
+}
+
+/*
+ * Basic parsing of a value specified for -Z/--compress.
+ *
+ * We're not concerned here with understanding exactly what behavior the
+ * user wants, but we do need to know whether the user is requesting client
+ * or server side compression or leaving it unspecified, and we need to
+ * separate the name of the compression algorithm from the detail string.
+ *
+ * For instance, if the user writes --compress client-lz4:6, we want to
+ * separate that into (a) client-side compression, (b) algorithm "lz4",
+ * and (c) detail "6". Note, however, that all the client/server prefix is
+ * optional, and so is the detail. The algorithm name is required, unless
+ * the whole string is an integer, in which case we assume "gzip" as the
+ * algorithm and use the integer as the detail.
+ *
+ * We're not concerned with validation at this stage, so if the user writes
+ * --compress client-turkey:sandwich, the requested algorithm is "turkey"
+ * and the detail string is "sandwich". We'll sort out whether that's legal
+ * at a later stage.
+ */
+static void
+parse_compress_options(char *option, char **algorithm, char **detail,
+ CompressionLocation *locationres)
+{
+ char *sep;
+ char *endp;
+
+ /*
+ * Check whether the compression specification consists of a bare integer.
+ *
+ * If so, for backward compatibility, assume gzip.
+ */
+ (void) strtol(option, &endp, 10);
+ if (*endp == '\0')
+ {
+ *locationres = COMPRESS_LOCATION_UNSPECIFIED;
+ *algorithm = pstrdup("gzip");
+ *detail = pstrdup(option);
+ return;
+ }
+
+ /* Strip off any "client-" or "server-" prefix. */
+ if (strncmp(option, "server-", 7) == 0)
+ {
+ *locationres = COMPRESS_LOCATION_SERVER;
+ option += 7;
+ }
+ else if (strncmp(option, "client-", 7) == 0)
+ {
+ *locationres = COMPRESS_LOCATION_CLIENT;
+ option += 7;
+ }
+ else
+ *locationres = COMPRESS_LOCATION_UNSPECIFIED;
+
+ /*
+ * Check whether there is a compression detail following the algorithm
+ * name.
+ */
+ sep = strchr(option, ':');
+ if (sep == NULL)
+ {
+ *algorithm = pstrdup(option);
+ *detail = NULL;
+ }
+ else
+ {
+ char *alg;
+
+ alg = palloc((sep - option) + 1);
+ memcpy(alg, option, sep - option);
+ alg[sep - option] = '\0';
+
+ *algorithm = alg;
+ *detail = pstrdup(sep + 1);
+ }
+}
+
+/*
+ * Read a stream of COPY data and invoke the provided callback for each
+ * chunk.
+ */
+static void
+ReceiveCopyData(PGconn *conn, WriteDataCallback callback,
+ void *callback_data)
+{
+ PGresult *res;
+
+ /* 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;
+
+ r = PQgetCopyData(conn, &copybuf, 0);
+ if (r == -1)
+ {
+ /* End of chunk. */
+ break;
+ }
+ else if (r == -2)
+ pg_fatal("could not read COPY data: %s",
+ PQerrorMessage(conn));
+
+ if (bgchild_exited)
+ pg_fatal("background process terminated unexpectedly");
+
+ (*callback) (r, copybuf, callback_data);
+
+ PQfreemem(copybuf);
+ }
+}
+
+/*
+ * Figure out what to do with an archive received from the server based on
+ * the options selected by the user. We may just write the results directly
+ * to a file, or we might compress first, or we might extract the tar file
+ * and write each member separately. This function doesn't do any of that
+ * directly, but it works out what kind of bbstreamer we need to create so
+ * that the right stuff happens when, down the road, we actually receive
+ * the data.
+ */
+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)
+{
+ bbstreamer *streamer = NULL;
+ bbstreamer *manifest_inject_streamer = NULL;
+ bool inject_manifest;
+ bool is_tar,
+ is_tar_gz,
+ is_tar_lz4,
+ is_tar_zstd,
+ is_compressed_tar;
+ bool must_parse_archive;
+ int archive_name_len = strlen(archive_name);
+
+ /*
+ * Normally, we emit the backup manifest as a separate file, but when
+ * we're writing a tarfile to stdout, we don't have that option, so
+ * include it in the one tarfile we've got.
+ */
+ inject_manifest = (format == 't' && strcmp(basedir, "-") == 0 && manifest);
+
+ /* 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;
+
+ /*
+ * Injecting the manifest into a compressed tar file would be possible if
+ * we decompressed it, parsed the tarfile, generated a new tarfile, and
+ * recompressed it, but compressing and decompressing multiple times just
+ * to inject the manifest seems inefficient enough that it's probably not
+ * what the user wants. So, instead, reject the request and tell the user
+ * to specify something more reasonable.
+ */
+ 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);
+ }
+
+ /*
+ * We have to parse the archive if (1) we're suppose to extract it, or if
+ * (2) we need to inject backup_manifest or recovery configuration into
+ * it. However, we only know how to parse tar archives.
+ */
+ must_parse_archive = (format == 'p' || inject_manifest ||
+ (spclocation == NULL && writerecoveryconf));
+
+ /* 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);
+ }
+
+ if (format == 'p')
+ {
+ const char *directory;
+
+ /*
+ * In plain format, we must extract the archive. The data for the main
+ * tablespace will be written to the base directory, and the data for
+ * other tablespaces will be written to the directory where they're
+ * located on the server, after applying any user-specified tablespace
+ * mappings.
+ */
+ directory = spclocation == NULL ? basedir
+ : get_tablespace_mapping(spclocation);
+ streamer = bbstreamer_extractor_new(directory,
+ get_tablespace_mapping,
+ progress_update_filename);
+ }
+ else
+ {
+ FILE *archive_file;
+ char archive_filename[MAXPGPATH];
+
+ /*
+ * In tar format, we just write the archive without extracting it.
+ * Normally, we write it to the archive name provided by the caller,
+ * but when the base directory is "-" that means we need to write to
+ * standard output.
+ */
+ if (strcmp(basedir, "-") == 0)
+ {
+ snprintf(archive_filename, sizeof(archive_filename), "-");
+ archive_file = stdout;
+ }
+ else
+ {
+ snprintf(archive_filename, sizeof(archive_filename),
+ "%s/%s", basedir, archive_name);
+ archive_file = NULL;
+ }
+
+ if (compress->algorithm == PG_COMPRESSION_NONE)
+ streamer = bbstreamer_plain_writer_new(archive_filename,
+ archive_file);
+ else if (compress->algorithm == PG_COMPRESSION_GZIP)
+ {
+ strlcat(archive_filename, ".gz", sizeof(archive_filename));
+ streamer = bbstreamer_gzip_writer_new(archive_filename,
+ archive_file, compress);
+ }
+ else if (compress->algorithm == PG_COMPRESSION_LZ4)
+ {
+ strlcat(archive_filename, ".lz4", sizeof(archive_filename));
+ streamer = bbstreamer_plain_writer_new(archive_filename,
+ archive_file);
+ streamer = bbstreamer_lz4_compressor_new(streamer, compress);
+ }
+ else if (compress->algorithm == PG_COMPRESSION_ZSTD)
+ {
+ strlcat(archive_filename, ".zst", sizeof(archive_filename));
+ streamer = bbstreamer_plain_writer_new(archive_filename,
+ archive_file);
+ streamer = bbstreamer_zstd_compressor_new(streamer, compress);
+ }
+ else
+ {
+ Assert(false); /* not reachable */
+ }
+
+ /*
+ * If we need to parse the archive for whatever reason, then we'll
+ * also need to re-archive, because, if the output format is tar, the
+ * only point of parsing the archive is to be able to inject stuff
+ * into it.
+ */
+ if (must_parse_archive)
+ streamer = bbstreamer_tar_archiver_new(streamer);
+ progress_update_filename(archive_filename);
+ }
+
+ /*
+ * If we're supposed to inject the backup manifest into the results, it
+ * should be done here, so that the file content can be injected directly,
+ * without worrying about the details of the tar format.
+ */
+ if (inject_manifest)
+ manifest_inject_streamer = streamer;
+
+ /*
+ * If this is the main tablespace and we're supposed to write recovery
+ * information, arrange to do that.
+ */
+ if (spclocation == NULL && writerecoveryconf)
+ {
+ Assert(must_parse_archive);
+ streamer = bbstreamer_recovery_injector_new(streamer,
+ is_recovery_guc_supported,
+ recoveryconfcontents);
+ }
+
+ /*
+ * If we're doing anything that involves understanding the contents of the
+ * archive, we'll need to parse it. If not, we can skip parsing it, but
+ * old versions of the server send improperly terminated tarfiles, so if
+ * we're talking to such a server we'll need to add the terminator here.
+ */
+ if (must_parse_archive)
+ streamer = bbstreamer_tar_parser_new(streamer);
+ else if (expect_unterminated_tarfile)
+ streamer = bbstreamer_tar_terminator_new(streamer);
+
+ /*
+ * If the user has requested a server compressed archive along with
+ * archive extraction at client then we need to decompress it.
+ */
+ if (format == 'p')
+ {
+ if (is_tar_gz)
+ streamer = bbstreamer_gzip_decompressor_new(streamer);
+ else if (is_tar_lz4)
+ streamer = bbstreamer_lz4_decompressor_new(streamer);
+ else if (is_tar_zstd)
+ streamer = bbstreamer_zstd_decompressor_new(streamer);
+ }
+
+ /* Return the results. */
+ *manifest_inject_streamer_p = manifest_inject_streamer;
+ return streamer;
+}
+
+/*
+ * Receive all of the archives the server wants to send - and the backup
+ * manifest if present - as a single COPY stream.
+ */
+static void
+ReceiveArchiveStream(PGconn *conn, pg_compress_specification *compress)
+{
+ ArchiveStreamState state;
+
+ /* 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 we buffered the backup manifest in order to inject it into the
+ * output tarfile, do that now.
+ */
+ if (state.manifest_inject_streamer != NULL &&
+ state.manifest_buffer != NULL)
+ {
+ bbstreamer_inject_file(state.manifest_inject_streamer,
+ "backup_manifest",
+ state.manifest_buffer->data,
+ state.manifest_buffer->len);
+ destroyPQExpBuffer(state.manifest_buffer);
+ state.manifest_buffer = NULL;
+ }
+
+ /* If there's still an archive in progress, end processing. */
+ if (state.streamer != NULL)
+ {
+ bbstreamer_finalize(state.streamer);
+ bbstreamer_free(state.streamer);
+ state.streamer = NULL;
+ }
+}
+
+/*
+ * Receive one chunk of data sent by the server as part of a single COPY
+ * stream that includes all archives and the manifest.
+ */
+static void
+ReceiveArchiveStreamChunk(size_t r, char *copybuf, void *callback_data)
+{
+ ArchiveStreamState *state = callback_data;
+ size_t cursor = 0;
+
+ /* Each CopyData message begins with a type byte. */
+ switch (GetCopyDataByte(r, copybuf, &cursor))
+ {
+ case 'n':
+ {
+ /* New archive. */
+ char *archive_name;
+ char *spclocation;
+
+ /*
+ * We force a progress report at the end of each tablespace. A
+ * new tablespace starts when the previous one ends, except in
+ * the case of the very first one.
+ */
+ if (++state->tablespacenum > 0)
+ progress_report(state->tablespacenum, true, false);
+
+ /* Sanity check. */
+ if (state->manifest_buffer != NULL ||
+ state->manifest_file !=NULL)
+ pg_fatal("archives must precede manifest");
+
+ /* Parse the rest of the CopyData message. */
+ archive_name = GetCopyDataString(r, copybuf, &cursor);
+ spclocation = GetCopyDataString(r, copybuf, &cursor);
+ GetCopyDataEnd(r, copybuf, cursor);
+
+ /*
+ * Basic sanity checks on the archive name: it shouldn't be
+ * empty, it shouldn't start with a dot, and it shouldn't
+ * contain a path separator.
+ */
+ if (archive_name[0] == '\0' || archive_name[0] == '.' ||
+ strchr(archive_name, '/') != NULL ||
+ strchr(archive_name, '\\') != NULL)
+ pg_fatal("invalid archive name: \"%s\"",
+ archive_name);
+
+ /*
+ * An empty spclocation is treated as NULL. We expect this
+ * case to occur for the data directory itself, but not for
+ * any archives that correspond to tablespaces.
+ */
+ if (spclocation[0] == '\0')
+ spclocation = NULL;
+
+ /* End processing of any prior archive. */
+ if (state->streamer != NULL)
+ {
+ bbstreamer_finalize(state->streamer);
+ bbstreamer_free(state->streamer);
+ state->streamer = NULL;
+ }
+
+ /*
+ * Create an appropriate backup streamer, unless a backup
+ * target was specified. In that case, it's up to the server
+ * to put the backup wherever it needs to go.
+ */
+ if (backup_target == NULL)
+ {
+ /*
+ * We know that recovery GUCs are supported, because this
+ * protocol can only be used on v15+.
+ */
+ state->streamer =
+ CreateBackupStreamer(archive_name,
+ spclocation,
+ &state->manifest_inject_streamer,
+ true, false,
+ state->compress);
+ }
+ break;
+ }
+
+ case 'd':
+ {
+ /* Archive or manifest data. */
+ if (state->manifest_buffer != NULL)
+ {
+ /* Manifest data, buffer in memory. */
+ appendPQExpBuffer(state->manifest_buffer, copybuf + 1,
+ r - 1);
+ }
+ else if (state->manifest_file !=NULL)
+ {
+ /* Manifest data, write to disk. */
+ if (fwrite(copybuf + 1, r - 1, 1,
+ state->manifest_file) != 1)
+ {
+ /*
+ * If fwrite() didn't set errno, assume that the
+ * problem is that we're out of disk space.
+ */
+ if (errno == 0)
+ errno = ENOSPC;
+ pg_fatal("could not write to file \"%s\": %m",
+ state->manifest_filename);
+ }
+ }
+ else if (state->streamer != NULL)
+ {
+ /* Archive data. */
+ bbstreamer_content(state->streamer, NULL, copybuf + 1,
+ r - 1, BBSTREAMER_UNKNOWN);
+ }
+ else
+ pg_fatal("unexpected payload data");
+ break;
+ }
+
+ case 'p':
+ {
+ /*
+ * Progress report.
+ *
+ * The remainder of the message is expected to be an 8-byte
+ * count of bytes completed.
+ */
+ totaldone = GetCopyDataUInt64(r, copybuf, &cursor);
+ GetCopyDataEnd(r, copybuf, cursor);
+
+ /*
+ * The server shouldn't send progress report messages too
+ * often, so we force an update each time we receive one.
+ */
+ progress_report(state->tablespacenum, true, false);
+ break;
+ }
+
+ case 'm':
+ {
+ /*
+ * Manifest data will be sent next. This message is not
+ * expected to have any further payload data.
+ */
+ GetCopyDataEnd(r, copybuf, cursor);
+
+ /*
+ * If a backup target was specified, figuring out where to put
+ * the manifest is the server's problem. Otherwise, we need to
+ * deal with it.
+ */
+ if (backup_target == NULL)
+ {
+ /*
+ * If we're supposed inject the manifest into the archive,
+ * we prepare to buffer it in memory; otherwise, we
+ * prepare to write it to a temporary file.
+ */
+ if (state->manifest_inject_streamer != NULL)
+ state->manifest_buffer = createPQExpBuffer();
+ else
+ {
+ snprintf(state->manifest_filename,
+ sizeof(state->manifest_filename),
+ "%s/backup_manifest.tmp", basedir);
+ state->manifest_file =
+ fopen(state->manifest_filename, "wb");
+ if (state->manifest_file == NULL)
+ pg_fatal("could not create file \"%s\": %m",
+ state->manifest_filename);
+ }
+ }
+ break;
+ }
+
+ default:
+ ReportCopyDataParseError(r, copybuf);
+ break;
+ }
+}
+
+/*
+ * Get a single byte from a CopyData message.
+ *
+ * Bail out if none remain.
+ */
+static char
+GetCopyDataByte(size_t r, char *copybuf, size_t *cursor)
+{
+ if (*cursor >= r)
+ ReportCopyDataParseError(r, copybuf);
+
+ return copybuf[(*cursor)++];
+}
+
+/*
+ * Get a NUL-terminated string from a CopyData message.
+ *
+ * Bail out if the terminating NUL cannot be found.
+ */
+static char *
+GetCopyDataString(size_t r, char *copybuf, size_t *cursor)
+{
+ size_t startpos = *cursor;
+ size_t endpos = startpos;
+
+ while (1)
+ {
+ if (endpos >= r)
+ ReportCopyDataParseError(r, copybuf);
+ if (copybuf[endpos] == '\0')
+ break;
+ ++endpos;
+ }
+
+ *cursor = endpos + 1;
+ return &copybuf[startpos];
+}
+
+/*
+ * Get an unsigned 64-bit integer from a CopyData message.
+ *
+ * Bail out if there are not at least 8 bytes remaining.
+ */
+static uint64
+GetCopyDataUInt64(size_t r, char *copybuf, size_t *cursor)
+{
+ uint64 result;
+
+ if (*cursor + sizeof(uint64) > r)
+ ReportCopyDataParseError(r, copybuf);
+ memcpy(&result, &copybuf[*cursor], sizeof(uint64));
+ *cursor += sizeof(uint64);
+ return pg_ntoh64(result);
+}
+
+/*
+ * Bail out if we didn't parse the whole message.
+ */
+static void
+GetCopyDataEnd(size_t r, char *copybuf, size_t cursor)
+{
+ if (r != cursor)
+ ReportCopyDataParseError(r, copybuf);
+}
+
+/*
+ * Report failure to parse a CopyData message from the server. Then exit.
+ *
+ * As a debugging aid, we try to give some hint about what kind of message
+ * provoked the failure. Perhaps this is not detailed enough, but it's not
+ * clear that it's worth expending any more code on what should be a
+ * can't-happen case.
+ */
+static void
+ReportCopyDataParseError(size_t r, char *copybuf)
+{
+ if (r == 0)
+ pg_fatal("empty COPY message");
+ else
+ pg_fatal("malformed COPY message of type %d, length %zu",
+ copybuf[0], r);
+}
+
+/*
+ * Receive raw tar data from the server, and stream it to the appropriate
+ * location. If we're writing a single tarfile to standard output, also
+ * receive the backup manifest and inject it into that tarfile.
+ */
+static void
+ReceiveTarFile(PGconn *conn, char *archive_name, char *spclocation,
+ bool tablespacenum, pg_compress_specification *compress)
+{
+ WriteTarState state;
+ bbstreamer *manifest_inject_streamer;
+ bool is_recovery_guc_supported;
+ bool expect_unterminated_tarfile;
+
+ /* Pass all COPY data through to the backup streamer. */
+ memset(&state, 0, sizeof(state));
+ is_recovery_guc_supported =
+ PQserverVersion(conn) >= MINIMUM_VERSION_FOR_RECOVERY_GUC;
+ expect_unterminated_tarfile =
+ PQserverVersion(conn) < MINIMUM_VERSION_FOR_TERMINATED_TARFILE;
+ state.streamer = CreateBackupStreamer(archive_name, spclocation,
+ &manifest_inject_streamer,
+ is_recovery_guc_supported,
+ expect_unterminated_tarfile,
+ compress);
+ state.tablespacenum = tablespacenum;
+ ReceiveCopyData(conn, ReceiveTarCopyChunk, &state);
+ progress_update_filename(NULL);
+
+ /*
+ * The decision as to whether we need to inject the backup manifest into
+ * the output at this stage is made by CreateBackupStreamer; if that is
+ * needed, manifest_inject_streamer will be non-NULL; otherwise, it will
+ * be NULL.
+ */
+ if (manifest_inject_streamer != NULL)
+ {
+ PQExpBufferData buf;
+
+ /* 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. */
+ bbstreamer_inject_file(manifest_inject_streamer, "backup_manifest",
+ buf.data, buf.len);
+
+ /* Free memory. */
+ termPQExpBuffer(&buf);
+ }
+
+ /* Cleanup. */
+ bbstreamer_finalize(state.streamer);
+ bbstreamer_free(state.streamer);
+
+ progress_report(tablespacenum, true, false);
+
+ /*
+ * Do not sync the resulting tar file yet, all files are synced once at
+ * the end.
+ */
+}
+
+/*
+ * Receive one chunk of tar-format data from the server.
+ */
+static void
+ReceiveTarCopyChunk(size_t r, char *copybuf, void *callback_data)
+{
+ WriteTarState *state = callback_data;
+
+ bbstreamer_content(state->streamer, NULL, copybuf, r, BBSTREAMER_UNKNOWN);
+
+ totaldone += r;
+ progress_report(state->tablespacenum, false, false);
+}
+
+
+/*
+ * Retrieve tablespace path, either relocated or original depending on whether
+ * -T was passed or not.
+ */
+static const char *
+get_tablespace_mapping(const char *dir)
+{
+ TablespaceListCell *cell;
+ char canon_dir[MAXPGPATH];
+
+ /* Canonicalize path for comparison consistency */
+ strlcpy(canon_dir, dir, sizeof(canon_dir));
+ canonicalize_path(canon_dir);
+
+ for (cell = tablespace_dirs.head; cell; cell = cell->next)
+ if (strcmp(canon_dir, cell->old_dir) == 0)
+ return cell->new_dir;
+
+ return dir;
+}
+
+/*
+ * Receive the backup manifest file and write it out to a file.
+ */
+static void
+ReceiveBackupManifest(PGconn *conn)
+{
+ WriteManifestState state;
+
+ snprintf(state.filename, sizeof(state.filename),
+ "%s/backup_manifest.tmp", basedir);
+ state.file = fopen(state.filename, "wb");
+ if (state.file == NULL)
+ pg_fatal("could not create file \"%s\": %m", state.filename);
+
+ ReceiveCopyData(conn, ReceiveBackupManifestChunk, &state);
+
+ fclose(state.file);
+}
+
+/*
+ * Receive one chunk of the backup manifest file and write it out to a file.
+ */
+static void
+ReceiveBackupManifestChunk(size_t r, char *copybuf, void *callback_data)
+{
+ WriteManifestState *state = callback_data;
+
+ 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);
+ }
+}
+
+/*
+ * Receive the backup manifest file and write it out to a file.
+ */
+static void
+ReceiveBackupManifestInMemory(PGconn *conn, PQExpBuffer buf)
+{
+ ReceiveCopyData(conn, ReceiveBackupManifestInMemoryChunk, buf);
+}
+
+/*
+ * Receive one chunk of the backup manifest file and write it out to a file.
+ */
+static void
+ReceiveBackupManifestInMemoryChunk(size_t r, char *copybuf,
+ void *callback_data)
+{
+ PQExpBuffer buf = callback_data;
+
+ appendPQExpBuffer(buf, copybuf, r);
+}
+
+static void
+BaseBackup(char *compression_algorithm, char *compression_detail,
+ CompressionLocation compressloc, pg_compress_specification *client_compress)
+{
+ PGresult *res;
+ char *sysidentifier;
+ TimeLineID latesttli;
+ TimeLineID starttli;
+ char *basebkp;
+ int i;
+ char xlogstart[64];
+ char xlogend[64];
+ int minServerMajor,
+ maxServerMajor;
+ int serverVersion,
+ serverMajor;
+ int writing_to_stdout;
+ bool use_new_option_syntax = false;
+ PQExpBufferData buf;
+
+ Assert(conn != NULL);
+ initPQExpBuffer(&buf);
+
+ /*
+ * Check server version. BASE_BACKUP command was introduced in 9.1, so we
+ * can't work with servers older than 9.1.
+ */
+ minServerMajor = 901;
+ maxServerMajor = PG_VERSION_NUM / 100;
+ serverVersion = PQserverVersion(conn);
+ serverMajor = serverVersion / 100;
+ if (serverMajor < minServerMajor || serverMajor > maxServerMajor)
+ {
+ const char *serverver = PQparameterStatus(conn, "server_version");
+
+ pg_fatal("incompatible server version %s",
+ serverver ? serverver : "'unknown'");
+ }
+ if (serverMajor >= 1500)
+ use_new_option_syntax = true;
+
+ /*
+ * If WAL streaming was requested, also check that the server is new
+ * enough for that.
+ */
+ if (includewal == STREAM_WAL && !CheckServerVersionForStreaming(conn))
+ {
+ /*
+ * Error message already written in CheckServerVersionForStreaming(),
+ * but add a hint about using -X none.
+ */
+ pg_log_error_hint("Use -X none or -X fetch to disable log streaming.");
+ exit(1);
+ }
+
+ /*
+ * Build contents of configuration file if requested
+ */
+ if (writerecoveryconf)
+ recoveryconfcontents = GenerateRecoveryConfig(conn, replication_slot);
+
+ /*
+ * Run IDENTIFY_SYSTEM so we can get the timeline
+ */
+ if (!RunIdentifySystem(conn, &sysidentifier, &latesttli, NULL, NULL))
+ exit(1);
+
+ /*
+ * Start the actual backup
+ */
+ AppendStringCommandOption(&buf, use_new_option_syntax, "LABEL", label);
+ if (estimatesize)
+ AppendPlainCommandOption(&buf, use_new_option_syntax, "PROGRESS");
+ if (includewal == FETCH_WAL)
+ AppendPlainCommandOption(&buf, use_new_option_syntax, "WAL");
+ if (fastcheckpoint)
+ {
+ if (use_new_option_syntax)
+ AppendStringCommandOption(&buf, use_new_option_syntax,
+ "CHECKPOINT", "fast");
+ else
+ AppendPlainCommandOption(&buf, use_new_option_syntax, "FAST");
+ }
+ if (includewal != NO_WAL)
+ {
+ if (use_new_option_syntax)
+ AppendIntegerCommandOption(&buf, use_new_option_syntax, "WAIT", 0);
+ else
+ AppendPlainCommandOption(&buf, use_new_option_syntax, "NOWAIT");
+ }
+ if (maxrate > 0)
+ AppendIntegerCommandOption(&buf, use_new_option_syntax, "MAX_RATE",
+ maxrate);
+ if (format == 't')
+ AppendPlainCommandOption(&buf, use_new_option_syntax, "TABLESPACE_MAP");
+ if (!verify_checksums)
+ {
+ if (use_new_option_syntax)
+ AppendIntegerCommandOption(&buf, use_new_option_syntax,
+ "VERIFY_CHECKSUMS", 0);
+ else
+ AppendPlainCommandOption(&buf, use_new_option_syntax,
+ "NOVERIFY_CHECKSUMS");
+ }
+
+ if (manifest)
+ {
+ AppendStringCommandOption(&buf, use_new_option_syntax, "MANIFEST",
+ manifest_force_encode ? "force-encode" : "yes");
+ if (manifest_checksums != NULL)
+ AppendStringCommandOption(&buf, use_new_option_syntax,
+ "MANIFEST_CHECKSUMS", manifest_checksums);
+ }
+
+ if (backup_target != NULL)
+ {
+ char *colon;
+
+ if (serverMajor < 1500)
+ pg_fatal("backup targets are not supported by this server version");
+
+ if (writerecoveryconf)
+ pg_fatal("recovery configuration cannot be written when a backup target is used");
+
+ AppendPlainCommandOption(&buf, use_new_option_syntax, "TABLESPACE_MAP");
+
+ if ((colon = strchr(backup_target, ':')) == NULL)
+ {
+ AppendStringCommandOption(&buf, use_new_option_syntax,
+ "TARGET", backup_target);
+ }
+ else
+ {
+ char *target;
+
+ target = pnstrdup(backup_target, colon - backup_target);
+ AppendStringCommandOption(&buf, use_new_option_syntax,
+ "TARGET", target);
+ AppendStringCommandOption(&buf, use_new_option_syntax,
+ "TARGET_DETAIL", colon + 1);
+ }
+ }
+ else if (serverMajor >= 1500)
+ AppendStringCommandOption(&buf, use_new_option_syntax,
+ "TARGET", "client");
+
+ 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");
+ }
+
+ if (use_new_option_syntax && buf.len > 0)
+ basebkp = psprintf("BASE_BACKUP (%s)", buf.data);
+ else
+ basebkp = psprintf("BASE_BACKUP %s", buf.data);
+
+ if (PQsendQuery(conn, basebkp) == 0)
+ pg_fatal("could not send replication command \"%s\": %s",
+ "BASE_BACKUP", PQerrorMessage(conn));
+
+ /*
+ * Get the starting WAL location
+ */
+ 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);
+
+ strlcpy(xlogstart, PQgetvalue(res, 0, 0), sizeof(xlogstart));
+
+ if (verbose)
+ pg_log_info("checkpoint completed");
+
+ /*
+ * 9.3 and later sends the TLI of the starting point. With older servers,
+ * assume it's the same as the latest timeline reported by
+ * IDENTIFY_SYSTEM.
+ */
+ if (PQnfields(res) >= 2)
+ starttli = atoi(PQgetvalue(res, 0, 1));
+ else
+ starttli = latesttli;
+ PQclear(res);
+ MemSet(xlogend, 0, sizeof(xlogend));
+
+ if (verbose && includewal != NO_WAL)
+ pg_log_info("write-ahead log start point: %s on timeline %u",
+ xlogstart, starttli);
+
+ /*
+ * Get the header
+ */
+ 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");
+
+ /*
+ * Sum up the total size, for progress reporting
+ */
+ totalsize_kb = totaldone = 0;
+ tablespacecount = PQntuples(res);
+ for (i = 0; i < PQntuples(res); i++)
+ {
+ totalsize_kb += atol(PQgetvalue(res, i, 2));
+
+ /*
+ * Verify tablespace directories are empty. Don't bother with the
+ * first once since it can be relocated, and it will be checked before
+ * we do anything anyway.
+ *
+ * Note that this is skipped for tar format backups and backups that
+ * the server is storing to a target location, since in that case we
+ * won't be storing anything into these directories and thus should
+ * not create them.
+ */
+ if (backup_target == NULL && format == 'p' && !PQgetisnull(res, i, 1))
+ {
+ char *path = unconstify(char *, get_tablespace_mapping(PQgetvalue(res, i, 1)));
+
+ verify_dir_is_empty_or_create(path, &made_tablespace_dirs, &found_tablespace_dirs);
+ }
+ }
+
+ /*
+ * When writing to stdout, require a single tablespace
+ */
+ writing_to_stdout = format == 't' && basedir != NULL &&
+ strcmp(basedir, "-") == 0;
+ if (writing_to_stdout && PQntuples(res) > 1)
+ pg_fatal("can only write single tablespace to stdout, database has %d",
+ PQntuples(res));
+
+ /*
+ * If we're streaming WAL, start the streaming session before we start
+ * receiving the actual data chunks.
+ */
+ if (includewal == STREAM_WAL)
+ {
+ pg_compress_algorithm wal_compress_algorithm;
+ int wal_compress_level;
+
+ if (verbose)
+ pg_log_info("starting background WAL receiver");
+
+ if (client_compress->algorithm == PG_COMPRESSION_GZIP)
+ {
+ wal_compress_algorithm = PG_COMPRESSION_GZIP;
+ wal_compress_level = client_compress->level;
+ }
+ else
+ {
+ wal_compress_algorithm = PG_COMPRESSION_NONE;
+ wal_compress_level = 0;
+ }
+
+ StartLogStreamer(xlogstart, starttli, sysidentifier,
+ wal_compress_algorithm,
+ wal_compress_level);
+ }
+
+ 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;
+
+ /*
+ * If we write the data out to a tar file, it will be named
+ * base.tar if it's the main data directory or <tablespaceoid>.tar
+ * if it's for another tablespace. CreateBackupStreamer() will
+ * arrange to add .gz to the archive name if pg_basebackup is
+ * performing compression.
+ */
+ 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);
+ }
+
+ /*
+ * Now receive backup manifest, if appropriate.
+ *
+ * If we're writing a tarfile to stdout, ReceiveTarFile will have
+ * already processed the backup manifest and included it in the output
+ * tarfile. Such a configuration doesn't allow for writing multiple
+ * files.
+ *
+ * If we're talking to an older server, it won't send a backup
+ * manifest, so don't try to receive one.
+ */
+ if (!writing_to_stdout && manifest)
+ ReceiveBackupManifest(conn);
+ }
+
+ if (showprogress)
+ {
+ progress_update_filename(NULL);
+ progress_report(PQntuples(res), true, true);
+ }
+
+ PQclear(res);
+
+ /*
+ * Get the stop position
+ */
+ 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)
+ {
+ const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
+
+ if (sqlstate &&
+ strcmp(sqlstate, ERRCODE_DATA_CORRUPTED) == 0)
+ {
+ pg_log_error("checksum error occurred");
+ checksum_failure = true;
+ }
+ else
+ {
+ pg_log_error("final receive failed: %s",
+ PQerrorMessage(conn));
+ }
+ exit(1);
+ }
+
+ if (bgchild > 0)
+ {
+#ifndef WIN32
+ int status;
+ pid_t r;
+#else
+ DWORD status;
+
+ /*
+ * get a pointer sized version of bgchild to avoid warnings about
+ * casting to a different size on WIN64.
+ */
+ intptr_t bgchild_handle = bgchild;
+ uint32 hi,
+ lo;
+#endif
+
+ 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 */
+
+ /*
+ * On Windows, since we are in the same process, we can just store the
+ * value directly in the variable, and then set the flag that says
+ * it's there.
+ */
+ if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2)
+ pg_fatal("could not parse write-ahead log location \"%s\"",
+ xlogend);
+ xlogendptr = ((uint64) hi) << 32 | lo;
+ InterlockedIncrement(&has_xlogendptr);
+
+ /* First wait for the thread to exit */
+ if (WaitForSingleObjectEx((HANDLE) bgchild_handle, INFINITE, FALSE) !=
+ WAIT_OBJECT_0)
+ {
+ _dosmaperr(GetLastError());
+ pg_fatal("could not wait for child thread: %m");
+ }
+ if (GetExitCodeThread((HANDLE) bgchild_handle, &status) == 0)
+ {
+ _dosmaperr(GetLastError());
+ pg_fatal("could not get child thread exit status: %m");
+ }
+ if (status != 0)
+ pg_fatal("child thread exited with error %u",
+ (unsigned int) status);
+ /* Exited normally, we're happy */
+#endif
+ }
+
+ /* Free the configuration file contents */
+ destroyPQExpBuffer(recoveryconfcontents);
+
+ /*
+ * End of copy data. Final result is already checked inside the loop.
+ */
+ PQclear(res);
+ PQfinish(conn);
+ conn = NULL;
+
+ /*
+ * Make data persistent on disk once backup is completed. For tar format
+ * sync the parent directory and all its contents as each tar file was not
+ * synced after being completed. In plain format, all the data of the
+ * base directory is synced, taking into account all the tablespaces.
+ * Errors are not considered fatal.
+ *
+ * If, however, there's a backup target, we're not writing anything
+ * locally, so in that case we skip this step.
+ */
+ if (do_sync && backup_target == NULL)
+ {
+ if (verbose)
+ pg_log_info("syncing data to disk ...");
+ if (format == 't')
+ {
+ if (strcmp(basedir, "-") != 0)
+ (void) fsync_dir_recurse(basedir);
+ }
+ else
+ {
+ (void) fsync_pgdata(basedir, serverVersion);
+ }
+ }
+
+ /*
+ * After synchronizing data to disk, perform a durable rename of
+ * backup_manifest.tmp to backup_manifest, if we wrote such a file. This
+ * way, a failure or system crash before we reach this point will leave us
+ * without a backup_manifest file, decreasing the chances that a directory
+ * we leave behind will be mistaken for a valid backup.
+ */
+ if (!writing_to_stdout && manifest && backup_target == NULL)
+ {
+ char tmp_filename[MAXPGPATH];
+ char filename[MAXPGPATH];
+
+ if (verbose)
+ pg_log_info("renaming backup_manifest.tmp to backup_manifest");
+
+ snprintf(tmp_filename, MAXPGPATH, "%s/backup_manifest.tmp", basedir);
+ snprintf(filename, MAXPGPATH, "%s/backup_manifest", basedir);
+
+ 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");
+}
+
+
+int
+main(int argc, char **argv)
+{
+ static struct option long_options[] = {
+ {"help", no_argument, NULL, '?'},
+ {"version", no_argument, NULL, 'V'},
+ {"pgdata", required_argument, NULL, 'D'},
+ {"format", required_argument, NULL, 'F'},
+ {"checkpoint", required_argument, NULL, 'c'},
+ {"create-slot", no_argument, NULL, 'C'},
+ {"max-rate", required_argument, NULL, 'r'},
+ {"write-recovery-conf", no_argument, NULL, 'R'},
+ {"slot", required_argument, NULL, 'S'},
+ {"target", required_argument, NULL, 't'},
+ {"tablespace-mapping", required_argument, NULL, 'T'},
+ {"wal-method", required_argument, NULL, 'X'},
+ {"gzip", no_argument, NULL, 'z'},
+ {"compress", required_argument, NULL, 'Z'},
+ {"label", required_argument, NULL, 'l'},
+ {"no-clean", no_argument, NULL, 'n'},
+ {"no-sync", no_argument, NULL, 'N'},
+ {"dbname", required_argument, NULL, 'd'},
+ {"host", required_argument, NULL, 'h'},
+ {"port", required_argument, NULL, 'p'},
+ {"username", required_argument, NULL, 'U'},
+ {"no-password", no_argument, NULL, 'w'},
+ {"password", no_argument, NULL, 'W'},
+ {"status-interval", required_argument, NULL, 's'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"progress", no_argument, NULL, 'P'},
+ {"waldir", required_argument, NULL, 1},
+ {"no-slot", no_argument, NULL, 2},
+ {"no-verify-checksums", no_argument, NULL, 3},
+ {"no-estimate-size", no_argument, NULL, 4},
+ {"no-manifest", no_argument, NULL, 5},
+ {"manifest-force-encode", no_argument, NULL, 6},
+ {"manifest-checksums", required_argument, NULL, 7},
+ {NULL, 0, NULL, 0}
+ };
+ int c;
+
+ int option_index;
+ char *compression_algorithm = "none";
+ char *compression_detail = NULL;
+ CompressionLocation compressloc = COMPRESS_LOCATION_UNSPECIFIED;
+ pg_compress_specification client_compress;
+
+ pg_logging_init(argv[0]);
+ progname = get_progname(argv[0]);
+ set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ usage();
+ exit(0);
+ }
+ else if (strcmp(argv[1], "-V") == 0
+ || strcmp(argv[1], "--version") == 0)
+ {
+ puts("pg_basebackup (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
+
+ atexit(cleanup_directories_atexit);
+
+ while ((c = getopt_long(argc, argv, "CD:F:r:RS:t:T:X:l:nNzZ:d:c:h:p:U:s:wWkvP",
+ long_options, &option_index)) != -1)
+ {
+ switch (c)
+ {
+ case 'C':
+ create_slot = true;
+ break;
+ case 'D':
+ basedir = pg_strdup(optarg);
+ break;
+ case 'F':
+ if (strcmp(optarg, "p") == 0 || strcmp(optarg, "plain") == 0)
+ format = 'p';
+ else if (strcmp(optarg, "t") == 0 || strcmp(optarg, "tar") == 0)
+ format = 't';
+ else
+ pg_fatal("invalid output format \"%s\", must be \"plain\" or \"tar\"",
+ optarg);
+ break;
+ case 'r':
+ maxrate = parse_max_rate(optarg);
+ break;
+ case 'R':
+ writerecoveryconf = true;
+ break;
+ case 'S':
+
+ /*
+ * When specifying replication slot name, use a permanent
+ * slot.
+ */
+ replication_slot = pg_strdup(optarg);
+ temp_replication_slot = false;
+ break;
+ case 2:
+ no_slot = true;
+ break;
+ case 't':
+ backup_target = pg_strdup(optarg);
+ break;
+ case 'T':
+ tablespace_list_append(optarg);
+ break;
+ case 'X':
+ if (strcmp(optarg, "n") == 0 ||
+ strcmp(optarg, "none") == 0)
+ {
+ includewal = NO_WAL;
+ }
+ else if (strcmp(optarg, "f") == 0 ||
+ strcmp(optarg, "fetch") == 0)
+ {
+ includewal = FETCH_WAL;
+ }
+ else if (strcmp(optarg, "s") == 0 ||
+ strcmp(optarg, "stream") == 0)
+ {
+ includewal = STREAM_WAL;
+ }
+ else
+ pg_fatal("invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\"",
+ optarg);
+ break;
+ case 1:
+ xlog_dir = pg_strdup(optarg);
+ break;
+ case 'l':
+ label = pg_strdup(optarg);
+ break;
+ case 'n':
+ noclean = true;
+ break;
+ case 'N':
+ do_sync = false;
+ break;
+ case 'z':
+ compression_algorithm = "gzip";
+ compression_detail = NULL;
+ compressloc = COMPRESS_LOCATION_UNSPECIFIED;
+ break;
+ case 'Z':
+ parse_compress_options(optarg, &compression_algorithm,
+ &compression_detail, &compressloc);
+ break;
+ case 'c':
+ if (pg_strcasecmp(optarg, "fast") == 0)
+ fastcheckpoint = true;
+ else if (pg_strcasecmp(optarg, "spread") == 0)
+ fastcheckpoint = false;
+ else
+ pg_fatal("invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\"",
+ optarg);
+ break;
+ case 'd':
+ connection_string = pg_strdup(optarg);
+ break;
+ case 'h':
+ dbhost = pg_strdup(optarg);
+ break;
+ case 'p':
+ dbport = pg_strdup(optarg);
+ break;
+ case 'U':
+ dbuser = pg_strdup(optarg);
+ break;
+ case 'w':
+ dbgetpassword = -1;
+ break;
+ case 'W':
+ dbgetpassword = 1;
+ break;
+ case 's':
+ if (!option_parse_int(optarg, "-s/--status-interval", 0,
+ INT_MAX / 1000,
+ &standby_message_timeout))
+ exit(1);
+ standby_message_timeout *= 1000;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'P':
+ showprogress = true;
+ break;
+ case 3:
+ verify_checksums = false;
+ break;
+ case 4:
+ estimatesize = false;
+ break;
+ case 5:
+ manifest = false;
+ break;
+ case 6:
+ manifest_force_encode = true;
+ break;
+ case 7:
+ manifest_checksums = pg_strdup(optarg);
+ break;
+ default:
+ /* getopt_long already emitted a complaint */
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+ }
+
+ /*
+ * Any non-option arguments?
+ */
+ 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);
+ }
+
+ /*
+ * Setting the backup target to 'client' is equivalent to leaving out the
+ * option. This logic allows us to assume elsewhere that the backup is
+ * being stored locally if and only if backup_target == NULL.
+ */
+ if (backup_target != NULL && strcmp(backup_target, "client") == 0)
+ {
+ pg_free(backup_target);
+ backup_target = NULL;
+ }
+
+ /*
+ * Can't use --format with --target. Without --target, default format is
+ * 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';
+
+ /*
+ * Either directory or backup target should be specified, but not both
+ */
+ 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);
+ }
+
+ /*
+ * If the user has not specified where to perform backup compression,
+ * default to the client, unless the user specified --target, in which
+ * case the server is the only choice.
+ */
+ if (compressloc == COMPRESS_LOCATION_UNSPECIFIED)
+ {
+ if (backup_target == NULL)
+ compressloc = COMPRESS_LOCATION_CLIENT;
+ else
+ compressloc = COMPRESS_LOCATION_SERVER;
+ }
+
+ /*
+ * If any compression that we're doing is happening on the client side, we
+ * must try to parse the compression algorithm and detail, but if it's all
+ * on the server side, then we're just going to pass through whatever was
+ * requested and let the server decide what to do.
+ */
+ if (compressloc == COMPRESS_LOCATION_CLIENT)
+ {
+ pg_compress_algorithm alg;
+ char *error_detail;
+
+ if (!parse_compress_algorithm(compression_algorithm, &alg))
+ pg_fatal("unrecognized compression algorithm: \"%s\"",
+ compression_algorithm);
+
+ parse_compress_specification(alg, compression_detail, &client_compress);
+ error_detail = validate_compress_specification(&client_compress);
+ if (error_detail != NULL)
+ pg_fatal("invalid compression specification: %s",
+ error_detail);
+ }
+ else
+ {
+ Assert(compressloc == COMPRESS_LOCATION_SERVER);
+ client_compress.algorithm = PG_COMPRESSION_NONE;
+ client_compress.options = 0;
+ }
+
+ /*
+ * Can't perform client-side compression if the backup is not being sent
+ * to the client.
+ */
+ 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-side compression doesn't make sense unless tar format is in use.
+ */
+ 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);
+ }
+
+ /*
+ * Sanity checks for WAL method.
+ */
+ 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);
+ }
+
+ /*
+ * Sanity checks for replication slot options.
+ */
+ 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);
+ }
+ }
+
+ /*
+ * Sanity checks on WAL directory.
+ */
+ 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);
+ }
+ }
+
+ /*
+ * Sanity checks for progress reporting options.
+ */
+ 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);
+ }
+
+ /*
+ * Sanity checks for backup manifest options.
+ */
+ 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);
+
+#ifndef WIN32
+
+ /*
+ * Trap SIGCHLD to be able to handle the WAL stream process exiting. There
+ * is no SIGCHLD on Windows, there we rely on the background thread
+ * setting the signal variable on unexpected but graceful exit. If the WAL
+ * stream thread crashes on Windows it will bring down the entire process
+ * as it's a thread, so there is nothing to catch should that happen. A
+ * crash on UNIX will be caught by the signal handler.
+ */
+ pqsignal(SIGCHLD, sigchld_handler);
+#endif
+
+ /*
+ * Set umask so that directories/files are created with the same
+ * permissions as directories/files in the source data directory.
+ *
+ * pg_mode_mask is set to owner-only by default and then updated in
+ * GetConnection() where we get the mode from the server-side with
+ * RetrieveDataDirCreatePerm() and then call SetDataDirectoryCreatePerm().
+ */
+ umask(pg_mode_mask);
+
+ /* Backup manifests are supported in 13 and newer versions */
+ if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_MANIFESTS)
+ manifest = false;
+
+ /*
+ * If an output directory was specified, verify that it exists, or create
+ * it. Note that for a tar backup, an output directory of "-" means we are
+ * writing to stdout, so do nothing in that case.
+ */
+ if (basedir != NULL && (format == 'p' || strcmp(basedir, "-") != 0))
+ verify_dir_is_empty_or_create(basedir, &made_new_pgdata, &found_existing_pgdata);
+
+ /* determine remote server's xlog segment size */
+ if (!RetrieveWalSegSize(conn))
+ exit(1);
+
+ /* Create pg_wal symlink, if required */
+ if (xlog_dir)
+ {
+ char *linkloc;
+
+ verify_dir_is_empty_or_create(xlog_dir, &made_new_xlogdir, &found_existing_xlogdir);
+
+ /*
+ * Form name of the place where the symlink must go. pg_xlog has been
+ * renamed to pg_wal in post-10 clusters.
+ */
+ linkloc = psprintf("%s/%s", basedir,
+ PQserverVersion(conn) < MINIMUM_VERSION_FOR_PG_WAL ?
+ "pg_xlog" : "pg_wal");
+
+#ifdef HAVE_SYMLINK
+ if (symlink(xlog_dir, linkloc) != 0)
+ pg_fatal("could not create symbolic link \"%s\": %m", linkloc);
+#else
+ pg_fatal("symlinks are not supported on this platform");
+#endif
+ free(linkloc);
+ }
+
+ BaseBackup(compression_algorithm, compression_detail, compressloc,
+ &client_compress);
+
+ success = true;
+ return 0;
+}
diff --git a/src/bin/pg_basebackup/pg_receivewal.c b/src/bin/pg_basebackup/pg_receivewal.c
new file mode 100644
index 0000000..26dcf33
--- /dev/null
+++ b/src/bin/pg_basebackup/pg_receivewal.c
@@ -0,0 +1,992 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_receivewal.c - receive streaming WAL data and write it
+ * to a local file.
+ *
+ * Author: Magnus Hagander <magnus@hagander.net>
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/pg_receivewal.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <dirent.h>
+#include <limits.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifdef USE_LZ4
+#include <lz4frame.h>
+#endif
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "access/xlog_internal.h"
+#include "common/file_perm.h"
+#include "common/logging.h"
+#include "fe_utils/option_utils.h"
+#include "getopt_long.h"
+#include "libpq-fe.h"
+#include "receivelog.h"
+#include "streamutil.h"
+
+/* Time to sleep between reconnection attempts */
+#define RECONNECT_SLEEP_TIME 5
+
+/* Global options */
+static char *basedir = NULL;
+static int verbose = 0;
+static int compresslevel = 0;
+static int noloop = 0;
+static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
+static volatile bool time_to_stop = false;
+static bool do_create_slot = false;
+static bool slot_exists_ok = false;
+static bool do_drop_slot = false;
+static bool do_sync = true;
+static bool synchronous = false;
+static char *replication_slot = NULL;
+static pg_compress_algorithm compression_algorithm = PG_COMPRESSION_NONE;
+static XLogRecPtr endpos = InvalidXLogRecPtr;
+
+
+static void usage(void);
+static void parse_compress_options(char *option, char **algorithm,
+ char **detail);
+static DIR *get_destination_dir(char *dest_folder);
+static void close_destination_dir(DIR *dest_dir, char *dest_folder);
+static XLogRecPtr FindStreamingStart(uint32 *tli);
+static void StreamLog(void);
+static bool stop_streaming(XLogRecPtr segendpos, uint32 timeline,
+ bool segment_finished);
+
+static void
+disconnect_atexit(void)
+{
+ if (conn != NULL)
+ PQfinish(conn);
+}
+
+static void
+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);
+}
+
+/*
+ * Basic parsing of a value specified for -Z/--compress
+ *
+ * The parsing consists of a METHOD:DETAIL string fed later on to a more
+ * advanced routine in charge of proper validation checks. This only extracts
+ * METHOD and DETAIL. If only an integer is found, the method is implied by
+ * the value specified.
+ */
+static void
+parse_compress_options(char *option, char **algorithm, char **detail)
+{
+ char *sep;
+ char *endp;
+ long result;
+
+ /*
+ * Check whether the compression specification consists of a bare integer.
+ *
+ * For backward-compatibility, assume "none" if the integer found is zero
+ * and "gzip" otherwise.
+ */
+ result = strtol(option, &endp, 10);
+ if (*endp == '\0')
+ {
+ if (result == 0)
+ {
+ *algorithm = pstrdup("none");
+ *detail = NULL;
+ }
+ else
+ {
+ *algorithm = pstrdup("gzip");
+ *detail = pstrdup(option);
+ }
+ return;
+ }
+
+ /*
+ * Check whether there is a compression detail following the algorithm
+ * name.
+ */
+ sep = strchr(option, ':');
+ if (sep == NULL)
+ {
+ *algorithm = pstrdup(option);
+ *detail = NULL;
+ }
+ else
+ {
+ char *alg;
+
+ alg = palloc((sep - option) + 1);
+ memcpy(alg, option, sep - option);
+ alg[sep - option] = '\0';
+
+ *algorithm = alg;
+ *detail = pstrdup(sep + 1);
+ }
+}
+
+/*
+ * Check if the filename looks like a WAL file, letting caller know if this
+ * WAL segment is partial and/or compressed.
+ */
+static bool
+is_xlogfilename(const char *filename, bool *ispartial,
+ pg_compress_algorithm *wal_compression_algorithm)
+{
+ size_t fname_len = strlen(filename);
+ size_t xlog_pattern_len = strspn(filename, "0123456789ABCDEF");
+
+ /* File does not look like a WAL file */
+ if (xlog_pattern_len != XLOG_FNAME_LEN)
+ return false;
+
+ /* File looks like a completed uncompressed WAL file */
+ if (fname_len == XLOG_FNAME_LEN)
+ {
+ *ispartial = false;
+ *wal_compression_algorithm = PG_COMPRESSION_NONE;
+ return true;
+ }
+
+ /* File looks like a completed gzip-compressed WAL file */
+ if (fname_len == XLOG_FNAME_LEN + strlen(".gz") &&
+ strcmp(filename + XLOG_FNAME_LEN, ".gz") == 0)
+ {
+ *ispartial = false;
+ *wal_compression_algorithm = PG_COMPRESSION_GZIP;
+ return true;
+ }
+
+ /* File looks like a completed LZ4-compressed WAL file */
+ if (fname_len == XLOG_FNAME_LEN + strlen(".lz4") &&
+ strcmp(filename + XLOG_FNAME_LEN, ".lz4") == 0)
+ {
+ *ispartial = false;
+ *wal_compression_algorithm = PG_COMPRESSION_LZ4;
+ return true;
+ }
+
+ /* File looks like a partial uncompressed WAL file */
+ if (fname_len == XLOG_FNAME_LEN + strlen(".partial") &&
+ strcmp(filename + XLOG_FNAME_LEN, ".partial") == 0)
+ {
+ *ispartial = true;
+ *wal_compression_algorithm = PG_COMPRESSION_NONE;
+ return true;
+ }
+
+ /* File looks like a partial gzip-compressed WAL file */
+ if (fname_len == XLOG_FNAME_LEN + strlen(".gz.partial") &&
+ strcmp(filename + XLOG_FNAME_LEN, ".gz.partial") == 0)
+ {
+ *ispartial = true;
+ *wal_compression_algorithm = PG_COMPRESSION_GZIP;
+ return true;
+ }
+
+ /* File looks like a partial LZ4-compressed WAL file */
+ if (fname_len == XLOG_FNAME_LEN + strlen(".lz4.partial") &&
+ strcmp(filename + XLOG_FNAME_LEN, ".lz4.partial") == 0)
+ {
+ *ispartial = true;
+ *wal_compression_algorithm = PG_COMPRESSION_LZ4;
+ return true;
+ }
+
+ /* File does not look like something we know */
+ return false;
+}
+
+static bool
+stop_streaming(XLogRecPtr xlogpos, uint32 timeline, bool segment_finished)
+{
+ static uint32 prevtimeline = 0;
+ static XLogRecPtr prevpos = InvalidXLogRecPtr;
+
+ /* 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;
+ return true;
+ }
+
+ /*
+ * Note that we report the previous, not current, position here. After a
+ * timeline switch, xlogpos points to the beginning of the segment because
+ * that's where we always begin streaming. Reporting the end of previous
+ * timeline isn't totally accurate, because the next timeline can begin
+ * slightly before the end of the WAL that we received on the previous
+ * timeline, but it's close enough for reporting purposes.
+ */
+ 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");
+ return true;
+ }
+ return false;
+}
+
+
+/*
+ * Get destination directory.
+ */
+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;
+}
+
+
+/*
+ * Close existing directory.
+ */
+static void
+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);
+}
+
+
+/*
+ * Determine starting location for streaming, based on any existing xlog
+ * segments in the directory. We start at the end of the last one that is
+ * complete (size matches wal segment size), on the timeline with highest ID.
+ *
+ * If there are no WAL files in the directory, returns InvalidXLogRecPtr.
+ */
+static XLogRecPtr
+FindStreamingStart(uint32 *tli)
+{
+ DIR *dir;
+ struct dirent *dirent;
+ XLogSegNo high_segno = 0;
+ uint32 high_tli = 0;
+ bool high_ispartial = false;
+
+ dir = get_destination_dir(basedir);
+
+ while (errno = 0, (dirent = readdir(dir)) != NULL)
+ {
+ uint32 tli;
+ XLogSegNo segno;
+ pg_compress_algorithm wal_compression_algorithm;
+ bool ispartial;
+
+ if (!is_xlogfilename(dirent->d_name,
+ &ispartial, &wal_compression_algorithm))
+ continue;
+
+ /*
+ * Looks like an xlog file. Parse its position.
+ */
+ XLogFromFileName(dirent->d_name, &tli, &segno, WalSegSz);
+
+ /*
+ * Check that the segment has the right size, if it's supposed to be
+ * completed. For non-compressed segments just check the on-disk size
+ * and see if it matches a completed segment. For gzip-compressed
+ * segments, look at the last 4 bytes of the compressed file, which is
+ * where the uncompressed size is located for files with a size lower
+ * than 4GB, and then compare it to the size of a completed segment.
+ * The 4 last bytes correspond to the ISIZE member according to
+ * http://www.zlib.org/rfc-gzip.html.
+ *
+ * For LZ4-compressed segments, uncompress the file in a throw-away
+ * buffer keeping track of the uncompressed size, then compare it to
+ * the size of a completed segment. Per its protocol, LZ4 does not
+ * store the uncompressed size of an object by default. contentSize
+ * is one possible way to do that, but we need to rely on a method
+ * where WAL segments could have been compressed by a different source
+ * than pg_receivewal, like an archive_command with lz4.
+ */
+ if (!ispartial && wal_compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ struct stat statbuf;
+ char fullpath[MAXPGPATH * 2];
+
+ snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name);
+ if (stat(fullpath, &statbuf) != 0)
+ pg_fatal("could not stat file \"%s\": %m", fullpath);
+
+ if (statbuf.st_size != WalSegSz)
+ {
+ pg_log_warning("segment file \"%s\" has incorrect size %lld, skipping",
+ dirent->d_name, (long long int) statbuf.st_size);
+ continue;
+ }
+ }
+ else if (!ispartial && wal_compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ int fd;
+ char buf[4];
+ int bytes_out;
+ char fullpath[MAXPGPATH * 2];
+ int r;
+
+ snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name);
+
+ fd = open(fullpath, O_RDONLY | PG_BINARY, 0);
+ if (fd < 0)
+ pg_fatal("could not open compressed file \"%s\": %m",
+ fullpath);
+ if (lseek(fd, (off_t) (-4), SEEK_END) < 0)
+ pg_fatal("could not seek in compressed file \"%s\": %m",
+ fullpath);
+ r = read(fd, (char *) buf, sizeof(buf));
+ if (r != sizeof(buf))
+ {
+ if (r < 0)
+ pg_fatal("could not read compressed file \"%s\": %m",
+ fullpath);
+ else
+ pg_fatal("could not read compressed file \"%s\": read %d of %zu",
+ fullpath, r, sizeof(buf));
+ }
+
+ close(fd);
+ bytes_out = (buf[3] << 24) | (buf[2] << 16) |
+ (buf[1] << 8) | buf[0];
+
+ if (bytes_out != WalSegSz)
+ {
+ pg_log_warning("compressed segment file \"%s\" has incorrect uncompressed size %d, skipping",
+ dirent->d_name, bytes_out);
+ continue;
+ }
+ }
+ else if (!ispartial && wal_compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+#ifdef USE_LZ4
+#define LZ4_CHUNK_SZ 64 * 1024 /* 64kB as maximum chunk size read */
+ int fd;
+ ssize_t r;
+ size_t uncompressed_size = 0;
+ char fullpath[MAXPGPATH * 2];
+ char *outbuf;
+ char *readbuf;
+ LZ4F_decompressionContext_t ctx = NULL;
+ LZ4F_decompressOptions_t dec_opt;
+ LZ4F_errorCode_t status;
+
+ memset(&dec_opt, 0, sizeof(dec_opt));
+ snprintf(fullpath, sizeof(fullpath), "%s/%s", basedir, dirent->d_name);
+
+ 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));
+
+ outbuf = pg_malloc0(LZ4_CHUNK_SZ);
+ readbuf = pg_malloc0(LZ4_CHUNK_SZ);
+ do
+ {
+ char *readp;
+ char *readend;
+
+ r = read(fd, readbuf, LZ4_CHUNK_SZ);
+ if (r < 0)
+ pg_fatal("could not read file \"%s\": %m", fullpath);
+
+ /* Done reading the file */
+ if (r == 0)
+ break;
+
+ /* Process one chunk */
+ readp = readbuf;
+ readend = readbuf + r;
+ while (readp < readend)
+ {
+ size_t out_size = LZ4_CHUNK_SZ;
+ size_t read_size = readend - readp;
+
+ memset(outbuf, 0, LZ4_CHUNK_SZ);
+ status = LZ4F_decompress(ctx, outbuf, &out_size,
+ readp, &read_size, &dec_opt);
+ if (LZ4F_isError(status))
+ pg_fatal("could not decompress file \"%s\": %s",
+ fullpath,
+ LZ4F_getErrorName(status));
+
+ readp += read_size;
+ uncompressed_size += out_size;
+ }
+
+ /*
+ * No need to continue reading the file when the
+ * uncompressed_size exceeds WalSegSz, even if there are still
+ * data left to read. However, if uncompressed_size is equal
+ * to WalSegSz, it should verify that there is no more data to
+ * 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;
+
+ /*
+ * Move the starting pointer to the start of the next segment, if the
+ * highest one we saw was completed. Otherwise start streaming from
+ * the beginning of the .partial segment.
+ */
+ if (!high_ispartial)
+ high_segno++;
+
+ XLogSegNoOffsetToRecPtr(high_segno, 0, WalSegSz, high_ptr);
+
+ *tli = high_tli;
+ return high_ptr;
+ }
+ else
+ return InvalidXLogRecPtr;
+}
+
+/*
+ * Start the log streaming
+ */
+static void
+StreamLog(void)
+{
+ XLogRecPtr serverpos;
+ TimeLineID servertli;
+ StreamCtl stream;
+ char *sysidentifier;
+
+ MemSet(&stream, 0, sizeof(stream));
+
+ /*
+ * Connect in replication mode to the server
+ */
+ if (conn == NULL)
+ conn = GetConnection();
+ if (!conn)
+ /* Error message already written in GetConnection() */
+ return;
+
+ if (!CheckServerVersionForStreaming(conn))
+ {
+ /*
+ * Error message already written in CheckServerVersionForStreaming().
+ * There's no hope of recovering from a version mismatch, so don't
+ * retry.
+ */
+ exit(1);
+ }
+
+ /*
+ * Identify server, obtaining start LSN position and current timeline ID
+ * at the same time, necessary if not valid data can be found in the
+ * existing output directory.
+ */
+ if (!RunIdentifySystem(conn, &sysidentifier, &servertli, &serverpos, NULL))
+ exit(1);
+
+ /*
+ * Figure out where to start streaming. First scan the local directory.
+ */
+ stream.startpos = FindStreamingStart(&stream.timeline);
+ if (stream.startpos == InvalidXLogRecPtr)
+ {
+ /*
+ * Try to get the starting point from the slot if any. This is
+ * supported in PostgreSQL 15 and newer.
+ */
+ if (replication_slot != NULL &&
+ PQserverVersion(conn) >= 150000)
+ {
+ if (!GetSlotInformation(conn, replication_slot, &stream.startpos,
+ &stream.timeline))
+ {
+ /* Error is logged by GetSlotInformation() */
+ return;
+ }
+ }
+
+ /*
+ * If it the starting point is still not known, use the current WAL
+ * flush value as last resort.
+ */
+ if (stream.startpos == InvalidXLogRecPtr)
+ {
+ stream.startpos = serverpos;
+ stream.timeline = servertli;
+ }
+ }
+
+ Assert(stream.startpos != InvalidXLogRecPtr &&
+ stream.timeline != 0);
+
+ /*
+ * Always start streaming at the beginning of a segment
+ */
+ stream.startpos -= XLogSegmentOffset(stream.startpos, WalSegSz);
+
+ /*
+ * Start the replication
+ */
+ if (verbose)
+ pg_log_info("starting log streaming at %X/%X (timeline %u)",
+ LSN_FORMAT_ARGS(stream.startpos),
+ stream.timeline);
+
+ stream.stream_stop = stop_streaming;
+ stream.stop_socket = PGINVALID_SOCKET;
+ stream.standby_message_timeout = standby_message_timeout;
+ stream.synchronous = synchronous;
+ stream.do_sync = do_sync;
+ stream.mark_done = false;
+ stream.walmethod = CreateWalDirectoryMethod(basedir,
+ compression_algorithm,
+ compresslevel,
+ stream.do_sync);
+ stream.partial_suffix = ".partial";
+ stream.replication_slot = replication_slot;
+ stream.sysidentifier = sysidentifier;
+
+ ReceiveXlogStream(conn, &stream);
+
+ if (!stream.walmethod->finish())
+ {
+ pg_log_info("could not finish writing WAL files: %m");
+ return;
+ }
+
+ PQfinish(conn);
+ conn = NULL;
+
+ FreeWalDirectoryMethod();
+ pg_free(stream.walmethod);
+ pg_free(stream.sysidentifier);
+}
+
+/*
+ * When sigint is called, just tell the system to exit at the next possible
+ * moment.
+ */
+#ifndef WIN32
+
+static void
+sigint_handler(int signum)
+{
+ time_to_stop = true;
+}
+#endif
+
+int
+main(int argc, char **argv)
+{
+ static struct option long_options[] = {
+ {"help", no_argument, NULL, '?'},
+ {"version", no_argument, NULL, 'V'},
+ {"directory", required_argument, NULL, 'D'},
+ {"dbname", required_argument, NULL, 'd'},
+ {"endpos", required_argument, NULL, 'E'},
+ {"host", required_argument, NULL, 'h'},
+ {"port", required_argument, NULL, 'p'},
+ {"username", required_argument, NULL, 'U'},
+ {"no-loop", no_argument, NULL, 'n'},
+ {"no-password", no_argument, NULL, 'w'},
+ {"password", no_argument, NULL, 'W'},
+ {"status-interval", required_argument, NULL, 's'},
+ {"slot", required_argument, NULL, 'S'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"compress", required_argument, NULL, 'Z'},
+/* action */
+ {"create-slot", no_argument, NULL, 1},
+ {"drop-slot", no_argument, NULL, 2},
+ {"if-not-exists", no_argument, NULL, 3},
+ {"synchronous", no_argument, NULL, 4},
+ {"no-sync", no_argument, NULL, 5},
+ {NULL, 0, NULL, 0}
+ };
+
+ int c;
+ int option_index;
+ char *db_name;
+ uint32 hi,
+ lo;
+ pg_compress_specification compression_spec;
+ char *compression_detail = NULL;
+ char *compression_algorithm_str = "none";
+ char *error_detail = NULL;
+
+ pg_logging_init(argv[0]);
+ progname = get_progname(argv[0]);
+ set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ usage();
+ exit(0);
+ }
+ else if (strcmp(argv[1], "-V") == 0 ||
+ strcmp(argv[1], "--version") == 0)
+ {
+ puts("pg_receivewal (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
+
+ while ((c = getopt_long(argc, argv, "D:d:E:h:p:U:s:S:nwWvZ:",
+ long_options, &option_index)) != -1)
+ {
+ switch (c)
+ {
+ case 'D':
+ basedir = pg_strdup(optarg);
+ break;
+ case 'd':
+ connection_string = pg_strdup(optarg);
+ break;
+ case 'h':
+ dbhost = pg_strdup(optarg);
+ break;
+ case 'p':
+ dbport = pg_strdup(optarg);
+ break;
+ case 'U':
+ dbuser = pg_strdup(optarg);
+ break;
+ case 'w':
+ dbgetpassword = -1;
+ break;
+ case 'W':
+ dbgetpassword = 1;
+ break;
+ case 's':
+ if (!option_parse_int(optarg, "-s/--status-interval", 0,
+ INT_MAX / 1000,
+ &standby_message_timeout))
+ exit(1);
+ standby_message_timeout *= 1000;
+ break;
+ case 'S':
+ replication_slot = pg_strdup(optarg);
+ break;
+ case 'E':
+ if (sscanf(optarg, "%X/%X", &hi, &lo) != 2)
+ pg_fatal("could not parse end position \"%s\"", optarg);
+ endpos = ((uint64) hi) << 32 | lo;
+ break;
+ case 'n':
+ noloop = 1;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'Z':
+ parse_compress_options(optarg, &compression_algorithm_str,
+ &compression_detail);
+ break;
+/* action */
+ case 1:
+ do_create_slot = true;
+ break;
+ case 2:
+ do_drop_slot = true;
+ break;
+ case 3:
+ slot_exists_ok = true;
+ break;
+ case 4:
+ synchronous = true;
+ break;
+ case 5:
+ do_sync = false;
+ break;
+ default:
+ /* getopt_long already emitted a complaint */
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+ }
+
+ /*
+ * Any non-option arguments?
+ */
+ 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);
+ }
+
+ /*
+ * Required arguments
+ */
+ 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);
+ }
+
+ /*
+ * Compression options
+ */
+ if (!parse_compress_algorithm(compression_algorithm_str,
+ &compression_algorithm))
+ pg_fatal("unrecognized compression algorithm: \"%s\"",
+ compression_algorithm_str);
+
+ parse_compress_specification(compression_algorithm, compression_detail,
+ &compression_spec);
+ error_detail = validate_compress_specification(&compression_spec);
+ if (error_detail != NULL)
+ pg_fatal("invalid compression specification: %s",
+ error_detail);
+
+ /* Extract the compression level */
+ compresslevel = compression_spec.level;
+
+ if (compression_algorithm == PG_COMPRESSION_ZSTD)
+ pg_fatal("compression with %s is not yet supported", "ZSTD");
+
+ /*
+ * Check existence of destination folder.
+ */
+ if (!do_drop_slot && !do_create_slot)
+ {
+ DIR *dir = get_destination_dir(basedir);
+
+ close_destination_dir(dir, basedir);
+ }
+
+ /*
+ * Obtain a connection before doing anything.
+ */
+ conn = GetConnection();
+ if (!conn)
+ /* error message already written in GetConnection() */
+ exit(1);
+ atexit(disconnect_atexit);
+
+ /*
+ * Trap signals. (Don't do this until after the initial password prompt,
+ * if one is needed, in GetConnection.)
+ */
+#ifndef WIN32
+ pqsignal(SIGINT, sigint_handler);
+#endif
+
+ /*
+ * Run IDENTIFY_SYSTEM to make sure we've successfully have established a
+ * replication connection and haven't connected using a database specific
+ * connection.
+ */
+ if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name))
+ exit(1);
+
+ /*
+ * Check that there is a database associated with connection, none should
+ * be defined in this context.
+ */
+ if (db_name)
+ pg_fatal("replication connection using slot \"%s\" is unexpectedly database specific",
+ replication_slot);
+
+ /*
+ * Set umask so that directories/files are created with the same
+ * permissions as directories/files in the source data directory.
+ *
+ * pg_mode_mask is set to owner-only by default and then updated in
+ * GetConnection() where we get the mode from the server-side with
+ * RetrieveDataDirCreatePerm() and then call SetDataDirectoryCreatePerm().
+ */
+ umask(pg_mode_mask);
+
+ /*
+ * Drop a replication slot.
+ */
+ if (do_drop_slot)
+ {
+ if (verbose)
+ pg_log_info("dropping replication slot \"%s\"", replication_slot);
+
+ if (!DropReplicationSlot(conn, replication_slot))
+ exit(1);
+ exit(0);
+ }
+
+ /* Create a replication slot */
+ if (do_create_slot)
+ {
+ if (verbose)
+ pg_log_info("creating replication slot \"%s\"", replication_slot);
+
+ if (!CreateReplicationSlot(conn, replication_slot, NULL, false, true, false,
+ slot_exists_ok, false))
+ exit(1);
+ exit(0);
+ }
+
+ /* determine remote server's xlog segment size */
+ if (!RetrieveWalSegSize(conn))
+ exit(1);
+
+ /*
+ * Don't close the connection here so that subsequent StreamLog() can
+ * reuse it.
+ */
+
+ while (true)
+ {
+ StreamLog();
+ if (time_to_stop)
+ {
+ /*
+ * We've been Ctrl-C'ed or end of streaming position has been
+ * willingly reached, so exit without an error code.
+ */
+ exit(0);
+ }
+ else if (noloop)
+ pg_fatal("disconnected");
+ else
+ {
+ /* translator: check source for value for %d */
+ pg_log_info("disconnected; waiting %d seconds to try again",
+ RECONNECT_SLEEP_TIME);
+ pg_usleep(RECONNECT_SLEEP_TIME * 1000000);
+ }
+ }
+}
diff --git a/src/bin/pg_basebackup/pg_recvlogical.c b/src/bin/pg_basebackup/pg_recvlogical.c
new file mode 100644
index 0000000..02b8e27
--- /dev/null
+++ b/src/bin/pg_basebackup/pg_recvlogical.c
@@ -0,0 +1,1039 @@
+/*-------------------------------------------------------------------------
+ *
+ * pg_recvlogical.c - receive data from a logical decoding slot in a streaming
+ * fashion and write it to a local file.
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/pg_recvlogical.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "access/xlog_internal.h"
+#include "common/fe_memutils.h"
+#include "common/file_perm.h"
+#include "common/logging.h"
+#include "fe_utils/option_utils.h"
+#include "getopt_long.h"
+#include "libpq-fe.h"
+#include "libpq/pqsignal.h"
+#include "pqexpbuffer.h"
+#include "streamutil.h"
+
+/* Time to sleep between reconnection attempts */
+#define RECONNECT_SLEEP_TIME 5
+
+/* Global Options */
+static char *outfile = NULL;
+static int verbose = 0;
+static bool two_phase = false;
+static int noloop = 0;
+static int standby_message_timeout = 10 * 1000; /* 10 sec = default */
+static int fsync_interval = 10 * 1000; /* 10 sec = default */
+static XLogRecPtr startpos = InvalidXLogRecPtr;
+static XLogRecPtr endpos = InvalidXLogRecPtr;
+static bool do_create_slot = false;
+static bool slot_exists_ok = false;
+static bool do_start_slot = false;
+static bool do_drop_slot = false;
+static char *replication_slot = NULL;
+
+/* filled pairwise with option, value. value may be NULL */
+static char **options;
+static size_t noptions = 0;
+static const char *plugin = "test_decoding";
+
+/* Global State */
+static int outfd = -1;
+static volatile sig_atomic_t time_to_abort = false;
+static volatile sig_atomic_t output_reopen = false;
+static bool output_isfile;
+static TimestampTz output_last_fsync = -1;
+static bool output_needs_fsync = false;
+static XLogRecPtr output_written_lsn = InvalidXLogRecPtr;
+static XLogRecPtr output_fsync_lsn = InvalidXLogRecPtr;
+
+static void usage(void);
+static void StreamLogicalLog(void);
+static bool flushAndSendFeedback(PGconn *conn, TimestampTz *now);
+static void prepareToTerminate(PGconn *conn, XLogRecPtr endpos,
+ bool keepalive, XLogRecPtr lsn);
+
+static void
+usage(void)
+{
+ printf(_("%s controls PostgreSQL logical decoding streams.\n\n"),
+ progname);
+ printf(_("Usage:\n"));
+ printf(_(" %s [OPTION]...\n"), progname);
+ printf(_("\nAction to be performed:\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(_(" --start start streaming in a replication slot (for the slot's name see --slot)\n"));
+ printf(_("\nOptions:\n"));
+ printf(_(" -E, --endpos=LSN exit after receiving the specified LSN\n"));
+ printf(_(" -f, --file=FILE receive log into this file, - for stdout\n"));
+ printf(_(" -F --fsync-interval=SECS\n"
+ " time between fsyncs to the output file (default: %d)\n"), (fsync_interval / 1000));
+ printf(_(" --if-not-exists do not error if slot already exists when creating a slot\n"));
+ printf(_(" -I, --startpos=LSN where in an existing slot should the streaming start\n"));
+ printf(_(" -n, --no-loop do not loop on connection lost\n"));
+ printf(_(" -o, --option=NAME[=VALUE]\n"
+ " pass option NAME with optional value VALUE to the\n"
+ " output plugin\n"));
+ printf(_(" -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"), plugin);
+ printf(_(" -s, --status-interval=SECS\n"
+ " time between status packets sent to server (default: %d)\n"), (standby_message_timeout / 1000));
+ printf(_(" -S, --slot=SLOTNAME name of the logical replication slot\n"));
+ printf(_(" -t, --two-phase enable decoding of prepared transactions when creating a slot\n"));
+ printf(_(" -v, --verbose output verbose messages\n"));
+ printf(_(" -V, --version output version information, then exit\n"));
+ printf(_(" -?, --help show this help, then exit\n"));
+ printf(_("\nConnection options:\n"));
+ printf(_(" -d, --dbname=DBNAME database to connect to\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(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
+}
+
+/*
+ * Send a Standby Status Update message to server.
+ */
+static bool
+sendFeedback(PGconn *conn, TimestampTz now, bool force, bool replyRequested)
+{
+ static XLogRecPtr last_written_lsn = InvalidXLogRecPtr;
+ static XLogRecPtr last_fsync_lsn = InvalidXLogRecPtr;
+
+ char replybuf[1 + 8 + 8 + 8 + 8 + 1];
+ int len = 0;
+
+ /*
+ * we normally don't want to send superfluous feedback, but if it's
+ * because of a timeout we need to, otherwise wal_sender_timeout will kill
+ * us.
+ */
+ if (!force &&
+ last_written_lsn == output_written_lsn &&
+ last_fsync_lsn == output_fsync_lsn)
+ return true;
+
+ if (verbose)
+ pg_log_info("confirming write up to %X/%X, flush to %X/%X (slot %s)",
+ LSN_FORMAT_ARGS(output_written_lsn),
+ LSN_FORMAT_ARGS(output_fsync_lsn),
+ replication_slot);
+
+ replybuf[len] = 'r';
+ len += 1;
+ fe_sendint64(output_written_lsn, &replybuf[len]); /* write */
+ len += 8;
+ fe_sendint64(output_fsync_lsn, &replybuf[len]); /* flush */
+ len += 8;
+ fe_sendint64(InvalidXLogRecPtr, &replybuf[len]); /* apply */
+ len += 8;
+ fe_sendint64(now, &replybuf[len]); /* sendTime */
+ len += 8;
+ replybuf[len] = replyRequested ? 1 : 0; /* replyRequested */
+ len += 1;
+
+ startpos = output_written_lsn;
+ last_written_lsn = output_written_lsn;
+ last_fsync_lsn = output_fsync_lsn;
+
+ if (PQputCopyData(conn, replybuf, len) <= 0 || PQflush(conn))
+ {
+ pg_log_error("could not send feedback packet: %s",
+ PQerrorMessage(conn));
+ return false;
+ }
+
+ return true;
+}
+
+static void
+disconnect_atexit(void)
+{
+ if (conn != NULL)
+ PQfinish(conn);
+}
+
+static bool
+OutputFsync(TimestampTz now)
+{
+ output_last_fsync = now;
+
+ output_fsync_lsn = output_written_lsn;
+
+ if (fsync_interval <= 0)
+ return true;
+
+ if (!output_needs_fsync)
+ return true;
+
+ output_needs_fsync = false;
+
+ /* can only fsync if it's a regular file */
+ if (!output_isfile)
+ return true;
+
+ if (fsync(outfd) != 0)
+ pg_fatal("could not fsync file \"%s\": %m", outfile);
+
+ return true;
+}
+
+/*
+ * Start the log streaming
+ */
+static void
+StreamLogicalLog(void)
+{
+ PGresult *res;
+ char *copybuf = NULL;
+ TimestampTz last_status = -1;
+ int i;
+ PQExpBuffer query;
+
+ output_written_lsn = InvalidXLogRecPtr;
+ output_fsync_lsn = InvalidXLogRecPtr;
+
+ /*
+ * Connect in replication mode to the server
+ */
+ if (!conn)
+ conn = GetConnection();
+ if (!conn)
+ /* Error message already written in GetConnection() */
+ return;
+
+ /*
+ * Start the replication
+ */
+ if (verbose)
+ pg_log_info("starting log streaming at %X/%X (slot %s)",
+ LSN_FORMAT_ARGS(startpos),
+ replication_slot);
+
+ /* Initiate the replication stream at specified location */
+ query = createPQExpBuffer();
+ appendPQExpBuffer(query, "START_REPLICATION SLOT \"%s\" LOGICAL %X/%X",
+ replication_slot, LSN_FORMAT_ARGS(startpos));
+
+ /* print options if there are any */
+ if (noptions)
+ appendPQExpBufferStr(query, " (");
+
+ for (i = 0; i < noptions; i++)
+ {
+ /* separator */
+ if (i > 0)
+ appendPQExpBufferStr(query, ", ");
+
+ /* write option name */
+ appendPQExpBuffer(query, "\"%s\"", options[(i * 2)]);
+
+ /* write option value if specified */
+ if (options[(i * 2) + 1] != NULL)
+ appendPQExpBuffer(query, " '%s'", options[(i * 2) + 1]);
+ }
+
+ if (noptions)
+ appendPQExpBufferChar(query, ')');
+
+ res = PQexec(conn, query->data);
+ if (PQresultStatus(res) != PGRES_COPY_BOTH)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ query->data, PQresultErrorMessage(res));
+ PQclear(res);
+ goto error;
+ }
+ PQclear(res);
+ resetPQExpBuffer(query);
+
+ if (verbose)
+ pg_log_info("streaming initiated");
+
+ while (!time_to_abort)
+ {
+ int r;
+ int bytes_left;
+ int bytes_written;
+ TimestampTz now;
+ int hdr_len;
+ XLogRecPtr cur_record_lsn = InvalidXLogRecPtr;
+
+ if (copybuf != NULL)
+ {
+ PQfreemem(copybuf);
+ copybuf = NULL;
+ }
+
+ /*
+ * Potentially send a status message to the primary.
+ */
+ now = feGetCurrentTimestamp();
+
+ if (outfd != -1 &&
+ feTimestampDifferenceExceeds(output_last_fsync, now,
+ fsync_interval))
+ {
+ if (!OutputFsync(now))
+ goto error;
+ }
+
+ if (standby_message_timeout > 0 &&
+ feTimestampDifferenceExceeds(last_status, now,
+ standby_message_timeout))
+ {
+ /* Time to send feedback! */
+ if (!sendFeedback(conn, now, true, false))
+ goto error;
+
+ last_status = now;
+ }
+
+ /* got SIGHUP, close output file */
+ if (outfd != -1 && output_reopen && strcmp(outfile, "-") != 0)
+ {
+ now = feGetCurrentTimestamp();
+ if (!OutputFsync(now))
+ goto error;
+ close(outfd);
+ outfd = -1;
+ }
+ output_reopen = false;
+
+ /* open the output file, if not open yet */
+ if (outfd == -1)
+ {
+ struct stat statbuf;
+
+ if (strcmp(outfile, "-") == 0)
+ outfd = fileno(stdout);
+ else
+ outfd = open(outfile, O_CREAT | O_APPEND | O_WRONLY | PG_BINARY,
+ S_IRUSR | S_IWUSR);
+ if (outfd == -1)
+ {
+ pg_log_error("could not open log file \"%s\": %m", outfile);
+ goto error;
+ }
+
+ if (fstat(outfd, &statbuf) != 0)
+ {
+ pg_log_error("could not stat file \"%s\": %m", outfile);
+ goto error;
+ }
+
+ output_isfile = S_ISREG(statbuf.st_mode) && !isatty(outfd);
+ }
+
+ r = PQgetCopyData(conn, &copybuf, 1);
+ if (r == 0)
+ {
+ /*
+ * In async mode, and no data available. We block on reading but
+ * not more than the specified timeout, so that we can send a
+ * response back to the client.
+ */
+ fd_set input_mask;
+ TimestampTz message_target = 0;
+ TimestampTz fsync_target = 0;
+ struct timeval timeout;
+ struct timeval *timeoutptr = NULL;
+
+ if (PQsocket(conn) < 0)
+ {
+ pg_log_error("invalid socket: %s", PQerrorMessage(conn));
+ goto error;
+ }
+
+ FD_ZERO(&input_mask);
+ FD_SET(PQsocket(conn), &input_mask);
+
+ /* Compute when we need to wakeup to send a keepalive message. */
+ if (standby_message_timeout)
+ message_target = last_status + (standby_message_timeout - 1) *
+ ((int64) 1000);
+
+ /* Compute when we need to wakeup to fsync the output file. */
+ if (fsync_interval > 0 && output_needs_fsync)
+ fsync_target = output_last_fsync + (fsync_interval - 1) *
+ ((int64) 1000);
+
+ /* Now compute when to wakeup. */
+ if (message_target > 0 || fsync_target > 0)
+ {
+ TimestampTz targettime;
+ long secs;
+ int usecs;
+
+ targettime = message_target;
+
+ if (fsync_target > 0 && fsync_target < targettime)
+ targettime = fsync_target;
+
+ feTimestampDifference(now,
+ targettime,
+ &secs,
+ &usecs);
+ if (secs <= 0)
+ timeout.tv_sec = 1; /* Always sleep at least 1 sec */
+ else
+ timeout.tv_sec = secs;
+ timeout.tv_usec = usecs;
+ timeoutptr = &timeout;
+ }
+
+ r = select(PQsocket(conn) + 1, &input_mask, NULL, NULL, timeoutptr);
+ if (r == 0 || (r < 0 && errno == EINTR))
+ {
+ /*
+ * Got a timeout or signal. Continue the loop and either
+ * deliver a status packet to the server or just go back into
+ * blocking.
+ */
+ continue;
+ }
+ else if (r < 0)
+ {
+ pg_log_error("%s() failed: %m", "select");
+ goto error;
+ }
+
+ /* Else there is actually data on the socket */
+ if (PQconsumeInput(conn) == 0)
+ {
+ pg_log_error("could not receive data from WAL stream: %s",
+ PQerrorMessage(conn));
+ goto error;
+ }
+ continue;
+ }
+
+ /* End of copy stream */
+ if (r == -1)
+ break;
+
+ /* Failure while reading the copy stream */
+ if (r == -2)
+ {
+ pg_log_error("could not read COPY data: %s",
+ PQerrorMessage(conn));
+ goto error;
+ }
+
+ /* Check the message type. */
+ if (copybuf[0] == 'k')
+ {
+ int pos;
+ bool replyRequested;
+ XLogRecPtr walEnd;
+ bool endposReached = false;
+
+ /*
+ * Parse the keepalive message, enclosed in the CopyData message.
+ * We just check if the server requested a reply, and ignore the
+ * rest.
+ */
+ pos = 1; /* skip msgtype 'k' */
+ walEnd = fe_recvint64(&copybuf[pos]);
+ output_written_lsn = Max(walEnd, output_written_lsn);
+
+ pos += 8; /* read walEnd */
+
+ pos += 8; /* skip sendTime */
+
+ if (r < pos + 1)
+ {
+ pg_log_error("streaming header too small: %d", r);
+ goto error;
+ }
+ replyRequested = copybuf[pos];
+
+ if (endpos != InvalidXLogRecPtr && walEnd >= endpos)
+ {
+ /*
+ * If there's nothing to read on the socket until a keepalive
+ * we know that the server has nothing to send us; and if
+ * walEnd has passed endpos, we know nothing else can have
+ * committed before endpos. So we can bail out now.
+ */
+ endposReached = true;
+ }
+
+ /* Send a reply, if necessary */
+ if (replyRequested || endposReached)
+ {
+ if (!flushAndSendFeedback(conn, &now))
+ goto error;
+ last_status = now;
+ }
+
+ if (endposReached)
+ {
+ prepareToTerminate(conn, endpos, true, InvalidXLogRecPtr);
+ time_to_abort = true;
+ break;
+ }
+
+ continue;
+ }
+ else if (copybuf[0] != 'w')
+ {
+ pg_log_error("unrecognized streaming header: \"%c\"",
+ copybuf[0]);
+ goto error;
+ }
+
+ /*
+ * Read the header of the XLogData message, enclosed in the CopyData
+ * message. We only need the WAL location field (dataStart), the rest
+ * of the header is ignored.
+ */
+ hdr_len = 1; /* msgtype 'w' */
+ hdr_len += 8; /* dataStart */
+ hdr_len += 8; /* walEnd */
+ hdr_len += 8; /* sendTime */
+ if (r < hdr_len + 1)
+ {
+ pg_log_error("streaming header too small: %d", r);
+ goto error;
+ }
+
+ /* Extract WAL location for this block */
+ cur_record_lsn = fe_recvint64(&copybuf[1]);
+
+ if (endpos != InvalidXLogRecPtr && cur_record_lsn > endpos)
+ {
+ /*
+ * We've read past our endpoint, so prepare to go away being
+ * cautious about what happens to our output data.
+ */
+ if (!flushAndSendFeedback(conn, &now))
+ goto error;
+ prepareToTerminate(conn, endpos, false, cur_record_lsn);
+ time_to_abort = true;
+ break;
+ }
+
+ output_written_lsn = Max(cur_record_lsn, output_written_lsn);
+
+ bytes_left = r - hdr_len;
+ bytes_written = 0;
+
+ /* signal that a fsync is needed */
+ output_needs_fsync = true;
+
+ while (bytes_left)
+ {
+ int ret;
+
+ ret = write(outfd,
+ copybuf + hdr_len + bytes_written,
+ bytes_left);
+
+ if (ret < 0)
+ {
+ pg_log_error("could not write %d bytes to log file \"%s\": %m",
+ bytes_left, outfile);
+ goto error;
+ }
+
+ /* Write was successful, advance our position */
+ bytes_written += ret;
+ bytes_left -= ret;
+ }
+
+ if (write(outfd, "\n", 1) != 1)
+ {
+ pg_log_error("could not write %d bytes to log file \"%s\": %m",
+ 1, outfile);
+ goto error;
+ }
+
+ if (endpos != InvalidXLogRecPtr && cur_record_lsn == endpos)
+ {
+ /* endpos was exactly the record we just processed, we're done */
+ if (!flushAndSendFeedback(conn, &now))
+ goto error;
+ prepareToTerminate(conn, endpos, false, cur_record_lsn);
+ time_to_abort = true;
+ break;
+ }
+ }
+
+ res = PQgetResult(conn);
+ if (PQresultStatus(res) == PGRES_COPY_OUT)
+ {
+ PQclear(res);
+
+ /*
+ * We're doing a client-initiated clean exit and have sent CopyDone to
+ * the server. Drain any messages, so we don't miss a last-minute
+ * ErrorResponse. The walsender stops generating XLogData records once
+ * it sees CopyDone, so expect this to finish quickly. After CopyDone,
+ * it's too late for sendFeedback(), even if this were to take a long
+ * time. Hence, use synchronous-mode PQgetCopyData().
+ */
+ while (1)
+ {
+ int r;
+
+ if (copybuf != NULL)
+ {
+ PQfreemem(copybuf);
+ copybuf = NULL;
+ }
+ r = PQgetCopyData(conn, &copybuf, 0);
+ if (r == -1)
+ break;
+ if (r == -2)
+ {
+ pg_log_error("could not read COPY data: %s",
+ PQerrorMessage(conn));
+ time_to_abort = false; /* unclean exit */
+ goto error;
+ }
+ }
+
+ res = PQgetResult(conn);
+ }
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ pg_log_error("unexpected termination of replication stream: %s",
+ PQresultErrorMessage(res));
+ goto error;
+ }
+ PQclear(res);
+
+ if (outfd != -1 && strcmp(outfile, "-") != 0)
+ {
+ TimestampTz t = feGetCurrentTimestamp();
+
+ /* no need to jump to error on failure here, we're finishing anyway */
+ OutputFsync(t);
+
+ if (close(outfd) != 0)
+ pg_log_error("could not close file \"%s\": %m", outfile);
+ }
+ outfd = -1;
+error:
+ if (copybuf != NULL)
+ {
+ PQfreemem(copybuf);
+ copybuf = NULL;
+ }
+ destroyPQExpBuffer(query);
+ PQfinish(conn);
+ conn = NULL;
+}
+
+/*
+ * Unfortunately we can't do sensible signal handling on windows...
+ */
+#ifndef WIN32
+
+/*
+ * When sigint is called, just tell the system to exit at the next possible
+ * moment.
+ */
+static void
+sigint_handler(int signum)
+{
+ time_to_abort = true;
+}
+
+/*
+ * Trigger the output file to be reopened.
+ */
+static void
+sighup_handler(int signum)
+{
+ output_reopen = true;
+}
+#endif
+
+
+int
+main(int argc, char **argv)
+{
+ static struct option long_options[] = {
+/* general options */
+ {"file", required_argument, NULL, 'f'},
+ {"fsync-interval", required_argument, NULL, 'F'},
+ {"no-loop", no_argument, NULL, 'n'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"two-phase", no_argument, NULL, 't'},
+ {"version", no_argument, NULL, 'V'},
+ {"help", no_argument, NULL, '?'},
+/* connection options */
+ {"dbname", required_argument, NULL, 'd'},
+ {"host", required_argument, NULL, 'h'},
+ {"port", required_argument, NULL, 'p'},
+ {"username", required_argument, NULL, 'U'},
+ {"no-password", no_argument, NULL, 'w'},
+ {"password", no_argument, NULL, 'W'},
+/* replication options */
+ {"startpos", required_argument, NULL, 'I'},
+ {"endpos", required_argument, NULL, 'E'},
+ {"option", required_argument, NULL, 'o'},
+ {"plugin", required_argument, NULL, 'P'},
+ {"status-interval", required_argument, NULL, 's'},
+ {"slot", required_argument, NULL, 'S'},
+/* action */
+ {"create-slot", no_argument, NULL, 1},
+ {"start", no_argument, NULL, 2},
+ {"drop-slot", no_argument, NULL, 3},
+ {"if-not-exists", no_argument, NULL, 4},
+ {NULL, 0, NULL, 0}
+ };
+ int c;
+ int option_index;
+ uint32 hi,
+ lo;
+ char *db_name;
+
+ pg_logging_init(argv[0]);
+ progname = get_progname(argv[0]);
+ set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_basebackup"));
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ usage();
+ exit(0);
+ }
+ else if (strcmp(argv[1], "-V") == 0 ||
+ strcmp(argv[1], "--version") == 0)
+ {
+ puts("pg_recvlogical (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
+
+ while ((c = getopt_long(argc, argv, "E:f:F:nvtd:h:p:U:wWI:o:P:s:S:",
+ long_options, &option_index)) != -1)
+ {
+ switch (c)
+ {
+/* general options */
+ case 'f':
+ outfile = pg_strdup(optarg);
+ break;
+ case 'F':
+ if (!option_parse_int(optarg, "-F/--fsync-interval", 0,
+ INT_MAX / 1000,
+ &fsync_interval))
+ exit(1);
+ fsync_interval *= 1000;
+ break;
+ case 'n':
+ noloop = 1;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 't':
+ two_phase = true;
+ break;
+/* connection options */
+ case 'd':
+ dbname = pg_strdup(optarg);
+ break;
+ case 'h':
+ dbhost = pg_strdup(optarg);
+ break;
+ case 'p':
+ dbport = pg_strdup(optarg);
+ break;
+ case 'U':
+ dbuser = pg_strdup(optarg);
+ break;
+ case 'w':
+ dbgetpassword = -1;
+ break;
+ case 'W':
+ dbgetpassword = 1;
+ break;
+/* replication options */
+ case 'I':
+ if (sscanf(optarg, "%X/%X", &hi, &lo) != 2)
+ pg_fatal("could not parse start position \"%s\"", optarg);
+ startpos = ((uint64) hi) << 32 | lo;
+ break;
+ case 'E':
+ if (sscanf(optarg, "%X/%X", &hi, &lo) != 2)
+ pg_fatal("could not parse end position \"%s\"", optarg);
+ endpos = ((uint64) hi) << 32 | lo;
+ break;
+ case 'o':
+ {
+ char *data = pg_strdup(optarg);
+ char *val = strchr(data, '=');
+
+ if (val != NULL)
+ {
+ /* remove =; separate data from val */
+ *val = '\0';
+ val++;
+ }
+
+ noptions += 1;
+ options = pg_realloc(options, sizeof(char *) * noptions * 2);
+
+ options[(noptions - 1) * 2] = data;
+ options[(noptions - 1) * 2 + 1] = val;
+ }
+
+ break;
+ case 'P':
+ plugin = pg_strdup(optarg);
+ break;
+ case 's':
+ if (!option_parse_int(optarg, "-s/--status-interval", 0,
+ INT_MAX / 1000,
+ &standby_message_timeout))
+ exit(1);
+ standby_message_timeout *= 1000;
+ break;
+ case 'S':
+ replication_slot = pg_strdup(optarg);
+ break;
+/* action */
+ case 1:
+ do_create_slot = true;
+ break;
+ case 2:
+ do_start_slot = true;
+ break;
+ case 3:
+ do_drop_slot = true;
+ break;
+ case 4:
+ slot_exists_ok = true;
+ break;
+
+ default:
+ /* getopt_long already emitted a complaint */
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+ }
+
+ /*
+ * Any non-option arguments?
+ */
+ 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);
+ }
+
+ /*
+ * Required arguments
+ */
+ if (replication_slot == NULL)
+ {
+ pg_log_error("no slot specified");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (do_start_slot && outfile == NULL)
+ {
+ pg_log_error("no target file specified");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (!do_drop_slot && dbname == NULL)
+ {
+ pg_log_error("no database specified");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (!do_drop_slot && !do_create_slot && !do_start_slot)
+ {
+ pg_log_error("at least one action needs to be specified");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (do_drop_slot && (do_create_slot || do_start_slot))
+ {
+ pg_log_error("cannot use --create-slot or --start together with --drop-slot");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (startpos != InvalidXLogRecPtr && (do_create_slot || do_drop_slot))
+ {
+ pg_log_error("cannot use --create-slot or --drop-slot together with --startpos");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (endpos != InvalidXLogRecPtr && !do_start_slot)
+ {
+ pg_log_error("--endpos may only be specified with --start");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ if (two_phase && !do_create_slot)
+ {
+ pg_log_error("--two-phase may only be specified with --create-slot");
+ pg_log_error_hint("Try \"%s --help\" for more information.", progname);
+ exit(1);
+ }
+
+ /*
+ * Obtain a connection to server. Notably, if we need a password, we want
+ * to collect it from the user immediately.
+ */
+ conn = GetConnection();
+ if (!conn)
+ /* Error message already written in GetConnection() */
+ exit(1);
+ atexit(disconnect_atexit);
+
+ /*
+ * Trap signals. (Don't do this until after the initial password prompt,
+ * if one is needed, in GetConnection.)
+ */
+#ifndef WIN32
+ pqsignal(SIGINT, sigint_handler);
+ pqsignal(SIGHUP, sighup_handler);
+#endif
+
+ /*
+ * Run IDENTIFY_SYSTEM to make sure we connected using a database specific
+ * replication connection.
+ */
+ if (!RunIdentifySystem(conn, NULL, NULL, NULL, &db_name))
+ exit(1);
+
+ if (db_name == NULL)
+ pg_fatal("could not establish database-specific replication connection");
+
+ /*
+ * Set umask so that directories/files are created with the same
+ * permissions as directories/files in the source data directory.
+ *
+ * pg_mode_mask is set to owner-only by default and then updated in
+ * GetConnection() where we get the mode from the server-side with
+ * RetrieveDataDirCreatePerm() and then call SetDataDirectoryCreatePerm().
+ */
+ umask(pg_mode_mask);
+
+ /* Drop a replication slot. */
+ if (do_drop_slot)
+ {
+ if (verbose)
+ pg_log_info("dropping replication slot \"%s\"", replication_slot);
+
+ if (!DropReplicationSlot(conn, replication_slot))
+ exit(1);
+ }
+
+ /* Create a replication slot. */
+ if (do_create_slot)
+ {
+ if (verbose)
+ pg_log_info("creating replication slot \"%s\"", replication_slot);
+
+ if (!CreateReplicationSlot(conn, replication_slot, plugin, false,
+ false, false, slot_exists_ok, two_phase))
+ exit(1);
+ startpos = InvalidXLogRecPtr;
+ }
+
+ if (!do_start_slot)
+ exit(0);
+
+ /* Stream loop */
+ while (true)
+ {
+ StreamLogicalLog();
+ if (time_to_abort)
+ {
+ /*
+ * We've been Ctrl-C'ed or reached an exit limit condition. That's
+ * not an error, so exit without an errorcode.
+ */
+ exit(0);
+ }
+ else if (noloop)
+ pg_fatal("disconnected");
+ else
+ {
+ /* translator: check source for value for %d */
+ pg_log_info("disconnected; waiting %d seconds to try again",
+ RECONNECT_SLEEP_TIME);
+ pg_usleep(RECONNECT_SLEEP_TIME * 1000000);
+ }
+ }
+}
+
+/*
+ * Fsync our output data, and send a feedback message to the server. Returns
+ * true if successful, false otherwise.
+ *
+ * If successful, *now is updated to the current timestamp just before sending
+ * feedback.
+ */
+static bool
+flushAndSendFeedback(PGconn *conn, TimestampTz *now)
+{
+ /* flush data to disk, so that we send a recent flush pointer */
+ if (!OutputFsync(*now))
+ return false;
+ *now = feGetCurrentTimestamp();
+ if (!sendFeedback(conn, *now, true, false))
+ return false;
+
+ return true;
+}
+
+/*
+ * Try to inform the server about our upcoming demise, but don't wait around or
+ * retry on failure.
+ */
+static void
+prepareToTerminate(PGconn *conn, XLogRecPtr endpos, bool keepalive, XLogRecPtr lsn)
+{
+ (void) PQputCopyEnd(conn, NULL);
+ (void) PQflush(conn);
+
+ if (verbose)
+ {
+ if (keepalive)
+ pg_log_info("end position %X/%X reached by keepalive",
+ LSN_FORMAT_ARGS(endpos));
+ else
+ pg_log_info("end position %X/%X reached by WAL record at %X/%X",
+ LSN_FORMAT_ARGS(endpos), LSN_FORMAT_ARGS(lsn));
+ }
+}
diff --git a/src/bin/pg_basebackup/po/de.po b/src/bin/pg_basebackup/po/de.po
new file mode 100644
index 0000000..97fc0f6
--- /dev/null
+++ b/src/bin/pg_basebackup/po/de.po
@@ -0,0 +1,1812 @@
+# German message translation file for pg_basebackup
+# Copyright (C) 2011 - 2022 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+#
+# Use these quotes: »%s«
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PostgreSQL 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-09-24 23:18+0000\n"
+"PO-Revision-Date: 2022-09-25 10:56+0200\n"
+"Last-Translator: Peter Eisentraut <peter@eisentraut.org>\n"
+"Language-Team: German <pgsql-translators@postgresql.org>\n"
+"Language: de\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "Fehler: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "Warnung: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "Detail: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "Tipp: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "diese Installation unterstützt keine Komprimierung mit %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "leere Zeichenkette gefunden wo eine Komprimierungsoption erwartet wurde"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "unbekannte Komprimierungsoption: »%s«"
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "Komprimierungsoption »%s« benötigt einen Wert"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "Wert für Komprimierungsoption »%s« muss eine ganze Zahl sein"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "Komprimierungsalgorithmus »%s« akzeptiert kein Komprimierungsniveau"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "Komprimierungsalgorithmus »%s« erwartet ein Komprimierungsniveau zwischen %d und %d (Standard bei %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "Komprimierungsalgorithmus »%s« akzeptiert keine Worker-Anzahl"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "Speicher aufgebraucht\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "kann NULL-Zeiger nicht kopieren (interner Fehler)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "konnte »stat« für Datei »%s« nicht ausführen: %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "konnte Verzeichnis »%s« nicht öffnen: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "konnte Verzeichnis »%s« nicht lesen: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "konnte Datei »%s« nicht öffnen: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "konnte Datei »%s« nicht fsyncen: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2256 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "konnte Datei »%s« nicht in »%s« umbenennen: %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "ungültiger Wert »%s« für Option %s"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s muss im Bereich %d..%d sein"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1636
+#, c-format
+msgid "out of memory"
+msgstr "Speicher aufgebraucht"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1433 pg_basebackup.c:1727
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "konnte nicht in Datei »%s« schreiben: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1497 pg_basebackup.c:1706
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "konnte Datei »%s« nicht erstellen: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "konnte Datei »%s« nicht schließen: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "unerwarteter Zustand beim Extrahieren des Archivs"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:686 pg_basebackup.c:730
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "konnte Verzeichnis »%s« nicht erzeugen: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "konnte Zugriffsrechte für Verzeichnis »%s« nicht setzen: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "konnte symbolische Verknüpfung von »%s« nach »%s« nicht erzeugen: %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "konnte Zugriffsrechte von Datei »%s« nicht setzen: %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "konnte komprimierte Datei »%s« nicht erzeugen: %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "konnte Standardausgabe nicht duplizieren: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "konnte Ausgabedatei nicht öffnen: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "konnte Komprimierungsniveau %d nicht setzen: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "diese Installation unterstützt keine gzip-Komprimierung"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "konnte nicht in komprimierte Datei »%s« schreiben: %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "konnte komprimierte Datei »%s« nicht schließen: %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "konnte Komprimierungsbibliothek nicht initialisieren"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "konnte Daten nicht dekomprimieren: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "unerwarteter Zustand beim Einfügen der Recovery-Einstellungen"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "konnte lz4-Komprimierungskontext nicht erzeugen: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "diese Installation unterstützt keine lz4-Komprimierung"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "konnte lz4-Header nicht schreiben: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "konnte Daten nicht komprimieren: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "konnte lz4-Komprimierung nicht beenden: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "konnte Komprimierungsbibliothek nicht initialisieren: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "Tar-Datei-Trailer überschreitet 2 Blöcke"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "unerwarteter Zustand beim Parsen des Tar-Archivs"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "Tar-Mitglied hat leeren Namen"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "COPY-Strom endete vor dem Ende der letzten Datei"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "konnte zstd-Komprimierungskontext nicht erzeugen"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "konnte zstd-Komprimierungsniveau nicht auf %d setzen: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "konnte Komprimierungs-Worker-Anzahl nicht auf %d setzen: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "diese Installation unterstützt keine zstd-Komprimierung"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "konnte zstd-Dekomprimierungskontext nicht erzeugen"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "entferne Datenverzeichnis »%s«"
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "konnte Datenverzeichnis nicht entfernen"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "entferne Inhalt des Datenverzeichnisses »%s«"
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "konnte Inhalt des Datenverzeichnisses nicht entfernen"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "entferne WAL-Verzeichnis »%s«"
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "konnte WAL-Verzeichnis nicht entfernen"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "entferne Inhalt des WAL-Verzeichnisses »%s«"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "konnte Inhalt des WAL-Verzeichnisses nicht entfernen"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "Datenverzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "WAL-Verzeichnis »%s« wurde auf Anwenderwunsch nicht entfernt"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "Änderungen in Tablespace-Verzeichnissen werden nicht rückgängig gemacht"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "Verzeichnisname zu lang"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "mehrere »=«-Zeichen im Tablespace-Mapping"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "ungültiges Tablespace-Mapping-Format »%s«, muss »ALTES_VERZ=NEUES_VERZ« sein"
+
+#: pg_basebackup.c:351
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "altes Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s"
+
+#: pg_basebackup.c:355
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "neues Verzeichnis im Tablespace-Mapping ist kein absoluter Pfad: %s"
+
+#: pg_basebackup.c:377
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s erzeugt eine Basissicherung eines laufenden PostgreSQL-Servers.\n"
+"\n"
+
+#: pg_basebackup.c:379 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Aufruf:\n"
+
+#: pg_basebackup.c:380 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [OPTION]...\n"
+
+#: pg_basebackup.c:381
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Optionen die die Ausgabe kontrollieren:\n"
+
+#: pg_basebackup.c:382
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=VERZ Basissicherung in dieses Verzeichnis empfangen\n"
+
+#: pg_basebackup.c:383
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t Ausgabeformat (plain (Voreinstellung), tar)\n"
+
+#: pg_basebackup.c:384
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=RATE maximale Transferrate für Übertragung des Datenver-\n"
+" zeichnisses (in kB/s, oder Suffix »k« oder »M« abgeben)\n"
+
+#: pg_basebackup.c:386
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" Konfiguration für Replikation schreiben\n"
+
+#: pg_basebackup.c:388
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=ZIEL[:DETAIL]\n"
+" Backup-Ziel (wenn nicht Client)\n"
+
+#: pg_basebackup.c:390
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=ALTES_VERZ=NEUES_VERZ\n"
+" Tablespace in ALTES_VERZ nach NEUES_VERZ verlagern\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=WALVERZ Verzeichnis für das Write-Ahead-Log\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" benötigte WAL-Dateien mit angegebener Methode einbeziehen\n"
+
+#: pg_basebackup.c:395
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip Tar-Ausgabe komprimieren\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METHODE[:DETAIL]\n"
+" auf Client oder Server wie angegeben komprimieren\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none Tar-Ausgabe nicht komprimieren\n"
+
+#: pg_basebackup.c:399
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Allgemeine Optionen:\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" schnelles oder verteiltes Checkpointing einstellen\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot Replikations-Slot erzeugen\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL Backup-Label setzen\n"
+
+#: pg_basebackup.c:404
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean nach Fehlern nicht aufräumen\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr ""
+" -N, --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n"
+" geschrieben sind\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress Fortschrittsinformationen zeigen\n"
+
+#: pg_basebackup.c:407 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=SLOTNAME zu verwendender Replikations-Slot\n"
+
+#: pg_basebackup.c:408 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose »Verbose«-Modus\n"
+
+#: pg_basebackup.c:409 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" Algorithmus für Manifest-Prüfsummen\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" alle Dateinamen im Manifest hex-kodieren\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size nicht die Backup-Größe auf dem Server schätzen\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest kein Backup-Manifest erzeugen\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot keinen temporären Replikations-Slot erzeugen\n"
+
+#: pg_basebackup.c:417
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" Prüfsummen nicht überprüfen\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n"
+
+#: pg_basebackup.c:420 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Verbindungsoptionen:\n"
+
+#: pg_basebackup.c:421 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=VERBDG Verbindungsparameter\n"
+
+#: pg_basebackup.c:422 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=HOSTNAME Name des Datenbankservers oder Socket-Verzeichnis\n"
+
+#: pg_basebackup.c:423 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT Portnummer des Datenbankservers\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVALL\n"
+" Zeit zwischen an Server gesendeten Statuspaketen (in Sekunden)\n"
+
+#: pg_basebackup.c:426 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NAME Datenbankbenutzername\n"
+
+#: pg_basebackup.c:427 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password niemals nach Passwort fragen\n"
+
+#: pg_basebackup.c:428 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr " -W, --password nach Passwort fragen (sollte automatisch geschehen)\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Berichten Sie Fehler an <%s>.\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s Homepage: <%s>\n"
+
+#: pg_basebackup.c:472
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "konnte nicht aus bereiter Pipe lesen: %m"
+
+#: pg_basebackup.c:475 pg_basebackup.c:622 pg_basebackup.c:2170
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "konnte Write-Ahead-Log-Position »%s« nicht interpretieren"
+
+#: pg_basebackup.c:581 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "konnte WAL-Dateien nicht zu Ende schreiben: %m"
+
+#: pg_basebackup.c:631
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "konnte Pipe für Hintergrundprozess nicht erzeugen: %m"
+
+#: pg_basebackup.c:664
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "temporärer Replikations-Slot »%s« wurde erzeugt"
+
+#: pg_basebackup.c:667
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "Replikations-Slot »%s« wurde erzeugt"
+
+#: pg_basebackup.c:701
+#, c-format
+msgid "could not create background process: %m"
+msgstr "konnte Hintergrundprozess nicht erzeugen: %m"
+
+#: pg_basebackup.c:710
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "konnte Hintergrund-Thread nicht erzeugen: %m"
+
+#: pg_basebackup.c:749
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "Verzeichnis »%s« existiert aber ist nicht leer"
+
+#: pg_basebackup.c:755
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "konnte nicht auf Verzeichnis »%s« zugreifen: %m"
+
+#: pg_basebackup.c:832
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d Tablespace %*s"
+msgstr[1] "%*s/%s kB (100%%), %d/%d Tablespaces %*s"
+
+#: pg_basebackup.c:844
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d Tablespace (%s%-*.*s)"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d Tablespaces (%s%-*.*s)"
+
+#: pg_basebackup.c:860
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d Tablespace"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d Tablespaces"
+
+#: pg_basebackup.c:884
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "Transferrate »%s« ist kein gültiger Wert"
+
+#: pg_basebackup.c:886
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "ungültige Transferrate »%s«: %m"
+
+#: pg_basebackup.c:893
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "Transferrate muss größer als null sein"
+
+#: pg_basebackup.c:923
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "ungültige Einheit für --max-rate: »%s«"
+
+#: pg_basebackup.c:927
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "Transferrate »%s« überschreitet Bereich für ganze Zahlen"
+
+#: pg_basebackup.c:934
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "Transferrate »%s« ist außerhalb des gültigen Bereichs"
+
+#: pg_basebackup.c:1030
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "konnte COPY-Datenstrom nicht empfangen: %s"
+
+#: pg_basebackup.c:1047 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "konnte COPY-Daten nicht lesen: %s"
+
+#: pg_basebackup.c:1051
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "Hintergrundprozess beendete unerwartet"
+
+#: pg_basebackup.c:1122
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "Manifest kann nicht in eine komprimierte Tar-Datei eingefügt werden"
+
+#: pg_basebackup.c:1123
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "Verwenden Sie clientseitige Komprimierung, senden Sie die Ausgabe in ein Verzeichnis statt auf die Standardausgabe, oder verwenden Sie %s."
+
+#: pg_basebackup.c:1139
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "kann Archiv »%s« nicht parsen"
+
+#: pg_basebackup.c:1140
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Nur Tar-Archive können geparst werden."
+
+#: pg_basebackup.c:1142
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Format »plain« benötigt pg_basebackup, um das Archiv zu parsen."
+
+#: pg_basebackup.c:1144
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "Wenn - als Ausgabeverzeichnis verwendet wird, wird pg_basebackup benötigt, um das Archiv zu parsen."
+
+#: pg_basebackup.c:1146
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "Die Option -R benötigt pg_basebackup, um das Archiv zu parsen."
+
+#: pg_basebackup.c:1357
+#, c-format
+msgid "archives must precede manifest"
+msgstr "Archive müssen vor dem Manifest kommen"
+
+#: pg_basebackup.c:1372
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "ungültiger Archivname: »%s«"
+
+#: pg_basebackup.c:1444
+#, c-format
+msgid "unexpected payload data"
+msgstr "unerwartete Payload-Daten"
+
+#: pg_basebackup.c:1587
+#, c-format
+msgid "empty COPY message"
+msgstr "leere COPY-Nachricht"
+
+#: pg_basebackup.c:1589
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "fehlerhafte COPY-Nachricht vom Typ %d, Länge %zu"
+
+#: pg_basebackup.c:1787
+#, c-format
+msgid "incompatible server version %s"
+msgstr "inkompatible Serverversion %s"
+
+#: pg_basebackup.c:1803
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Verwenden Sie -X none oder -X fetch, um Log-Streaming abzuschalten."
+
+#: pg_basebackup.c:1871
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "Backup-Ziele werden von dieser Serverversion nicht unterstützt"
+
+#: pg_basebackup.c:1874
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "Recovery-Konfiguration kann nicht geschrieben werden, wenn ein Backup-Ziel verwendet wird"
+
+#: pg_basebackup.c:1901
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "Server unterstützt keine serverseitige Komprimierung"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "Basissicherung eingeleitet, warte auf Abschluss des Checkpoints"
+
+#: pg_basebackup.c:1915
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "Warten auf Checkpoint"
+
+#: pg_basebackup.c:1928 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "konnte Replikationsbefehl »%s« nicht senden: %s"
+
+#: pg_basebackup.c:1936
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "konnte Basissicherung nicht starten: %s"
+
+#: pg_basebackup.c:1939
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "unerwartete Antwort auf Befehl BASE_BACKUP: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet"
+
+#: pg_basebackup.c:1945
+#, c-format
+msgid "checkpoint completed"
+msgstr "Checkpoint abgeschlossen"
+
+#: pg_basebackup.c:1960
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "Write-Ahead-Log-Startpunkt: %s auf Zeitleiste %u"
+
+#: pg_basebackup.c:1968
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "konnte Kopf der Sicherung nicht empfangen: %s"
+
+#: pg_basebackup.c:1971
+#, c-format
+msgid "no data returned from server"
+msgstr "keine Daten vom Server zurückgegeben"
+
+#: pg_basebackup.c:2006
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "kann nur einen einzelnen Tablespace auf die Standardausgabe schreiben, Datenbank hat %d"
+
+#: pg_basebackup.c:2019
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "Hintergrund-WAL-Receiver wird gestartet"
+
+#: pg_basebackup.c:2101
+#, c-format
+msgid "backup failed: %s"
+msgstr "Backup fehlgeschlagen: %s"
+
+#: pg_basebackup.c:2104
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "keine Write-Ahead-Log-Endposition vom Server zurückgegeben"
+
+#: pg_basebackup.c:2107
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "Write-Ahead-Log-Endposition: %s"
+
+#: pg_basebackup.c:2118
+#, c-format
+msgid "checksum error occurred"
+msgstr "ein Prüfsummenfehler ist aufgetreten"
+
+#: pg_basebackup.c:2123
+#, c-format
+msgid "final receive failed: %s"
+msgstr "letztes Empfangen fehlgeschlagen: %s"
+
+#: pg_basebackup.c:2147
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "warte bis Hintergrundprozess Streaming beendet hat ..."
+
+#: pg_basebackup.c:2151
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "konnte Befehl nicht an Hintergrund-Pipe senden: %m"
+
+#: pg_basebackup.c:2156
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "konnte nicht auf Kindprozess warten: %m"
+
+#: pg_basebackup.c:2158
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "Kindprozess %d endete, aber %d wurde erwartet"
+
+#: pg_basebackup.c:2160 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2180
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "konnte nicht auf Kind-Thread warten: %m"
+
+#: pg_basebackup.c:2185
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "konnte Statuscode des Kind-Threads nicht ermitteln: %m"
+
+#: pg_basebackup.c:2188
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "Kind-Thread hat mit Fehler %u beendet"
+
+#: pg_basebackup.c:2217
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "synchronisiere Daten auf Festplatte ..."
+
+#: pg_basebackup.c:2242
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "umbenennen von backup_manifest.tmp nach backup_manifest"
+
+#: pg_basebackup.c:2262
+#, c-format
+msgid "base backup completed"
+msgstr "Basissicherung abgeschlossen"
+
+#: pg_basebackup.c:2351
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "ungültiges Ausgabeformat »%s«, muss »plain« oder »tar« sein"
+
+#: pg_basebackup.c:2395
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "ungültige Option »%s« für --wal-method, muss »fetch«, »stream« oder »none« sein"
+
+#: pg_basebackup.c:2425
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "ungültiges Checkpoint-Argument »%s«, muss »fast« oder »spread« sein"
+
+#: pg_basebackup.c:2476 pg_basebackup.c:2488 pg_basebackup.c:2510
+#: pg_basebackup.c:2522 pg_basebackup.c:2528 pg_basebackup.c:2580
+#: pg_basebackup.c:2591 pg_basebackup.c:2601 pg_basebackup.c:2607
+#: pg_basebackup.c:2614 pg_basebackup.c:2626 pg_basebackup.c:2638
+#: pg_basebackup.c:2646 pg_basebackup.c:2659 pg_basebackup.c:2665
+#: pg_basebackup.c:2674 pg_basebackup.c:2686 pg_basebackup.c:2697
+#: pg_basebackup.c:2705 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Versuchen Sie »%s --help« für weitere Informationen."
+
+#: pg_basebackup.c:2486 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "zu viele Kommandozeilenargumente (das erste ist »%s«)"
+
+#: pg_basebackup.c:2509
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "Format und Backup-Ziel können nicht beide angegeben werden"
+
+#: pg_basebackup.c:2521
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "Ausgabeverzeichnis oder Backup-Ziel muss angegeben werden"
+
+#: pg_basebackup.c:2527
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "Ausgabeverzeichnis und Backup-Ziel können nicht beide angegeben werden"
+
+#: pg_basebackup.c:2557 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "unbekannter Komprimierungsalgorithmus: »%s«"
+
+#: pg_basebackup.c:2563 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "ungültige Komprimierungsangabe: %s"
+
+#: pg_basebackup.c:2579
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "clientseitige Komprimierung ist nicht möglich, wenn ein Backup-Ziel angegeben ist"
+
+#: pg_basebackup.c:2590
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "nur Sicherungen im Tar-Modus können komprimiert werden"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "WAL-Streaming ist nicht möglich, wenn ein Backup-Ziel angegeben ist"
+
+#: pg_basebackup.c:2606
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "im Tar-Modus können Write-Ahead-Logs nicht auf Standardausgabe geschrieben werden"
+
+#: pg_basebackup.c:2613
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "Replikations-Slots können nur mit WAL-Streaming verwendet werden"
+
+#: pg_basebackup.c:2625
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot kann nicht zusammen mit einem Slot-Namen verwendet werden"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2636 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "für %s muss ein Slot mit --slot angegeben werden"
+
+#: pg_basebackup.c:2644 pg_basebackup.c:2684 pg_basebackup.c:2695
+#: pg_basebackup.c:2703
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s und %s sind inkompatible Optionen"
+
+#: pg_basebackup.c:2658
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "WAL-Verzeichnis kann nicht zusammen mit einem Backup-Ziel angegeben werden"
+
+#: pg_basebackup.c:2664
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "WAL-Verzeichnis kann nur im »plain«-Modus angegeben werden"
+
+#: pg_basebackup.c:2673
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "WAL-Verzeichnis muss absoluten Pfad haben"
+
+#: pg_basebackup.c:2774
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "konnte symbolische Verknüpfung »%s« nicht erstellen: %m"
+
+#: pg_basebackup.c:2776
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "symbolische Verknüpfungen werden auf dieser Plattform nicht unterstützt"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s empfängt PostgreSQL-Write-Ahead-Logs.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Optionen:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=VERZ Write-Ahead-Log-Dateien in dieses Verzeichnis empfangen\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN nach Empfang der angegebenen LSN beenden\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr " --if-not-exists keinen Fehler ausgeben, wenn Slot beim Erzeugen schon existiert\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop bei Verbindungsverlust nicht erneut probieren\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr ""
+" --no-sync nicht warten, bis Änderungen sicher auf Festplatte\n"
+" geschrieben sind\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SEK\n"
+" Zeit zwischen an Server gesendeten Statuspaketen (Standard: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous Write-Ahead-Log sofort nach dem Schreiben flushen\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=METHODE[:DETAIL]\n"
+" wie angegeben komprimieren\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Optionale Aktionen:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr " --create-slot neuen Replikations-Slot erzeugen (Slot-Name siehe --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr " --drop-slot Replikations-Slot löschen (Slot-Name siehe --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "Segment bei %X/%X abgeschlossen (Zeitleiste %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "Log-Streaming gestoppt bei %X/%X (Zeitleiste %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "auf Zeitleiste %u umgeschaltet bei %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "Interrupt-Signal erhalten, beende"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "konnte Verzeichnis »%s« nicht schließen: %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "Segmentdatei »%s« hat falsche Größe %lld, wird übersprungen"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "konnte komprimierte Datei »%s« nicht öffnen: %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "konnte Positionszeiger in komprimierter Datei »%s« nicht setzen: %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "konnte komprimierte Datei »%s« nicht lesen: %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "konnte Datei »%s« nicht lesen: %d von %zu gelesen"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "komprimierte Segmentdatei »%s« hat falsche unkomprimierte Größe %d, wird übersprungen"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "konnte LZ4-Dekomprimierungskontext nicht erzeugen: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "konnte Datei »%s« nicht lesen: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "konnte Datei »%s« nicht dekomprimieren: %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "konnte LZ4-Dekomprimierungskontext nicht freigeben: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "komprimierte Segmentdatei »%s« hat falsche unkomprimierte Größe %zu, wird übersprungen"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "kann Datei »%s« nicht prüfen: Komprimierung mit %s wird von dieser Installation nicht unterstützt"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "starte Log-Streaming bei %X/%X (Zeitleiste %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "konnte Endposition »%s« nicht parsen"
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "--create-slot kann nicht zusammen mit --drop-slot verwendet werden"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "--synchronous kann nicht zusammen mit --no-sync verwendet werden"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "kein Zielverzeichnis angegeben"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "Komprimierung mit %s wird noch nicht unterstützt"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "Replikationsverbindung, die Slot »%s« verwendet, ist unerwarteterweise datenbankspezifisch"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "lösche Replikations-Slot »%s«"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "erzeuge Replikations-Slot »%s«"
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "Verbindung beendet"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "Verbindung beendet; erneuter Versuch in %d Sekunden"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s kontrolliert logische Dekodierungsströme von PostgreSQL.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Auszuführende Aktion:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr " --start Streaming in einem Replikations-Slot starten (Slot-Name siehe --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=DATEI Log in diese Datei empfangen, - für Standardausgabe\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F --fsync-interval=SEK\n"
+" Zeit zwischen Fsyncs der Ausgabedatei (Standard: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN wo in einem bestehenden Slot das Streaming starten soll\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NAME[=WERT]\n"
+" Option NAME mit optionalem Wert WERT an den\n"
+" Ausgabe-Plugin übergeben\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN Ausgabe-Plugin PLUGIN verwenden (Standard: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOTNAME Name des logischen Replikations-Slots\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr ""
+" -t, --two-phase Dekodieren von vorbereiteten Transaktionen beim Erzeugen\n"
+" eines Slots einschalten\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=DBNAME Datenbank, mit der verbunden werden soll\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "bestätige Schreiben bis %X/%X, Flush bis %X/%X (Slot %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "konnte Rückmeldungspaket nicht senden: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "starte Log-Streaming bei %X/%X (Slot %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "Streaming eingeleitet"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "konnte Logdatei »%s« nicht öffnen: %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "ungültiges Socket: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() fehlgeschlagen: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "konnte keine Daten vom WAL-Stream empfangen: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "Streaming-Header zu klein: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "unbekannter Streaming-Header: »%c«"
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "konnte %d Bytes nicht in Logdatei »%s« schreiben: %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "unerwarteter Abbruch des Replikations-Streams: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "konnte Startposition »%s« nicht parsen"
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "kein Slot angegeben"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "keine Zieldatei angegeben"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "keine Datenbank angegeben"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "mindestens eine Aktion muss angegeben werden"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "--create-slot oder --start kann nicht zusammen mit --drop-slot verwendet werden"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "--create-slot oder --drop-slot kann nicht zusammen mit --startpos verwendet werden"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos kann nur zusammen mit --start angegeben werden"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase kann nur zusammen mit --create-slot angegeben werden"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "konnte keine datenbankspezifische Replikationsverbindung herstellen"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "Endposition %X/%X durch Keepalive erreicht"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "Endposition %X/%X erreicht durch WAL-Eintrag bei %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "konnte Archivstatusdatei »%s« nicht erstellen: %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "konnte Archivstatusdatei »%s« nicht schließen: %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "konnte Größe der Write-Ahead-Log-Datei »%s« nicht ermittlen: %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "konnte bestehende Write-Ahead-Log-Datei »%s« nicht öffnen: %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "konnte bestehende Write-Ahead-Log-Datei »%s« nicht fsyncen: %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "Write-Ahead-Log-Datei »%s« hat %zd Byte, sollte 0 oder %d sein"
+msgstr[1] "Write-Ahead-Log-Datei »%s« hat %zd Bytes, sollte 0 oder %d sein"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "konnte Write-Ahead-Log-Datei »%s« nicht öffnen: %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "konnte Positionszeiger in Datei »%s« nicht ermitteln: %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "»%s« wird nicht umbenannt, Segment ist noch nicht vollständig"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "konnte Datei »%s« nicht schließen: %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "Server berichtete unerwarteten History-Dateinamen für Zeitleiste %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "konnte Zeitleisten-History-Datei »%s« nicht erzeugen: %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "konnte Zeitleisten-History-Datei »%s« nicht schreiben: %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen älter als %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "inkompatible Serverversion %s; Client unterstützt Streaming nicht mit Serverversionen neuer als %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "Systemidentifikator stimmt nicht zwischen Basissicherung und Streaming-Verbindung überein"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "Startzeitleiste %u ist auf dem Server nicht vorhanden"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "unerwartete Antwort auf Befehl TIMELINE_HISTORY: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "Server berichtete unerwartete nächste Zeitleiste %u, folgend auf Zeitleiste %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "Server beendete Streaming von Zeitleiste %u bei %X/%X, aber gab an, dass nächste Zeitleiste %u bei %X/%X beginnt"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "Replikationsstrom wurde vor Stopppunkt abgebrochen"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "unerwartete Ergebnismenge nach Ende der Zeitleiste: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "konnte Startpunkt der nächsten Zeitleiste (»%s«) nicht interpretieren"
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "konnte Datei »%s« nicht fsyncen: %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "Write-Ahead-Log-Eintrag für Offset %u erhalten ohne offene Datei"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "WAL-Daten-Offset %08x erhalten, %08x erwartet"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "konnte %d Bytes nicht in WAL-Datei »%s« schreiben: %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "konnte COPY-Ende-Paket nicht senden: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Passwort: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "konnte nicht mit Server verbinden"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "konnte search_path nicht auf leer setzen: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "konnte Servereinstellung für integer_datetimes nicht ermitteln"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "Kompilieroption »integer_datetimes« stimmt nicht mit Server überein"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "konnte WAL-Segmentgröße nicht ermitteln: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "WAL-Segmentgröße konnte nicht interpretiert werden"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Server gab einen Wert von %d Byte an"
+msgstr[1] "WAL-Segmentgröße muss eine Zweierpotenz zwischen 1 MB und 1 GB sein, aber der Server gab einen Wert von %d Bytes an"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "konnte Gruppenzugriffseinstellung nicht ermitteln: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "Gruppenzugriffseinstellung konnte nicht interpretiert werden: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "Konnte System nicht identifizieren: %d Zeilen und %d Felder erhalten, %d Zeilen und %d oder mehr Felder erwartet"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "konnte Replikations-Slot »%s« nicht lesen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "Replikations-Slot »%s« existiert nicht"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "physischer Replikations-Slot wurde erwartet, stattdessen wurde Typ »%s« erhalten"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "konnte restart_lsn »%s« für Replikations-Slot »%s« nicht parsen"
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "konnte Replikations-Slot »%s« nicht erzeugen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "konnte Replikations-Slot »%s« nicht löschen: %d Zeilen und %d Felder erhalten, %d Zeilen und %d Felder erwartet"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "konnte Daten nicht komprimieren"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "konnte Komprimierungsstrom nicht zurücksetzen"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "Implementierungsfehler: Tar-Dateien können nicht mehr als eine offene Datei haben"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "konnte Tar-Dateikopf nicht erzeugen"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "konnte Komprimierungsparameter nicht ändern"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "Unlink wird bei Komprimierung nicht unterstützt"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "konnte Komprimierungsstrom nicht schließen"
diff --git a/src/bin/pg_basebackup/po/el.po b/src/bin/pg_basebackup/po/el.po
new file mode 100644
index 0000000..f4fd4d6
--- /dev/null
+++ b/src/bin/pg_basebackup/po/el.po
@@ -0,0 +1,1839 @@
+# Greek message translation file for pg_basebackup
+# Copyright (C) 2021 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_basebackup (PostgreSQL) package.
+# Georgios Kokolatos <gkokolatos@pm.me>, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL) 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2023-04-12 16:47+0000\n"
+"PO-Revision-Date: 2023-04-14 10:40+0200\n"
+"Last-Translator: Georgios Kokolatos <gkokolatos@pm.me>\n"
+"Language-Team: \n"
+"Language: el\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 3.2.2\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "σφάλμα: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "προειδοποίηση: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "λεπτομέρεια: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "υπόδειξη: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "η παρούσα κατασκευή δεν υποστηρίζει συμπίεση με %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "βρέθηκε κενή συμβολοσειρά όπου αναμενόταν μια επιλογή συμπίεσης"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "μη αναγνωρίσιμη παράμετρος συμπίεσης: «%s»"
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "η επιλογή συμπίεσης «%s» απαιτεί τιμή"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "η τιμή της επιλογής συμπίεσης «%s» πρέπει να είναι ακέραια"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "ο αλγόριθμος συμπίεσης «%s» δεν δέχεται επίπεδο συμπίεσης"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "ο αλγόριθμος συμπίεσης «%s» αναμένει ένα επίπεδο συμπίεσης μεταξύ %d και %d (προεπιλογμένο %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "ο αλγόριθμος συμπίεσης «%s» δεν δέχεται μέγεθος εργατών"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "έλλειψη μνήμης\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "δεν ήταν δυνατή η αντιγραφή δείκτη null (εσωτερικό σφάλμα)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η εκτέλεση stat στο αρχείο «%s»: %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "δεν ήταν δυνατό το άνοιγμα του καταλόγου «%s»: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "δεν ήταν δυνατή η ανάγνωση του καταλόγου «%s»: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου «%s»: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η εκτέλεση της εντολής fsync στο αρχείο «%s»: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2266 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "δεν ήταν δυνατή η μετονομασία του αρχείου «%s» σε «%s»: %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "μη έγκυρη τιμή «%s» για την επιλογή %s"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s πρέπει να βρίσκεται εντός εύρους %d..%d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1646
+#, c-format
+msgid "out of memory"
+msgstr "έλλειψη μνήμης"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1443 pg_basebackup.c:1737
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η εγγραφή στο αρχείο «%s»: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1507 pg_basebackup.c:1716
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η δημιουργία αρχείου «%s»: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "δεν ήταν δυνατό το κλείσιμο του αρχείου «%s»: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "μη αναμενόμενη κατάσταση κατά την εξαγωγή αρχειοθήκης"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:696 pg_basebackup.c:740
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "δεν ήταν δυνατή η δημιουργία του καταλόγου «%s»: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "δεν ήταν δυνατή η ανάγνωση δικαιωμάτων του καταλόγου «%s»: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "δεν ήταν δυνατή η δημιουργία συμβολικού συνδέσμου από «%s» σε «%s»: %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "δεν ήταν δυνατός ο ορισμός δικαιωμάτων στο αρχείο «%s»: %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η δημιουργία συμπιεσμένου αρχείου «%s»: %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "δεν ήταν δυνατή η αναπαραγωγή τυπικής εξόδου: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "δεν ήταν δυνατό το άνοιγμα αρχείου εξόδου %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "δεν ήταν δυνατή η ρύθμιση επιπέδου συμπίεσης %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "η παρούσα κατασκευή δεν υποστηρίζει συμπίεση gzip"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η εγγραφή σε συμπιεσμένο αρχείο «%s»: %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "δεν ήταν δυνατό το κλείσιμο του συμπιεσμένου αρχείου «%s»: %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "δεν ήταν δυνατή η αρχικοποίηση της βιβλιοθήκης συμπίεσης"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "δεν ήταν δυνατή η αποσυμπίεση δεδομένων: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "απροσδόκητη κατάσταση κατά την έγχυση ρυθμίσεων αποκατάστασης"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "δεν ήταν δυνατή η δημιουργία lz4 περιεχομένου συμπίεσης: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "η παρούσα κατασκευή δεν υποστηρίζει συμπίεση lz4"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "δεν ήταν δυνατή η εγγραφή κεφαλίδας lz4: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "δεν ήταν δυνατή η συμπίεση δεδομένων: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "δεν ήταν δυνατός ο τερματισμός συμπίεσης lz4: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "δεν ήταν δυνατή η αρχικοποίηση της βιβλιοθήκης συμπίεσης: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "το αρχείο tar υπερβαίνει τα 2 μπλοκ"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "μη αναμενόμενη κατάσταση κατά την ανάλυση αρχειοθήκης tar"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "το μέλος tar έχει κενό όνομα"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "η ροή COPY τερματίστηκε πριν ολοκληρωθεί το τελευταίο αρχείο"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "δεν ήταν δυνατή η δημιουργία zstd περιεχομένου συμπίεσης"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "δεν ήταν δυνατή η ρύθμιση επιπέδου συμπίεσης zstd σε %d: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "δεν ήταν δυνατή η ρύθμιση αριθμού εργατών συμπίεσης %d: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "η παρούσα κατασκευή δεν υποστηρίζει συμπίεση zstd"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "δεν ήταν δυνατή η δημιουργία zstd περιεχομένου αποσυμπίεσης"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "αφαιρείται ο κατάλογος δεδομένων «%s»"
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "απέτυχε η αφαίρεση καταλόγου δεδομένων"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "αφαιρούνται περιεχόμενα του καταλόγου δεδομένων «%s»"
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "απέτυχε η αφαίρεση περιεχομένων του καταλόγου δεδομένων"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "αφαίρεση καταλόγου WAL «%s»"
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "απέτυχε η αφαίρεση καταλόγου WAL"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "αφαιρούνται τα περιεχόμενα του καταλόγου WAL «%s»"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "απέτυχε η αφαίρεση περιεχόμενων του καταλόγου WAL"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "ο κατάλογος δεδομένων «%s» δεν αφαιρείται κατα απαίτηση του χρήστη"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "κατάλογος WAL «%s» δεν αφαιρέθηκε κατά απαίτηση του χρήστη"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "οι αλλαγές στους καταλόγους πινακοχώρων δεν θα αναιρεθούν"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "πολύ μακρύ όνομα καταλόγου"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "πολλαπλά σύμβολα \"=\" στην αντιστοίχιση πινακοχώρου"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "μη έγκυρη μορφή αντιστοίχισης πινακοχώρου «%s», πρέπει να είναι «OLDDIR=NEWDIR»"
+
+#: pg_basebackup.c:361
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "ο παλιός κατάλογος δεν είναι απόλυτη διαδρομή στην αντιστοίχιση πινακοχώρου: %s"
+
+#: pg_basebackup.c:365
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "ο νέος κατάλογος δεν είναι μια απόλυτη διαδρομή στην αντιστοίχιση πινακοχώρου: %s"
+
+#: pg_basebackup.c:387
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s λαμβάνει ένα αντίγραφο ασφαλείας βάσης ενός διακομιστή PostgreSQL που εκτελείται.\n"
+"\n"
+
+#: pg_basebackup.c:389 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Χρήση:\n"
+
+#: pg_basebackup.c:390 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [ΕΠΙΛΟΓΗ]...\n"
+
+#: pg_basebackup.c:391
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Επιλογές που ελέγχουν το περιεχόμενο εξόδου:\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=DIRECTORY λάβε το αντίγραφο ασφαλείας βάσης στον κατάλογο\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t μορφή εξόδου (απλή (προεπιλογή), tar)\n"
+
+#: pg_basebackup.c:394
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=RATE μέγιστος ρυθμός μεταφοράς για τη μεταφορά καταλόγου δεδομένων\n"
+" (σε kB/s, ή χρησιμοποιήστε το επίθημα «k» ή «M»)\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" εγγραφή των ρυθμίσεων αναπαραγωγής\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=TARGET[:DETAIL]\n"
+" προορισμός αντιγράφων ασφαλείας (εάν είναι άλλος από τον πελάτη)\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" μετακίνησε τον πινακοχώρο από OLDDIR σε NEWDIR\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=WALDIR τοποθεσία για τον κατάλογο write-ahead log\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" περιέλαβε τα απαιτούμενα αρχεία WAL με την ορισμένη μέθοδο\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip συμπίεσε την έξοδο tar\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" συμπίεσε στον πελάτη ή στον διακομιστή όπως ορίζεται\n"
+
+#: pg_basebackup.c:408
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr ""
+" -Z, --compress=none να μην συμπιέσει την έξοδο tar\n"
+"\n"
+
+#: pg_basebackup.c:409
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Γενικές επιλογές:\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" όρισε fast ή spread λειτουργία λήψης σημείων ελέγχου\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot δημιούργησε υποδοχή αναπαραγωγής\n"
+
+#: pg_basebackup.c:413
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL όρισε ετικέτα αντιγράφου ασφαλείας\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean να μην καθαριστούν σφάλματα\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " -N, --no-sync να μην αναμένει την ασφαλή εγγραφή αλλαγών στον δίσκο\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress εμφάνισε πληροφορίες προόδου\n"
+
+#: pg_basebackup.c:417 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=SLOTNAME υποδοχή αναπαραγωγής για χρήση\n"
+
+#: pg_basebackup.c:418 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose περιφραστικά μηνύματα εξόδου\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n"
+
+#: pg_basebackup.c:420
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" χρησιμοποίησε αυτόν τον αλγόριθμο για τα αθροίσματα ελέγχου διακήρυξης\n"
+
+#: pg_basebackup.c:422
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" χρήση δεκαεξαδικής κωδικοποίησης για όλα\n"
+" τα ονόματα αρχείων στη διακήρυξη\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size να μην εκτιμήσει το μέγεθος του αντιγράφου ασφαλείας στην πλευρά του διακομιστή\n"
+
+#: pg_basebackup.c:425
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest κατάστειλε τη δημιουργία της διακήρυξης αντιγράφων ασφαλείας\n"
+
+#: pg_basebackup.c:426
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot εμπόδισε την δημιουργία προσωρινής υποδοχής αναπαραγωγής\n"
+
+#: pg_basebackup.c:427
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" να μην επιβεβαιώσει τα αθροίσματα ελέγχου\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help εμφάνισε αυτό το μήνυμα βοήθειας, μετά έξοδος\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Επιλογές σύνδεσης:\n"
+
+#: pg_basebackup.c:431 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONNSTR συμβολοσειρά σύνδεσης\n"
+
+#: pg_basebackup.c:432 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=HOSTNAME διακομιστής βάσης δεδομένων ή κατάλογος υποδοχών\n"
+
+#: pg_basebackup.c:433 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT θύρα διακομιστή βάσης δεδομένων\n"
+
+#: pg_basebackup.c:434
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVAL\n"
+" χρόνος μεταξύ αποστολής πακέτων κατάστασης στον διακομιστή (σε δευτερόλεπτα)\n"
+
+#: pg_basebackup.c:436 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NAME σύνδεση ως ο ορισμένος χρήστης βάσης δεδομένων\n"
+
+#: pg_basebackup.c:437 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password να μην ζητείται ποτέ κωδικός πρόσβασης\n"
+
+#: pg_basebackup.c:438 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr " -W, --password αναγκαστική προτροπή κωδικού πρόσβασης (πρέπει να συμβεί αυτόματα)\n"
+
+#: pg_basebackup.c:439 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Υποβάλετε αναφορές σφάλματων σε <%s>.\n"
+
+#: pg_basebackup.c:440 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s αρχική σελίδα: <%s>\n"
+
+#: pg_basebackup.c:482
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "δεν ήταν δυνατή η ανάγνωση από έτοιμη pipe: %m"
+
+#: pg_basebackup.c:485 pg_basebackup.c:632 pg_basebackup.c:2180
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "δεν ήταν δυνατή η ανάλυση της τοποθεσίας write-ahead log «%s»"
+
+#: pg_basebackup.c:591 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "δεν ήταν δυνατός ο τερματισμός εγγραφής αρχείων WAL: %m"
+
+#: pg_basebackup.c:641
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "δεν ήταν δυνατή η δημιουργία pipe για διεργασίες παρασκηνίου : %m"
+
+#: pg_basebackup.c:674
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "δημιουργήθηκε προσωρινή υποδοχή αναπαραγωγής «%s»"
+
+#: pg_basebackup.c:677
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "δημιουργήθηκε υποδοχή αναπαραγωγής «%s»"
+
+#: pg_basebackup.c:711
+#, c-format
+msgid "could not create background process: %m"
+msgstr "δεν ήταν δυνατή η δημιουργία διαδικασίας παρασκηνίου: %m"
+
+#: pg_basebackup.c:720
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "δεν ήταν δυνατή η δημιουργία νήματος παρασκηνίου: %m"
+
+#: pg_basebackup.c:759
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "ο κατάλογος «%s» υπάρχει και δεν είναι άδειος"
+
+#: pg_basebackup.c:765
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "δεν ήταν δυνατή η πρόσβαση του καταλόγου «%s»: %m"
+
+#: pg_basebackup.c:842
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d πινακοχώρος %*s"
+msgstr[1] "%*s/%s kB (100%%), %d/%d πινακοχώροι %*s"
+
+#: pg_basebackup.c:854
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d πινακοχώρος (%s%-*.*s)"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d πινακοχώροι (%s%-*.*s)"
+
+#: pg_basebackup.c:870
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d πινακοχώρος"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d πινακοχώροι"
+
+#: pg_basebackup.c:894
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "η τιμή ρυθμού μεταφοράς «%s» δεν είναι έγκυρη"
+
+#: pg_basebackup.c:896
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "μη έγκυρος ρυθμός μεταφοράς «%s»: %m"
+
+#: pg_basebackup.c:903
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "ο ρυθμός μεταφοράς πρέπει να είναι μεγαλύτερος από μηδέν"
+
+#: pg_basebackup.c:933
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "μη έγκυρη μονάδα --max-rate: «%s»"
+
+#: pg_basebackup.c:937
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "ο ρυθμός μεταφοράς «%s» υπερβαίνει το εύρος ακεραίων"
+
+#: pg_basebackup.c:944
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "ο ρυθμός μεταφοράς «%s» βρίσκεται εκτός εύρους τιμών"
+
+#: pg_basebackup.c:1040
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "δεν ήταν δυνατή η λήψη ροής δεδομένων COPY: %s"
+
+#: pg_basebackup.c:1057 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "δεν ήταν δυνατή η ανάγνωση δεδομένων COPY: %s"
+
+#: pg_basebackup.c:1061
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "διεργασία παρασκηνίου τερματίστηκε απρόσμενα"
+
+#: pg_basebackup.c:1132
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "δεν είναι δυνατή η έγχυση διακύρηξης σε συμπιεσμένο αρχείο tarfile"
+
+#: pg_basebackup.c:1133
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "Χρησιμοποιήστε συμπίεση από την πλευρά του πελάτη, στείλτε την έξοδο σε έναν κατάλογο αντί για την τυπική έξοδο, ή χρησιμοποιήστε %s."
+
+#: pg_basebackup.c:1149
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "δεν ήταν δυνατή η ανάλυση αρχειοθήκης «%s»"
+
+#: pg_basebackup.c:1150
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Μόνο οι αρχειοθήκες tar μπορούν να συμπιεστούν."
+
+#: pg_basebackup.c:1152
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Η απλή μορφή απαιτεί pg_basebackup για την ανάλυση του αρχείου."
+
+#: pg_basebackup.c:1154
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "Η χρήση του - ως καταλόγου εξόδου απαιτεί την ανάλυση του αρχείου από το pg_basebackup."
+
+#: pg_basebackup.c:1156
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "Η επιλογή -R απαιτεί pg_basebackup για την ανάλυση του αρχείου."
+
+#: pg_basebackup.c:1367
+#, c-format
+msgid "archives must precede manifest"
+msgstr "τα αρχεία πρέπει να προηγούνται του μανιφέστου"
+
+#: pg_basebackup.c:1382
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "άκυρη ονομασία αρχειοθήκης «%s»"
+
+#: pg_basebackup.c:1454
+#, c-format
+msgid "unexpected payload data"
+msgstr "μη αναμενόμενα δεδομένα φορτίου"
+
+#: pg_basebackup.c:1597
+#, c-format
+msgid "empty COPY message"
+msgstr "κενό μήνυμα COPY"
+
+#: pg_basebackup.c:1599
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "κακοσχηματισμένο μήνυμα COPY τύπου %d, μήκους %zu"
+
+#: pg_basebackup.c:1797
+#, c-format
+msgid "incompatible server version %s"
+msgstr "μη συμβατή έκδοση διακομιστή %s"
+
+#: pg_basebackup.c:1813
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Χρησιμοποίησε -X none ή -X fetch για την απενεργοποίηση της ροής καταγραφής."
+
+#: pg_basebackup.c:1881
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "οι στόχοι αντιγράφων ασφαλείας δεν υποστηρίζονται από αυτήν την έκδοση διακομιστή"
+
+#: pg_basebackup.c:1884
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "δεν είναι δυνατή η σύνταξη αρχείου ρυθμίσεων αποκατάστασης όταν χρησιμοποιείται προορισμός αντιγράφων ασφαλείας"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "ο διακομιστής δεν υποστηρίζει συμπίεση από την πλευρά του διακομιστή"
+
+#: pg_basebackup.c:1921
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "έναρξη δημιουργίας αντιγράφων ασφαλείας βάσης, αναμονή ολοκλήρωσης του σημείου ελέγχου"
+
+#: pg_basebackup.c:1925
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "αναμονή για το σημείο ελέγχου"
+
+#: pg_basebackup.c:1938 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "δεν ήταν δυνατή η αποστολή εντολής αναπαραγωγής «%s»: %s"
+
+#: pg_basebackup.c:1946
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "δεν ήταν δυνατή η έναρξη αντιγράφου ασφαλείας βάσης: %s"
+
+#: pg_basebackup.c:1949
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "ο διακομιστής επέστρεψε μη αναμενόμενη απόκριση στην εντολή BASE_BACKUP· έλαβε %d σειρές και %d πεδία, ανέμενε %d σειρές και %d πεδία"
+
+#: pg_basebackup.c:1955
+#, c-format
+msgid "checkpoint completed"
+msgstr "ολοκληρώθηκε το σημείο ελέγχου"
+
+#: pg_basebackup.c:1970
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "σημείο εκκίνησης write-ahead: %s στην χρονογραμμή %u"
+
+#: pg_basebackup.c:1978
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "δεν ήταν δυνατή η απόκτηση κεφαλίδας αντιγράφου ασφαλείας: %s"
+
+#: pg_basebackup.c:1981
+#, c-format
+msgid "no data returned from server"
+msgstr "δεν επιστράφηκαν δεδομένα από τον διακομιστή"
+
+#: pg_basebackup.c:2016
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "μπορεί να γράψει μόνο έναν πινακοχώρο στην τυπική έξοδο, η βάση δεδομένων διαθέτει %d"
+
+#: pg_basebackup.c:2029
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "εκκίνηση λήψης WAL στο παρασκήνιο"
+
+#: pg_basebackup.c:2111
+#, c-format
+msgid "backup failed: %s"
+msgstr "η δημιουργία αντιγράφων ασφαλείας απέτυχε: %s"
+
+#: pg_basebackup.c:2114
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "δεν επιστράφηκε τελική θέση write-ahead log από τον διακομιστή"
+
+#: pg_basebackup.c:2117
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "τελικό σημείο write-ahead log: %s"
+
+#: pg_basebackup.c:2128
+#, c-format
+msgid "checksum error occurred"
+msgstr "προέκυψε σφάλμα αθροίσματος ελέγχου"
+
+#: pg_basebackup.c:2133
+#, c-format
+msgid "final receive failed: %s"
+msgstr "απέτυχε η τελική λήψη: %s"
+
+#: pg_basebackup.c:2157
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "αναμένει τη διαδικασία παρασκηνίου να ολοκληρώσει τη ροή ..."
+
+#: pg_basebackup.c:2161
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "δεν ήταν δυνατή η αποστολή της εντολής σε pipe παρασκηνίου: %m"
+
+#: pg_basebackup.c:2166
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "δεν ήταν δυνατή η αναμονή απογονικής διεργασίας: %m"
+
+#: pg_basebackup.c:2168
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "απόγονος %d πέθανε, ανέμενε %d"
+
+#: pg_basebackup.c:2170 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2190
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "δεν ήταν δυνατή η αναμονή απογονικού νήματος: %m"
+
+#: pg_basebackup.c:2195
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "δεν ήταν δυνατή η απόκτηση κατάστασης εξόδου απογονικού νήματος: %m"
+
+#: pg_basebackup.c:2198
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "το απογονικό νήμα εξήλθε με σφάλμα %u"
+
+#: pg_basebackup.c:2227
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "συγχρονίζονται δεδομένα στο δίσκο …"
+
+#: pg_basebackup.c:2252
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "μετονομάζει backup_manifest.tmp σε backup_manifest"
+
+#: pg_basebackup.c:2272
+#, c-format
+msgid "base backup completed"
+msgstr "ολοκληρώθηκε το αντίγραφο ασφαλείας βάσης"
+
+#: pg_basebackup.c:2361
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "μη έγκυρη μορφή εξόδου «%s», πρέπει να είναι «plain» ή «tar»"
+
+#: pg_basebackup.c:2405
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "μη έγκυρη επιλογή μεθόδου wal «%s», πρέπει να είναι «fetch», «stream», ή «none»"
+
+#: pg_basebackup.c:2435
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "μη έγκυρη παράμετρος σημείου ελέγχου «%s», πρέπει να είναι «fast» ή «spread»"
+
+#: pg_basebackup.c:2486 pg_basebackup.c:2498 pg_basebackup.c:2520
+#: pg_basebackup.c:2532 pg_basebackup.c:2538 pg_basebackup.c:2590
+#: pg_basebackup.c:2601 pg_basebackup.c:2611 pg_basebackup.c:2617
+#: pg_basebackup.c:2624 pg_basebackup.c:2636 pg_basebackup.c:2648
+#: pg_basebackup.c:2656 pg_basebackup.c:2669 pg_basebackup.c:2675
+#: pg_basebackup.c:2684 pg_basebackup.c:2696 pg_basebackup.c:2707
+#: pg_basebackup.c:2715 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Δοκιμάστε «%s --help» για περισσότερες πληροφορίες."
+
+#: pg_basebackup.c:2496 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "πάρα πολλές παράμετροι εισόδου από την γραμμή εντολών (η πρώτη είναι η «%s»)"
+
+#: pg_basebackup.c:2519
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "δεν είναι δυνατός ο καθορισμός τόσο ενός ονόματος βάσης δεδομένων όσο και στόχου αντιγράφων ασφαλείας"
+
+#: pg_basebackup.c:2531
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "πρέπει να καθορίσετε τον κατάλογο εξόδου ή το στόχο δημιουργίας αντιγράφων ασφαλείας"
+
+#: pg_basebackup.c:2537
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "δεν είναι δυνατός ο καθορισμός τόσο του καταλόγου εξόδου όσο και του προορισμού αντιγράφων ασφαλείας"
+
+#: pg_basebackup.c:2567 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "μη αναγνωρίσιμος αλγόριθμος συμπίεσης: «%s»"
+
+#: pg_basebackup.c:2573 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "μη έγκυρη προδιαγραφή συμπίεσης: %s"
+
+#: pg_basebackup.c:2589
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "η συμπίεση από την πλευρά του πελάτη δεν είναι δυνατή όταν έχει καθοριστεί ένας στόχος δημιουργίας αντιγράφων ασφαλείας"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "μόνο τα αντίγραφα ασφαλείας tar μπορούν να συμπιεστούν"
+
+#: pg_basebackup.c:2610
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "δεν είναι δυνατή η ροή WAL όταν καθορίζεται στόχος αντιγράφου ασφαλείας"
+
+#: pg_basebackup.c:2616
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "δεν είναι δυνατή η ροή write-ahead logs σε λειτουργία tar στην τυπική έξοδο"
+
+#: pg_basebackup.c:2623
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "οι υποδοχές αναπαραγωγής μπορούν να χρησιμοποιηθούν μόνο με ροή WAL"
+
+#: pg_basebackup.c:2635
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot δεν μπορεί να χρησιμοποιηθεί σε συνδυασμό με όνομα υποδοχής"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2646 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s χρειάζεται να έχει οριστεί μία υποδοχή με --slot"
+
+#: pg_basebackup.c:2654 pg_basebackup.c:2694 pg_basebackup.c:2705
+#: pg_basebackup.c:2713
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s και %s αποτελούν μη συμβατές επιλογές"
+
+#: pg_basebackup.c:2668
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "η τοποθεσία του καταλόγου WAL δεν μπορεί να καθοριστεί μαζί με στόχο αντιγράφου ασφαλείας"
+
+#: pg_basebackup.c:2674
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "η τοποθεσία του καταλόγου WAL μπορεί να καθοριστεί μόνο σε λειτουργία plain"
+
+#: pg_basebackup.c:2683
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "η τοποθεσία του καταλόγου WAL πρέπει να είναι μία πλήρης διαδρομή"
+
+#: pg_basebackup.c:2784
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "δεν ήταν δυνατή η δημιουργία του συμβολικού συνδέσμου «%s»: %m"
+
+#: pg_basebackup.c:2786
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "συμβολικοί σύνδεσμοι δεν υποστηρίζονται στην παρούσα πλατφόρμα"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s λαμβάνει ροές PostgreSQL write-ahead logs.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Επιλογές:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=DIR να λάβει αρχεία write-ahead log files into this directory\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN έξοδος μετά τη λήψη του καθορισμένου LSN\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr " --if-not-exists μην θεωρηθεί ώς σφάλμα η ήδη ύπαρξη υποδοχής κατά τη δημιουργία μιας υποδοχής\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop να μην εισέλθει σε βρόχο κατά την απώλεια σύνδεσης\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " --no-sync να μην αναμένει την ασφαλή εγγραφή αλλαγών στον δίσκο\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SECS\n"
+" χρόνος μεταξύ πακέτων κατάστασης που αποστέλλονται στο διακομιστή (προεπιλογή: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous flush write-ahead log αμέσως μετά τη γραφή\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" συμπίεσε όπως ορίζεται\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Προαιρετικές δράσεις:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr " --create-slot δημιούργησε μια νέα υποδοχή αναπαραγωγής (για το όνομα της υποδοχής, δείτε --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr " --drop-slot εγκατάληψη της υποδοχής αναπαραγωγής (για το όνομα της υποδοχής δείτε --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "τελείωσε το τμήμα σε %X/%X (χρονογραμμή %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "διακοπή ροής αρχείων καταγραφής σε %X/%X (χρονογραμμή %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "μεταπήδησε στη χρονογραμμή %u στο %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "λήψη σήματος διακοπής, έξοδος"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "δεν ήταν δυνατό το κλείσιμο του καταλόγου «%s»: %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "το αρχείο τμήματος «%s» έχει εσφαλμένο μέγεθος %lld, θα παραληφθεί"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "δεν ήταν δυνατό το άνοιγμα του συμπιεσμένου αρχείου «%s»: %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η αναζήτηση στο συμπιεσμένο αρχείο «%s»: %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η ανάγνωση του συμπιεσμένου αρχείου «%s»: %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "δεν ήταν δυνατή η ανάγνωση του συμπιεσμένου αρχείου «%s»: ανέγνωσε %d από %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "συμπιεσμένο αρχείο τμήματος «%s» έχει εσφαλμένο μη συμπιεσμένο μέγεθος %d, θα παραληφθεί"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "δεν ήταν δυνατή η δημιουργία LZ4 περιεχομένου αποσυμπίεσης: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η ανάγνωση του αρχείου «%s»: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η αποσυμπιέση αρχείου «%s»: %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "δεν ήταν δυνατή η απελευθέρωση LZ4 περιεχομένου αποσυμπίεσης: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "συμπιεσμένο αρχείο τμήματος «%s» έχει εσφαλμένο μη συμπιεσμένο μέγεθος %zu, θα παραληφθεί"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "δεν είναι δυνατός ο έλεγχος του αρχείου «%s»: η συμπίεση με %s δεν υποστηρίζεται από αυτήν την κατασκευή"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "έναρξη ροής αρχείων καταγραφής σε %X/%X (χρονογραμμή %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "δεν ήταν δυνατή η ανάλυση της τελικής τοποθεσίας «%s»"
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "δεν είναι δυνατή η χρήση --create-slot σε συνδυασμό με --drop-slot"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "δεν είναι δυνατή η χρήση --synchronous σε συνδυασμό με --no-sync"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "δεν καθορίστηκε κατάλογος δεδομένων προορισμού"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "η συμπίεση με %s δεν υποστηρίζεται ακόμα"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "η σύνδεση αναπαραγωγής χρησιμοποιώντας την υποδοχή «%s» είναι απροσδόκητα συνυφασμένη με βάση δεδομένων"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "κατάργηση υποδοχής αναπαραγωγής «%s»"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "δημιουργία υποδοχής αναπαραγωγής «%s»"
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "αποσυνδέθηκε"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "αποσυνδέθηκε· αναμένει %d δεύτερα για να προσπαθήσει ξανά"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s ελέγχει ροές λογικής αποκωδικοποίησης PostgreSQL.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Δράση που θα πραγματοποιηθεί:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr " --start εκκίνηση ροής σε μια υποδοχή αναπαραγωγής (για το όνομα της υποδοχής δείτε --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=FILE λάβε το log σε αυτό το αρείο, - για τυπική έξοδο\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F --fsync-interval=SECS\n"
+" χρόνος μεταξύ fsyncs του αρχείου εξόδου (προεπιλογή: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN από πού θα ξεκινήσει η ροή σε μια υπάρχουσα υποδοχή\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NAME[=VALUE]\n"
+" πέρασε την επιλογή NAME με προαιρετική τιμή VALUE στο\n"
+" plugin εξόδου\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN χρησιμοποίησε το plugin εξόδου PLUGIN (προεπιλογή: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOTNAME όνομα της λογικής υποδοχής αναπαραγωγής\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase ενεργοποιήσε την αποκωδικοποίηση των προετοιμασμένων συναλλαγών κατά τη δημιουργία μιας υποδοχής\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=DBNAME βάση δεδομένων για να συνδεθεί\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "επιβεβαίωση εγγραφής έως %X/%X, flush σε %X/%X (υποδοχή %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "δεν ήταν δυνατή η αποστολή πακέτου σχολίων: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "έναρξη ροής αρχείων καταγραφής σε %X/%X (υποδοχή %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "έναρξη ροής"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου καταγραφής «%s»: %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "άκυρος υποδοχέας: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() απέτυχε: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "δεν ήταν δυνατή η λήψη δεδομένων από τη ροή WAL: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "πολύ μικρή κεφαλίδα ροής: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "μη αναγνωρίσιμη κεφαλίδα ροής: «%c»"
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η εγγραφή %d bytes στο αρχείο καταγραφής «%s»: %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "μη αναμενόμενος τερματισμός της ροής αναπαραγωγής: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "δεν ήταν δυνατή η ανάλυση της θέσης έναρξης «%s»"
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "δεν καθορίστηκε υποδοχή"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "δεν καθορίστηκε αρχείο προορισμού"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "δεν καθορίστηκε βάση δεδομένων"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "πρέπει να οριστεί τουλάχιστον μία πράξη"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "δεν είναι δυνατή η χρήση --create-slot ή --start σε συνδυασμό με --drop-slot"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "δεν είναι δυνατή η χρήση --create-slot ή --start σε συνδυασμό με --startpos"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos μπορεί να καθοριστεί μόνο με --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase μπορεί να καθοριστεί μόνο με --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "δεν ήταν δυνατή η δημιουργία σύνδεσης αναπαραγωγής συγκεκριμένης βάσης δεδομένων"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "τελική θέση %X/%X που επιτεύχθηκε από keepalive"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "τελική θέση %X/%X που επιτεύχθηκε από εγγραφή WAL στο %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η δημιουργία αρχείου κατάστασης αρχειοθήκης «%s»: %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "δεν ήταν δυνατό το κλείσιμο αρχείου κατάστασης αρχειοθήκης «%s»: %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η απόκτηση μεγέθους του υπάρχοντος αρχείου write-ahead log «%s»: %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "δεν ήταν δυνατό το άνοιγμα του υπάρχοντος αρχείου write-ahead log «%s»: %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "δεν ήταν δυνατό το fsync του υπάρχοντος αρχείου write-ahead log «%s»: %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "το αρχείο write-ahead log «%s» έχει %zd byte, θα έπρεπε να είναι 0 ή %d"
+msgstr[1] "το αρχείο write-ahead log «%s» έχει %zd bytes, θα έπρεπε να είναι 0 ή %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "δεν ήταν δυνατό το άνοιγμα του αρχείου write-ahead log «%s»: %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "δεν ήταν δυνατός ο προσδιορισμός της θέσης αναζήτησης στο αρχείο «%s»: %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "δεν μετονομάζει «%s», το τμήμα δεν είναι πλήρες"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "δεν ήταν δυνατό το κλείσιμο του αρχείου «%s»: %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "ο διακομιστής ανέφερε μη αναμενόμενο όνομα αρχείου ιστορικού για την χρονογραμμή %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η δημιουργία αρχείου ιστορικού χρονογραμμής «%s»: %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η εγγραφή αρχείου ιστορικού χρονογραμμής «%s»: %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "μη συμβατή έκδοση διακομιστή %s· Ο πελάτης δεν υποστηρίζει ροή από εκδόσεις διακομιστών παλαιότερες από %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "μη συμβατή έκδοση διακομιστή %s· Ο πελάτης δεν υποστηρίζει ροή από εκδόσεις διακομιστών νεότερες από %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "το αναγνωριστικό συστήματος δεν αντιστοιχεί μεταξύ βασικού αντιγράφου ασφαλείας και σύνδεσης ροής"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "η χρονογραμμή εκκίνησης %u δεν υπάρχει στο διακομιστή"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "μη αναμενόμενη απόκριση στην εντολή TIMELINE_HISTORY: έλαβε %d σειρές και %d πεδία, ανέμενε %d σειρές και %d πεδία"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "ο διακομιστής ανέφερε απροσδόκητη επόμενη χρονογραμμή %u, ακολουθώντας τη χρονογραμμή %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "ο διακομιστής σταμάτησε τη ροή χρονογραμμής %u στο %X/%X, αλλά ανέφερε ότι η επόμενη χρονογραμμή %u να ξεκινήσει από το %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "η ροή αναπαραγωγής τερματίστηκε πριν από το σημείο διακοπής"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "μη αναμενόμενο σύνολο αποτελεσμάτων μετά το τέλος της χρονογραμμής: έλαβε %d σειρές και %d πεδία, ανέμενε %d σειρές και %d πεδία"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "δεν ήταν δυνατή η ανάλυση του σημείου εκκίνησης «%s» της επόμενης χρονογραμμής"
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η εκτέλεση της εντολής fsync στο αρχείο «%s»: %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "έλαβε εγγραφή write-ahead log για μετατόπιση %u χωρίς ανοικτό αρχείου"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "έλαβε μετατόπιση δεδομένων WAL %08x, ανέμενε %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "δεν ήταν δυνατή η εγγραφή %d bytes στο αρχείο WAL «%s»: %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "δεν ήταν δυνατή η αποστολή πακέτου copy-end: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Κωδικός πρόσβασης: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "δεν ήταν δυνατή η σύνδεση με το διακομιστή"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "δεν ήταν δυνατή η εκκαθάριση του search_path: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "δεν ήταν δυνατός ο προσδιορισμός της ρύθμισης διακομιστή για integer_datetimes"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "η επισήμανση μεταγλώττισης integer_datetimes δεν συμφωνεί με το διακομιστή"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "δεν ήταν δυνατή η λήψη μεγέθους τμήματος WAL: %d σειρές και %d πεδία, ανέμενε %d σειρές και %d ή περισσότερα πεδία"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "δεν ήταν δυνατή η ανάλυση του μεγέθους του τμήματος WAL"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "το μέγεθος τμήματος WAL πρέπει να έχει τιμή δύναμη του δύο μεταξύ 1 MB και 1 GB, αλλά ο απομακρυσμένος διακομιστής ανέφερε τιμή %d byte"
+msgstr[1] "το μέγεθος τμήματος WAL πρέπει να έχει τιμή δύναμη του δύο μεταξύ 1 MB και 1 GB, αλλά ο απομακρυσμένος διακομιστής ανέφερε τιμή %d bytes"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "δεν ήταν δυνατή η λήψη επισήμανσης πρόσβασης group: %d σειρές και %d πεδία, ανέμενε %d σειρές και %d ή περισσότερα πεδία"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "δεν ήταν δυνατή η ανάλυση της σημαίας πρόσβασης γκρουπ: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "δεν ήταν δυνατή η αναγνώριση του συστήματος: έλαβε %d σειρές και %d πεδία, ανέμενε %d σειρές και %d ή περισσότερα πεδία"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "δεν ήταν δυνατή η ανάγνωση της υποδοχής αναπαραγωγής «%s»: έλαβε %d σειρές και %d πεδία, ανέμενε %d σειρές και %d πεδία"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "η υποδοχή αναπαραγωγής «%s» δεν υπάρχει"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "αναμένεται μια φυσική υποδοχή αναπαραγωγής, πήρε τον τύπο «%s» αντ 'αυτού"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "δεν ήταν δυνατή η ανάλυση restart_lsn «%s» για την υποδοχή αναπαραγωγής «%s»"
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "δεν ήταν δυνατή η δημιουργία της υποδοχής αναπαραγωγής «%s»: %d σειρές και %d πεδία, ανέμενε %d σειρές και %d πεδία"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "δεν ήταν δυνατή η κατάργηση της υποδοχής αναπαραγωγής «%s»: έλαβε %d σειρές και %d πεδία, ανέμενε %d σειρές και %d πεδία"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "δεν ήταν δυνατή η συμπίεση δεδομένων"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "δεν ήταν δυνατή η επαναφορά της ροής συμπίεσης"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "σφάλμα υλοποίησης: τα αρχεία tar δεν μπορούν να έχουν περισσότερα από ένα ανοιχτά αρχεία"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "δεν ήταν δυνατή η δημιουργία κεφαλίδας tar"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "δεν ήταν δυνατή η αλλαγή παραμέτρων συμπίεσης"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "το unlink δεν υποστηρίζεται με συμπίεση"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "δεν ήταν δυνατό το κλείσιμο της ροής συμπίεσης"
+
+#~ msgid " -Z, --compress=0-9 compress logs with given compression level\n"
+#~ msgstr " -Z, --compress=0-9 συμπίεσε logs με το ορισμένο επίπεδο συμπίεσης\n"
+
+#~ msgid " -Z, --compress=0-9 compress tar output with given compression level\n"
+#~ msgstr " -Z, --compress=0-9 συμπίεσε την έξοδο tar με το ορισμένο επίπεδο συμπίεσης\n"
+
+#~ msgid "could not get write-ahead log end position from server: %s"
+#~ msgstr "δεν ήταν δυνατή η απόκτηση τελικής θέσης write-ahead log από τον διακομιστή: %s"
+
+#~ msgid "fatal: "
+#~ msgstr "κρίσιμο: "
+
+#~ msgid "invalid compression level \"%s\""
+#~ msgstr "μη έγκυρο επίπεδο συμπίεσης «%s»"
+
+#~ msgid "invalid fsync interval \"%s\""
+#~ msgstr "μη έγκυρο διάστημα FSYNC «%s»"
+
+#~ msgid "invalid port number \"%s\""
+#~ msgstr "μη έγκυρος αριθμός πύλης: «%s»"
+
+#~ msgid "invalid status interval \"%s\""
+#~ msgstr "μη έγκυρο διάστημα status «%s»"
+
+#~ msgid "invalid tar block header size: %zu"
+#~ msgstr "μη έγκυρο μέγεθος κεφαλίδας μπλοκ tar: %zu"
+
+#~ msgid "unrecognized link indicator \"%c\""
+#~ msgstr "μη αναγνωρίσιμος δείκτης σύνδεσης «%c»"
diff --git a/src/bin/pg_basebackup/po/es.po b/src/bin/pg_basebackup/po/es.po
new file mode 100644
index 0000000..1be3250
--- /dev/null
+++ b/src/bin/pg_basebackup/po/es.po
@@ -0,0 +1,1813 @@
+# Spanish message translation file for pg_basebackup
+#
+# Copyright (c) 2011-2021, PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+#
+# Álvaro Herrera <alvherre@alvh.no-ip.org>, 2011-2014.
+# Carlos Chapi <carlos.chapi@2ndquadrant.com>, 2017, 2021.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL) 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2023-05-07 16:48+0000\n"
+"PO-Revision-Date: 2022-10-20 09:06+0200\n"
+"Last-Translator: Carlos Chapi <carloswaldo@babelruins.org>\n"
+"Language-Team: PgSQL-es-Ayuda <pgsql-es-ayuda@lists.postgresql.org>\n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: BlackCAT 1.1\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "error: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "precaución: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "detalle: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "consejo: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "esta instalación no soporta compresión con %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "se encontró una cadena vacía donde se esperaba una opción de compresión"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "opción de compresión no reconocida: «%s»"
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "la opción de compresión «%s» requiere un valor"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "el valor para la opción de compresión «%s» debe ser un entero"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "el algoritmo de compresión «%s» no acepta un nivel de compresión"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "el algoritmo de compresión «%s» espera un nivel de compresión entre %d y %d (por omisión %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "el algoritmo de compresión «%s» no acepta una cantidad de procesos ayudantes"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "memoria agotada\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "no se puede duplicar un puntero nulo (error interno)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "no se pudo hacer stat al archivo «%s»: %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "no se pudo abrir el directorio «%s»: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "no se pudo leer el directorio «%s»: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "no se pudo abrir el archivo «%s»: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "no se pudo sincronizar (fsync) archivo «%s»: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2266 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "no se pudo renombrar el archivo de «%s» a «%s»: %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "el valor «%s» no es válido para la opción «%s»"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s debe estar en el rango %d..%d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1646
+#, c-format
+msgid "out of memory"
+msgstr "memoria agotada"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1443 pg_basebackup.c:1737
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "no se pudo escribir a archivo «%s»: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1507 pg_basebackup.c:1716
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "no se pudo crear archivo «%s»: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "no se pudo cerrar el archivo «%s»: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "estado inesperado mientras se extraía el archivo"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:696 pg_basebackup.c:740
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "no se pudo crear el directorio «%s»: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "no se pudo definir los permisos del directorio «%s»: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "no se pudo crear un enlace simbólico desde «%s» a «%s»: %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "no se pudo definir los permisos al archivo «%s»: %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "no se pudo crear el archivo comprimido «%s»: %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "no se pudo duplicar stdout: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "no se pudo abrir el archivo de salida: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "no se pudo definir el nivel de compresión %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "esta instalación no soporta compresión gzip"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "no se pudo escribir al archivo comprimido «%s»: %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "no se pudo cerrar el archivo comprimido «%s»: %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "no se pudo inicializar la biblioteca de compresión"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "no se pudo descomprimir datos: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "formato de resultados inesperado mientras se inyectaban los parámetros de recuperación"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "no se pudo crear un contexto de compresión lz4: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "esta instalación no soporta compresión lz4"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "no se pudo escribir la cabecera lz4: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "no se pudo comprimir datos: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "no se pudo terminar la compresión lz4: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "no se pudo inicializar la biblioteca de compresión: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "la terminación del archivo tar excede de 2 bloques"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "se encontró un estado inesperado mientras se interpretaba el archivo tar"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "miembro de tar tiene nombre vacío"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "el flujo COPY terminó antes que el último archivo estuviera completo"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "no se pudo restablecer el contexto de compresión zstd"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "no se pudo definir el nivel de compresión zstd a %d: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "no se pudo definir la cantidad de procesos ayudantes de compresión a %d: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "esta instalación no soporta compresión zstd"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "no se pudo crear el contexto de descompresión zstd"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "eliminando el directorio de datos «%s»"
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "no se pudo eliminar el directorio de datos"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "eliminando el contenido del directorio «%s»"
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "no se pudo eliminar el contenido del directorio de datos"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "eliminando el directorio de WAL «%s»"
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "no se pudo eliminar el directorio de WAL"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "eliminando el contenido del directorio de WAL «%s»"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "no se pudo eliminar el contenido del directorio de WAL"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "directorio de datos «%s» no eliminado a petición del usuario"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "directorio de WAL «%s» no eliminado a petición del usuario"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "los cambios a los directorios de tablespaces no se desharán"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "nombre de directorio demasiado largo"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "múltiples signos «=» en mapeo de tablespace"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "formato de mapeo de tablespace «%s» no válido, debe ser «ANTIGUO=NUEVO»"
+
+#: pg_basebackup.c:361
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "directorio antiguo no es una ruta absoluta en mapeo de tablespace: %s"
+
+#: pg_basebackup.c:365
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "directorio nuevo no es una ruta absoluta en mapeo de tablespace: %s"
+
+#: pg_basebackup.c:387
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s obtiene un respaldo base a partir de un servidor PostgreSQL en ejecución.\n"
+"\n"
+
+#: pg_basebackup.c:389 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Empleo:\n"
+
+#: pg_basebackup.c:390 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [OPCIÓN]...\n"
+
+#: pg_basebackup.c:391
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Opciones que controlan la salida:\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=DIR directorio en el cual recibir el respaldo base\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t formato de salida (plano (por omisión), tar)\n"
+
+#: pg_basebackup.c:394
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=TASA máxima tasa a la que transferir el directorio de datos\n"
+" (en kB/s, o use sufijos «k» o «M»)\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" escribe configuración para replicación\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=DESTINO:[DETALLE]\n"
+" destino del respaldo base (si no es el cliente)\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=ANTIGUO=NUEVO\n"
+" reubicar el directorio de tablespace de ANTIGUO a NUEVO\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=DIRWAL ubicación para el directorio WAL\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" incluye los archivos WAL necesarios,\n"
+" en el modo especificado\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip comprimir la salida de tar\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]MÉTODO[:DETALLE]\n"
+" comprimir en cliente o servidor como se especifica\n"
+
+#: pg_basebackup.c:408
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none no comprimir la salida tar\n"
+
+#: pg_basebackup.c:409
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Opciones generales:\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" utilizar checkpoint rápido o extendido\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot crear un slot de replicación\n"
+
+#: pg_basebackup.c:413
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=ETIQUETA establecer etiqueta del respaldo\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean no hacer limpieza tras errores\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " -N, --no-sync no esperar que los cambios se sincronicen a disco\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress mostrar información de progreso\n"
+
+#: pg_basebackup.c:417 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=NOMBRE slot de replicación a usar\n"
+
+#: pg_basebackup.c:418 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose desplegar mensajes verbosos\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version mostrar información de versión, luego salir\n"
+
+#: pg_basebackup.c:420
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" usar algoritmo para sumas de comprobación del manifiesto\n"
+
+#: pg_basebackup.c:422
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" codifica a hexadecimal todos los nombres de archivo en el manifiesto\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size no estimar el tamaño del la copia de seguridad en el lado del servidor\n"
+
+#: pg_basebackup.c:425
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest suprimir la generación del manifiesto de la copia de seguridad\n"
+
+#: pg_basebackup.c:426
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot evitar la creación de un slot de replicación temporal\n"
+
+#: pg_basebackup.c:427
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" no verificar checksums\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help mostrar esta ayuda, luego salir\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Opciones de conexión:\n"
+
+#: pg_basebackup.c:431 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONSTR cadena de conexión\n"
+
+#: pg_basebackup.c:432 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=ANFITRIÓN dirección del servidor o directorio del socket\n"
+
+#: pg_basebackup.c:433 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT número de port del servidor\n"
+
+#: pg_basebackup.c:434
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVALO (segundos)\n"
+" tiempo entre envíos de paquetes de estado al servidor\n"
+
+#: pg_basebackup.c:436 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NOMBRE conectarse con el usuario especificado\n"
+
+#: pg_basebackup.c:437 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password nunca pedir contraseña\n"
+
+#: pg_basebackup.c:438 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr ""
+" -W, --password forzar un prompt para la contraseña\n"
+" (debería ser automático)\n"
+
+#: pg_basebackup.c:439 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Reporte errores a <%s>.\n"
+
+#: pg_basebackup.c:440 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Sitio web de %s: <%s>\n"
+
+#: pg_basebackup.c:482
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "no se pudo leer desde la tubería: %m"
+
+#: pg_basebackup.c:485 pg_basebackup.c:632 pg_basebackup.c:2180
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "no se pudo interpretar la ubicación del WAL «%s»"
+
+#: pg_basebackup.c:591 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "no se pudo completar la escritura de archivos WAL: %m"
+
+#: pg_basebackup.c:641
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "no se pudo crear la tubería para el proceso en segundo plano: %m"
+
+#: pg_basebackup.c:674
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "se creó slot temporal de replicación «%s»"
+
+#: pg_basebackup.c:677
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "se creó el slot de replicación «%s»"
+
+#: pg_basebackup.c:711
+#, c-format
+msgid "could not create background process: %m"
+msgstr "no se pudo lanzar el proceso en segundo plano: %m"
+
+#: pg_basebackup.c:720
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "no se pudo lanzar el hilo en segundo plano: %m"
+
+#: pg_basebackup.c:759
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "el directorio «%s» existe pero no está vacío"
+
+#: pg_basebackup.c:765
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "no se pudo acceder al directorio «%s»: %m"
+
+#: pg_basebackup.c:842
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgstr[1] "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+
+#: pg_basebackup.c:854
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+
+#: pg_basebackup.c:870
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespaces"
+
+#: pg_basebackup.c:894
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "tasa de transferencia «%s» no es un valor válido"
+
+#: pg_basebackup.c:896
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "tasa de transferencia «%s» no válida: %m"
+
+#: pg_basebackup.c:903
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "tasa de transferencia debe ser mayor que cero"
+
+#: pg_basebackup.c:933
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "unidad de --max-rato no válida: «%s»"
+
+#: pg_basebackup.c:937
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "la tasa de transferencia «%s» excede el rango de enteros"
+
+#: pg_basebackup.c:944
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "la tasa de transferencia «%s» está fuera de rango"
+
+#: pg_basebackup.c:1040
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "no se pudo obtener un flujo de datos COPY: %s"
+
+#: pg_basebackup.c:1057 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "no fue posible leer datos COPY: %s"
+
+#: pg_basebackup.c:1061
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "un proceso en segundo plano terminó inesperadamente"
+
+#: pg_basebackup.c:1132
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "no se pueden inyectar un manifiesto en un archivo tar comprimido"
+
+#: pg_basebackup.c:1133
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "Use compresión del lado del cliente, envíe la salida a un directorio en lugar de a salida estándar, o use %s."
+
+#: pg_basebackup.c:1149
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "no se pudo interpretar el archivo «%s»"
+
+#: pg_basebackup.c:1150
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Sólo los archivos tar pueden ser interpretados."
+
+#: pg_basebackup.c:1152
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "El formato plano requiere que pg_basebackup interprete el archivo."
+
+#: pg_basebackup.c:1154
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "Usar - como directorio de salida requiere que pg_basebackup interprete el archivo."
+
+#: pg_basebackup.c:1156
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "La opción -R requiere que pg_basebackup interprete el archivo."
+
+#: pg_basebackup.c:1367
+#, c-format
+msgid "archives must precede manifest"
+msgstr "los archivos deben preceder al manifiesto"
+
+#: pg_basebackup.c:1382
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "nombre de archivo no válido: «%s»"
+
+#: pg_basebackup.c:1454
+#, c-format
+msgid "unexpected payload data"
+msgstr "datos inesperados"
+
+#: pg_basebackup.c:1597
+#, c-format
+msgid "empty COPY message"
+msgstr "mensaje COPY vacío"
+
+#: pg_basebackup.c:1599
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "mensaje COPY mal formado de tipo %d, largo %zu"
+
+#: pg_basebackup.c:1797
+#, c-format
+msgid "incompatible server version %s"
+msgstr "versión del servidor %s incompatible"
+
+#: pg_basebackup.c:1813
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Use -X none o -X fetch para deshabilitar el flujo de log."
+
+#: pg_basebackup.c:1881
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "los destinos de respaldo no están soportados por esta versión de servidor"
+
+#: pg_basebackup.c:1884
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "la configuración de recuperación no puede ser escrita cuando se usa un destino de respaldo base"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "el servidor no soporta compresión del lado del servidor"
+
+#: pg_basebackup.c:1921
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "iniciando el respaldo base, esperando que el checkpoint se complete"
+
+#: pg_basebackup.c:1925
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "esperando al checkpoint"
+
+#: pg_basebackup.c:1938 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "no se pudo ejecutar la orden de replicación «%s»: %s"
+
+#: pg_basebackup.c:1946
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "no se pudo iniciar el respaldo base: %s"
+
+#: pg_basebackup.c:1949
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "el servidor envió una respuesta inesperada a la orden BASE_BACKUP; se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos"
+
+#: pg_basebackup.c:1955
+#, c-format
+msgid "checkpoint completed"
+msgstr "el checkpoint se ha completado"
+
+#: pg_basebackup.c:1970
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "punto de inicio del WAL: %s en el timeline %u"
+
+#: pg_basebackup.c:1978
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "no se pudo obtener la cabecera de respaldo: %s"
+
+#: pg_basebackup.c:1981
+#, c-format
+msgid "no data returned from server"
+msgstr "el servidor no retornó datos"
+
+#: pg_basebackup.c:2016
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "sólo se puede escribir un tablespace a stdout, la base de datos tiene %d"
+
+#: pg_basebackup.c:2029
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "iniciando el receptor de WAL en segundo plano"
+
+#: pg_basebackup.c:2111
+#, c-format
+msgid "backup failed: %s"
+msgstr "el respaldo falló: %s"
+
+#: pg_basebackup.c:2114
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "el servidor no retornó la posición final del WAL"
+
+#: pg_basebackup.c:2117
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "posición final del WAL: %s"
+
+#: pg_basebackup.c:2128
+#, c-format
+msgid "checksum error occurred"
+msgstr "ocurrió un error de checksums"
+
+#: pg_basebackup.c:2133
+#, c-format
+msgid "final receive failed: %s"
+msgstr "la recepción final falló: %s"
+
+#: pg_basebackup.c:2157
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "esperando que el proceso en segundo plano complete el flujo..."
+
+#: pg_basebackup.c:2161
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "no se pudo enviar una orden a la tubería de segundo plano: %m"
+
+#: pg_basebackup.c:2166
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "no se pudo esperar al proceso hijo: %m"
+
+#: pg_basebackup.c:2168
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "el hijo %d murió, pero se esperaba al %d"
+
+#: pg_basebackup.c:2170 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2190
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "no se pudo esperar el hilo hijo: %m"
+
+#: pg_basebackup.c:2195
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "no se pudo obtener la cabecera de respaldo: %m"
+
+#: pg_basebackup.c:2198
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "el hilo hijo terminó con error %u"
+
+#: pg_basebackup.c:2227
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "sincronizando datos a disco ..."
+
+#: pg_basebackup.c:2252
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "renombrando backup_manifest.tmp a backup_manifest"
+
+#: pg_basebackup.c:2272
+#, c-format
+msgid "base backup completed"
+msgstr "el respaldo base se ha completado"
+
+#: pg_basebackup.c:2361
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "formato de salida «%s» no válido, debe ser «plain» o «tar»"
+
+#: pg_basebackup.c:2405
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "opción de wal-method «%s» no válida, debe ser «fetch», «stream» o «none»"
+
+#: pg_basebackup.c:2435
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "argumento de checkpoint «%s» no válido, debe ser «fast» o «spread»"
+
+#: pg_basebackup.c:2486 pg_basebackup.c:2498 pg_basebackup.c:2520
+#: pg_basebackup.c:2532 pg_basebackup.c:2538 pg_basebackup.c:2590
+#: pg_basebackup.c:2601 pg_basebackup.c:2611 pg_basebackup.c:2617
+#: pg_basebackup.c:2624 pg_basebackup.c:2636 pg_basebackup.c:2648
+#: pg_basebackup.c:2656 pg_basebackup.c:2669 pg_basebackup.c:2675
+#: pg_basebackup.c:2684 pg_basebackup.c:2696 pg_basebackup.c:2707
+#: pg_basebackup.c:2715 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Pruebe «%s --help» para mayor información."
+
+#: pg_basebackup.c:2496 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "demasiados argumentos en la línea de órdenes (el primero es «%s»)"
+
+#: pg_basebackup.c:2519
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "no se puede especificar un formato junto con un destino de respaldo"
+
+#: pg_basebackup.c:2531
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "debe especificar un directorio de salida o destino de respaldo base"
+
+#: pg_basebackup.c:2537
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "no se puede especificar un directorio de salida junto con un destino de respaldo"
+
+#: pg_basebackup.c:2567 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "algoritmo de compresión no reconocido: «%s»"
+
+#: pg_basebackup.c:2573 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "especificación de compresión no válida: %s"
+
+#: pg_basebackup.c:2589
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "la compresión del lado del cliente no es posible cuando se especifica un destino del respaldo base"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "sólo los respaldos de modo tar pueden ser comprimidos"
+
+#: pg_basebackup.c:2610
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "no se puede enviar WAL cuando se especifica un destino del respaldo base"
+
+#: pg_basebackup.c:2616
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "no se puede enviar WALs en modo tar a stdout"
+
+#: pg_basebackup.c:2623
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "los slots de replicación sólo pueden usarse con flujo de WAL"
+
+#: pg_basebackup.c:2635
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "no se puede usar --no-slot junto con nombre de slot"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2646 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "la opcón %s necesita que se especifique un slot con --slot"
+
+#: pg_basebackup.c:2654 pg_basebackup.c:2694 pg_basebackup.c:2705
+#: pg_basebackup.c:2713
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s y %s son opciones incompatibles"
+
+#: pg_basebackup.c:2668
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "la ubicación del directorio de WAL no puede especificarse junto con un destino de respaldo"
+
+#: pg_basebackup.c:2674
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "la ubicación del directorio de WAL sólo puede especificarse en modo «plain»"
+
+#: pg_basebackup.c:2683
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "la ubicación del directorio de WAL debe ser una ruta absoluta"
+
+#: pg_basebackup.c:2784
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "no se pudo crear el enlace simbólico «%s»: %m"
+
+#: pg_basebackup.c:2786
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "los enlaces simbólicos no están soportados en esta plataforma"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s recibe flujos del WAL de PostgreSQL.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opciones:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=DIR recibir los archivos de WAL en este directorio\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN salir luego de recibir el LSN especificado\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr " --if-not-exists no abandonar si el slot ya existe al crear un slot\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop no entrar en bucle al perder la conexión\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " --no-sync no esperar que los cambios se sincronicen a disco\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SECS\n"
+" tiempo entre envíos de paquetes de estado al servidor\n"
+" (por omisión: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous sincronizar el WAL inmediatamente después de escribir\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=MÉTODO[:DETALLE]\n"
+" comprimir como se indica\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Acciones optativas:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr " --create-slot crear un nuevo slot de replicación (para el nombre, vea --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr " --drop-slot eliminar un slot de replicación (para el nombre, vea --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "terminó el segmento en %X/%X (timeline %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "detenido el flujo de log en %X/%X (timeline %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "cambiado al timeline %u en %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "se recibió una señal de interrupción, saliendo"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "no se pudo abrir el directorio «%s»: %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %lld, ignorando"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "no se pudo abrir el archivo comprimido «%s»: %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "no se pudo buscar en el archivo comprimido «%s»: %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "no se pudo leer el archivo comprimido «%s»: %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "no se pudo leer el archivo comprimido «%s»: leídos %d de %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %d al descomprimirse, ignorando"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "no se pudo crear un contexto de descompresión LZ4: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "no se pudo leer el archivo «%s»: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "no se pudo descomprimir el archivo «%s»: %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "no se pudo liberar el contexto de descompresión LZ4: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "el archivo de segmento «%s» tiene tamaño incorrecto %zu al descomprimirse, ignorando"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "no se puede verificar el archivo «%s»: la compresión con %s no está soportada en este servidor"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "iniciando el flujo de log en %X/%X (timeline %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "no se pudo interpretar la posición final «%s»"
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "no puede usarse --create-slot junto con --drop-slot"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "no puede usarse --synchronous junto con --no-sync"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "no se especificó un directorio de salida"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "el método de compresión %s no está soportado aún"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "la conexión de replicación usando el slot «%s» es inesperadamente específica a una base de datos"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "eliminando el slot de replicación «%s»"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "creando el slot de replicación «%s»"
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "desconectado"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "desconectado; esperando %d segundos para intentar nuevamente"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s controla flujos de decodificación lógica de PostgreSQL.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Acciones a ejecutar:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr " --start iniciar flujo en un slot de replicación (para el nombre, vea --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=ARCHIVO recibir el log en este archivo, - para stdout\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F, --fsync-interval=SEGS\n"
+" tiempo entre fsyncs del archivo de salida (omisión: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN dónde en un slot existente debe empezar el flujo\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NOMBRE[=VALOR]\n"
+" pasar opción NOMBRE con valor opcional VALOR al\n"
+" plugin de salida\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN usar plug-in de salida PLUGIN (omisión: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=NOMBRE-SLOT nombre del slot de replicación lógica\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase activa decodificación de transacciones preparadas al crear un slot\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=BASE base de datos a la cual conectarse\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "confirmando escritura hasta %X/%X, fsync hasta %X/%X (slot %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "no se pudo enviar el paquete de retroalimentación: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "iniciando el flujo de log en %X/%X (slot %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "flujo iniciado"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "no se pudo abrir el archivo de registro «%s»: %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "el socket no es válido: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() falló: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "no se pudo recibir datos desde el flujo de WAL: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "cabecera de flujo demasiado pequeña: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "cabecera de flujo no reconocida: «%c»"
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "no se pudo escribir %d bytes al archivo de registro «%s»: %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "término inesperado del flujo de replicación: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "no se pudo interpretar la posición de inicio «%s»"
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "no se especificó slot"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "no se especificó un archivo de destino"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "no se especificó una base de datos"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "debe especificarse al menos una operación"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "no puede usarse --create-slot o --start junto con --drop-slot"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "no puede usarse --create-slot o --drop-slot junto con --startpos"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos sólo se puede utilizar con --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase sólo se puede utilizar con --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "no se pudo establecer una conexión de replicación específica a una base de datos"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "ubicación de término %X/%X alcanzado por «keep-alive»"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "ubicación de término %X/%X alcanzado por registro WAL en %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "no se pudo crear el archivo de estado «%s»: %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "no se pudo cerrar el archivo de estado «%s»: %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "no se pudo obtener el tamaño del archivo de WAL «%s»: %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "no se pudo abrir el archivo de WAL «%s»: %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "no se pudo sincronizar (fsync) el archivo de WAL «%s»: %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "el archivo de WAL «%s» mide %zd byte, debería ser 0 o %d"
+msgstr[1] "el archivo de WAL «%s» mide %zd bytes, debería ser 0 o %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "no se pudo abrir archivo de WAL «%s»: %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "no se pudo determinar la posición (seek) en el archivo «%s»: %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "no se cambiará el nombre a «%s», el segmento no está completo"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "no se pudo cerrar el archivo «%s»: %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "el servidor reportó un nombre inesperado para el archivo de historia de timeline %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "no se pudo crear el archivo de historia de timeline «%s»: %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "no se pudo escribir al archivo de historia de timeline «%s»: %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "versión de servidor %s incompatible; el cliente no soporta flujos de servidores anteriores a la versión %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "versión de servidor %s incompatible; el cliente no soporta flujos de servidores posteriores a %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "el identificador de sistema no coincide entre el respaldo base y la conexión de flujo"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "el timeline de inicio %u no está presente en el servidor"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "respuesta inesperada a la orden TIMELINE_HISTORY: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "el servidor reportó un timeline siguiente %u inesperado, a continuación del timeline %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "el servidor paró la transmisión del timeline %u en %X/%X, pero reportó que el siguiente timeline %u comienza en %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "el flujo de replicación terminó antes del punto de término"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "respuesta inesperada después del fin-de-timeline: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "no se pudo interpretar el punto de inicio del siguiente timeline «%s»"
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "no se pudo sincronizar (fsync) archivo «%s»: %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "se recibió un registro de WAL para el desplazamiento %u sin ningún archivo abierto"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "se obtuvo desplazamiento de datos WAL %08x, se esperaba %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "no se pudo escribir %d bytes al archivo WAL «%s»: %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "no se pudo enviar el paquete copy-end: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Contraseña: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "no se pudo conectar al servidor"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "no se pudo limpiar search_path: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "no se pudo determinar la opción integer_datetimes del servidor"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "la opción de compilación integer_datetimes no coincide con el servidor"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "no se pudo obtener el tamaño del segmento de WAL: se obtuvo %d filas y %d campos, se esperaban %d filas y %d o más campos"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "el tamaño de segmento de WAL no pudo ser analizado"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "el tamaño de segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el servidor remoto reportó un valor de %d byte"
+msgstr[1] "el tamaño de segmento de WAL debe ser una potencia de dos entre 1 MB y 1 GB, pero el servidor remoto reportó un valor de %d bytes"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "no se pudo obtener el indicador de acceso de grupo: se obtuvo %d filas y %d campos, se esperaban %d filas y %d o más campos"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "el indicador de acceso de grupo no pudo ser analizado: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "no se pudo identificar al sistema: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d o más campos"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "no se pudo leer el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "no existe el slot de replicación «%s»"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "se esperaba un slot de replicación físico, en cambio se obtuvo tipo «%s»"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "no se pudo interpretar restart_lsn de WAL «%s» para el slot de replicación «%s»"
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "no se pudo create el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "no se pudo eliminar el slot de replicación «%s»: se obtuvieron %d filas y %d campos, se esperaban %d filas y %d campos"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "no se pudo comprimir datos"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "no se pudo restablecer el flujo comprimido"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "error de implementación: los archivos tar no pueden tener abierto más de un fichero"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "no se pudo crear la cabecera del archivo tar"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "no se pudo cambiar los parámetros de compresión"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "unlink no soportado con compresión"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "no se pudo cerrar el flujo comprimido"
diff --git a/src/bin/pg_basebackup/po/fr.po b/src/bin/pg_basebackup/po/fr.po
new file mode 100644
index 0000000..f8be071
--- /dev/null
+++ b/src/bin/pg_basebackup/po/fr.po
@@ -0,0 +1,2197 @@
+# LANGUAGE message translation file for pg_basebackup
+# Copyright (C) 2011-2022 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_basebackup (PostgreSQL) package.
+#
+# Use these quotes: « %s »
+#
+# Guillaume Lelarge <guillaume@lelarge.info>, 2011-2022.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PostgreSQL 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-09-26 08:18+0000\n"
+"PO-Revision-Date: 2022-09-26 14:09+0200\n"
+"Last-Translator: Guillaume Lelarge <guillaume@lelarge.info>\n"
+"Language-Team: French <guillaume@lelarge.info>\n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Poedit 3.1.1\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "erreur : "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "attention : "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "détail : "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "astuce : "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "cette construction ne supporte pas la compression avec %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "a trouvé une chaîne vide alors qu'une option de compression était attendue"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "option de compression inconnue : « %s »"
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "l'option de compression « %s » requiert une valeur"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "la valeur pour l'option de compression « %s » doit être un entier"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "l'algorithme de compression « %s » n'accepte pas un niveau de compression"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "l'algorithme de compression « %s » attend un niveau de compression compris entre %d et %d (par défaut à %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "l'algorithme de compression « %s » n'accepte pas un nombre de workers"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "mémoire épuisée\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "ne peut pas dupliquer un pointeur nul (erreur interne)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "n'a pas pu tester le fichier « %s » : %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "n'a pas pu ouvrir le répertoire « %s » : %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "n'a pas pu lire le répertoire « %s » : %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "n'a pas pu ouvrir le fichier « %s » : %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2256 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "n'a pas pu renommer le fichier « %s » en « %s » : %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "valeur « %s » invalide pour l'option %s"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s doit être compris entre %d et %d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1636
+#, c-format
+msgid "out of memory"
+msgstr "mémoire épuisée"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1433 pg_basebackup.c:1727
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "n'a pas pu écrire dans le fichier « %s » : %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1497 pg_basebackup.c:1706
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "n'a pas pu créer le fichier « %s » : %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "n'a pas pu fermer le fichier « %s » : %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "état inattendu lors de l'extraction de l'archive"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:686 pg_basebackup.c:730
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "n'a pas pu créer le répertoire « %s » : %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "n'a pas pu configurer les droits du répertoire « %s » : %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "n'a pas pu créer le lien symbolique de « %s » vers « %s » : %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "n'a pas pu initialiser les droits du fichier « %s » : %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "n'a pas pu créer le fichier compressé « %s » : %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "n'a pas pu dupliquer la sortie (stdout) : %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "n'a pas pu ouvrir le fichier de sauvegarde : %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "n'a pas pu configurer le niveau de compression %d : %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "cette construction ne supporte pas la compression gzip"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "n'a pas pu écrire dans le fichier compressé « %s » : %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "n'a pas pu fermer le fichier compressé « %s » : %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "n'a pas pu initialiser la bibliothèque de compression"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "n'a pas pu décompresser les données : %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "état inattendu lors de l'injection des paramètres de restauration"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "n'a pas pu créer le contexte de compression lz4 : %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "cette construction ne supporte pas la compression lz4"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "n'a pas pu écrire l'entête lz4 : %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "n'a pas pu compresser les données : %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "n'a pas pu terminer la compression lz4 : %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "n'a pas pu initialiser la bibliothèque de compression : %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "la fin du fichier tar fait plus de 2 blocs"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "état inattendu lors de l'analyse de l'archive tar"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "le membre de tar a un nom vide"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "le flux COPY s'est terminé avant que le dernier fichier soit terminé"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "n'a pas pu créer le contexte de compression zstd"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "n'a pas pu configurer le niveau de compression zstd à %d : %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "n'a pas pu configurer le nombre de workers de compression à %d : %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "cette construction ne supporte pas la compression zstd"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "n'a pas pu créer le contexte de décompression zstd"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "suppression du répertoire des données « %s »"
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "échec de la suppression du répertoire des données"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "suppression du contenu du répertoire des données « %s »"
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "échec de la suppression du contenu du répertoire des données"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "suppression du répertoire des journaux de transactions « %s »"
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "échec de la suppression du répertoire des journaux de transactions"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "suppression du contenu du répertoire des journaux de transactions « %s »"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "échec de la suppression du contenu du répertoire des journaux de transactions"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "répertoire des données « %s » non supprimé à la demande de l'utilisateur"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "les modifications des répertoires des tablespaces ne seront pas annulées"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "nom du répertoire trop long"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "multiple signes « = » dans la correspondance de tablespace"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "format de correspondance de tablespace « %s » invalide, doit être « ANCIENREPERTOIRE=NOUVEAUREPERTOIRE »"
+
+#: pg_basebackup.c:351
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "l'ancien répertoire n'est pas un chemin absolu dans la correspondance de tablespace : %s"
+
+#: pg_basebackup.c:355
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "le nouveau répertoire n'est pas un chemin absolu dans la correspondance de tablespace : %s"
+
+#: pg_basebackup.c:377
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s prend une sauvegarde binaire d'un serveur PostgreSQL en cours\n"
+"d'exécution.\n"
+"\n"
+
+#: pg_basebackup.c:379 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Usage :\n"
+
+#: pg_basebackup.c:380 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [OPTION]...\n"
+
+#: pg_basebackup.c:381
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Options contrôlant la sortie :\n"
+
+#: pg_basebackup.c:382
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=RÉPERTOIRE reçoit la sauvegarde de base dans ce répertoire\n"
+
+#: pg_basebackup.c:383
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t format en sortie (plain (par défaut), tar)\n"
+
+#: pg_basebackup.c:384
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=TAUX taux maximum de transfert du répertoire de\n"
+" données (en Ko/s, ou utiliser le suffixe « k »\n"
+" ou « M »)\n"
+
+#: pg_basebackup.c:386
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr " -R, --write-recovery-conf écrit la configuration pour la réplication\n"
+
+#: pg_basebackup.c:388
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr " -t, --target=CIBLE[:DETAIL] cible de sauvegarde (si autre que client)\n"
+
+#: pg_basebackup.c:390
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=ANCIENREP=NOUVEAUREP\n"
+" déplace le répertoire ANCIENREP en NOUVEAUREP\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr ""
+" --waldir=RÉP_WAL emplacement du répertoire des journaux de\n"
+" transactions\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" inclut les journaux de transactions requis avec\n"
+" la méthode spécifiée\n"
+
+#: pg_basebackup.c:395
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip compresse la sortie tar\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METHODE[:DETAIL]\n"
+" compresse sur le client ou le serveur comme indiqué\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none ne compresse pas la sortie tar\n"
+
+#: pg_basebackup.c:399
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Options générales :\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr " -c, --checkpoint=fast|spread exécute un CHECKPOINT rapide ou réparti\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " --create-slot crée un slot de réplication\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL configure le label de sauvegarde\n"
+
+#: pg_basebackup.c:404
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean ne nettoie pas en cas d'erreur\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr ""
+" -N, --no-sync n'attend pas que les modifications soient\n"
+" proprement écrites sur disque\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress affiche la progression de la sauvegarde\n"
+
+#: pg_basebackup.c:407 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=NOMREP slot de réplication à utiliser\n"
+
+#: pg_basebackup.c:408 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose affiche des messages verbeux\n"
+
+#: pg_basebackup.c:409 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version affiche la version puis quitte\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" utilise cet algorithme pour les sommes de\n"
+" contrôle du manifeste\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode encode tous les noms de fichier dans le\n"
+" manifeste en hexadécimal\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr ""
+" --no-estimate-size ne réalise pas d'estimation sur la taille de la\n"
+" sauvegarde côté serveur\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr ""
+" --no-manifest supprime la génération de manifeste de\n"
+" sauvegarde\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr ""
+" --no-slot empêche la création de slots de réplication\n"
+" temporaires\n"
+
+#: pg_basebackup.c:417
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr " --no-verify-checksums ne vérifie pas les sommes de contrôle\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help affiche cette aide puis quitte\n"
+
+#: pg_basebackup.c:420 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Options de connexion :\n"
+
+#: pg_basebackup.c:421 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CHAÎNE_CONNEX chaîne de connexion\n"
+
+#: pg_basebackup.c:422 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr ""
+" -h, --host=HÔTE hôte du serveur de bases de données ou\n"
+" répertoire des sockets\n"
+
+#: pg_basebackup.c:423 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT numéro de port du serveur de bases de données\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVAL durée entre l'envoi de paquets de statut au\n"
+" serveur (en secondes)\n"
+
+#: pg_basebackup.c:426 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=UTILISATEUR se connecte avec cet utilisateur\n"
+
+#: pg_basebackup.c:427 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password ne demande jamais le mot de passe\n"
+
+#: pg_basebackup.c:428 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr ""
+" -W, --password force la demande du mot de passe (devrait\n"
+" survenir automatiquement)\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Rapporter les bogues à <%s>.\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Page d'accueil de %s : <%s>\n"
+
+#: pg_basebackup.c:472
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "n'a pas pu lire à partir du tube : %m"
+
+#: pg_basebackup.c:475 pg_basebackup.c:622 pg_basebackup.c:2170
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "n'a pas pu analyser l'emplacement du journal des transactions « %s »"
+
+#: pg_basebackup.c:581 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "n'a pas pu finir l'écriture dans les fichiers de transactions : %m"
+
+#: pg_basebackup.c:631
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "n'a pas pu créer un tube pour le processus en tâche de fond : %m"
+
+#: pg_basebackup.c:664
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "a créé le slot de réplication temporaire « %s »"
+
+#: pg_basebackup.c:667
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "a créé le slot de réplication « %s »"
+
+#: pg_basebackup.c:701
+#, c-format
+msgid "could not create background process: %m"
+msgstr "n'a pas pu créer un processus en tâche de fond : %m"
+
+#: pg_basebackup.c:710
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "n'a pas pu créer un thread en tâche de fond : %m"
+
+#: pg_basebackup.c:749
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "le répertoire « %s » existe mais n'est pas vide"
+
+#: pg_basebackup.c:755
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "n'a pas pu accéder au répertoire « %s » : %m"
+
+#: pg_basebackup.c:832
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s Ko (100%%), %d/%d tablespace %*s"
+msgstr[1] "%*s/%s Ko (100%%), %d/%d tablespaces %*s"
+
+#: pg_basebackup.c:844
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s Ko (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgstr[1] "%*s/%s Ko (%d%%), %d/%d tablespaces (%s%-*.*s)"
+
+#: pg_basebackup.c:860
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s Ko (%d%%), %d/%d tablespace"
+msgstr[1] "%*s/%s Ko (%d%%), %d/%d tablespaces"
+
+#: pg_basebackup.c:884
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "le taux de transfert « %s » ne correspond pas à une valeur valide"
+
+#: pg_basebackup.c:886
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "taux de transfert invalide (« %s ») : %m"
+
+#: pg_basebackup.c:893
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "le taux de transfert doit être supérieur à zéro"
+
+#: pg_basebackup.c:923
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "unité invalide pour --max-rate : « %s »"
+
+#: pg_basebackup.c:927
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "le taux de transfert « %s » dépasse l'échelle des entiers"
+
+#: pg_basebackup.c:934
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "le taux de transfert « %s » est en dehors des limites"
+
+#: pg_basebackup.c:1030
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "n'a pas pu obtenir le flux de données de COPY : %s"
+
+#: pg_basebackup.c:1047 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "n'a pas pu lire les données du COPY : %s"
+
+#: pg_basebackup.c:1051
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "un processus worker s'est arrêté de façon inattendue"
+
+#: pg_basebackup.c:1122
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "ne peut pas injecter le manifeste dans un fichier tar compressé"
+
+#: pg_basebackup.c:1123
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "Utilisez la compression côté client, envoyez la sortie dans un répertoire plutôt que sur la sortie standard, ou utilisez %s."
+
+#: pg_basebackup.c:1139
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "n'a pas pu analyser l'archive « %s »"
+
+#: pg_basebackup.c:1140
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Seules les archives tar peuvent être analysées"
+
+#: pg_basebackup.c:1142
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Le format plain requiert que pg_basebackup analyse l'archive."
+
+#: pg_basebackup.c:1144
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "Utiliser - comme répertoire de sortie requiert que pg_basebackup analyse l'archive."
+
+#: pg_basebackup.c:1146
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "L'option -R requiert que pg_basebackup analyse l'archive."
+
+#: pg_basebackup.c:1357
+#, c-format
+msgid "archives must precede manifest"
+msgstr "les archives doivent précéder le manifeste"
+
+#: pg_basebackup.c:1372
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "nom d'archive invalide : « %s »"
+
+#: pg_basebackup.c:1444
+#, c-format
+msgid "unexpected payload data"
+msgstr "donnée de charge inattendue"
+
+#: pg_basebackup.c:1587
+#, c-format
+msgid "empty COPY message"
+msgstr "message COPY vide"
+
+#: pg_basebackup.c:1589
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "message COPY malformé de type %d, longueur %zu"
+
+#: pg_basebackup.c:1787
+#, c-format
+msgid "incompatible server version %s"
+msgstr "version « %s » du serveur incompatible"
+
+#: pg_basebackup.c:1803
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Utilisez -X none ou -X fetch pour désactiver la réplication en flux."
+
+#: pg_basebackup.c:1871
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "les cibles de sauvegarde ne sont pas supportées par cette version du serveur"
+
+#: pg_basebackup.c:1874
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "la configuration de la restauration ne peut pas être écrite quand une cible de restauration est utilisée"
+
+#: pg_basebackup.c:1901
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "le serveur ne supporte pas la compression côté serveur"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "début de la sauvegarde de base, en attente de la fin du checkpoint"
+
+#: pg_basebackup.c:1915
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "en attente du checkpoint"
+
+#: pg_basebackup.c:1928 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "n'a pas pu envoyer la commande de réplication « %s » : %s"
+
+#: pg_basebackup.c:1936
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "n'a pas pu initier la sauvegarde de base : %s"
+
+#: pg_basebackup.c:1939
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "le serveur a renvoyé une réponse inattendue à la commande BASE_BACKUP ; a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs"
+
+#: pg_basebackup.c:1945
+#, c-format
+msgid "checkpoint completed"
+msgstr "checkpoint terminé"
+
+#: pg_basebackup.c:1960
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "point de départ du journal de transactions : %s sur la timeline %u"
+
+#: pg_basebackup.c:1968
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "n'a pas pu obtenir l'en-tête du serveur : %s"
+
+#: pg_basebackup.c:1971
+#, c-format
+msgid "no data returned from server"
+msgstr "aucune donnée renvoyée du serveur"
+
+#: pg_basebackup.c:2006
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "peut seulement écrire un tablespace sur la sortie standard, la base en a %d"
+
+#: pg_basebackup.c:2019
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "lance le récepteur de journaux de transactions en tâche de fond"
+
+#: pg_basebackup.c:2101
+#, c-format
+msgid "backup failed: %s"
+msgstr "échec de la sauvegarde : %s"
+
+#: pg_basebackup.c:2104
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "aucune position de fin du journal de transactions renvoyée par le serveur"
+
+#: pg_basebackup.c:2107
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "point final du journal de transactions : %s"
+
+#: pg_basebackup.c:2118
+#, c-format
+msgid "checksum error occurred"
+msgstr "erreur de somme de contrôle"
+
+#: pg_basebackup.c:2123
+#, c-format
+msgid "final receive failed: %s"
+msgstr "échec lors de la réception finale : %s"
+
+#: pg_basebackup.c:2147
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "en attente que le processus en tâche de fond termine le flux..."
+
+#: pg_basebackup.c:2151
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "n'a pas pu envoyer la commande au tube du processus : %m"
+
+#: pg_basebackup.c:2156
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "n'a pas pu attendre le processus fils : %m"
+
+#: pg_basebackup.c:2158
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "le fils %d est mort, %d attendu"
+
+#: pg_basebackup.c:2160 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2180
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "n'a pas pu attendre le thread : %m"
+
+#: pg_basebackup.c:2185
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "n'a pas pu obtenir le code de sortie du thread : %m"
+
+#: pg_basebackup.c:2188
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "le thread a quitté avec le code d'erreur %u"
+
+#: pg_basebackup.c:2217
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "synchronisation des données sur disque..."
+
+#: pg_basebackup.c:2242
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "renommage de backup_manifest.tmp en backup_manifest"
+
+#: pg_basebackup.c:2262
+#, c-format
+msgid "base backup completed"
+msgstr "sauvegarde de base terminée"
+
+#: pg_basebackup.c:2351
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "format de sortie « %s » invalide, doit être soit « plain » soit « tar »"
+
+#: pg_basebackup.c:2395
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "option wal-method « %s » invalide, doit être soit « fetch » soit « stream » soit « none »"
+
+#: pg_basebackup.c:2425
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "argument « %s » invalide pour le CHECKPOINT, doit être soit « fast » soit « spread »"
+
+#: pg_basebackup.c:2476 pg_basebackup.c:2488 pg_basebackup.c:2510
+#: pg_basebackup.c:2522 pg_basebackup.c:2528 pg_basebackup.c:2580
+#: pg_basebackup.c:2591 pg_basebackup.c:2601 pg_basebackup.c:2607
+#: pg_basebackup.c:2614 pg_basebackup.c:2626 pg_basebackup.c:2638
+#: pg_basebackup.c:2646 pg_basebackup.c:2659 pg_basebackup.c:2665
+#: pg_basebackup.c:2674 pg_basebackup.c:2686 pg_basebackup.c:2697
+#: pg_basebackup.c:2705 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Essayez « %s --help » pour plus d'informations."
+
+#: pg_basebackup.c:2486 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "trop d'arguments en ligne de commande (le premier étant « %s »)"
+
+#: pg_basebackup.c:2509
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "ne peut pas spécifier à la fois le format et la cible de sauvegarde"
+
+#: pg_basebackup.c:2521
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "doit spécifier un répertoire de sortie ou une cible de sauvegarde"
+
+#: pg_basebackup.c:2527
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "ne peut pas spécifier à la fois le répertoire en sortie et la cible de sauvegarde"
+
+#: pg_basebackup.c:2557 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "algorithme de compression inconnu : « %s »"
+
+#: pg_basebackup.c:2563 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "spécification de compression invalide : %s"
+
+#: pg_basebackup.c:2579
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "la compression client n'est pas possible quand une cible de restauration est indiquée."
+
+#: pg_basebackup.c:2590
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "seules les sauvegardes en mode tar peuvent être compressées"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "Les journaux de transactions ne peuvent pas être envoyés en flux quand une cible de sauvegarde est indiquée."
+
+#: pg_basebackup.c:2606
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "ne peut pas envoyer les journaux de transactions vers stdout en mode tar"
+
+#: pg_basebackup.c:2613
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "les slots de réplications peuvent seulement être utilisés avec la réplication en flux des WAL"
+
+#: pg_basebackup.c:2625
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot ne peut pas être utilisé avec un nom de slot"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2636 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s a besoin du slot avec l'option --slot"
+
+#: pg_basebackup.c:2644 pg_basebackup.c:2684 pg_basebackup.c:2695
+#: pg_basebackup.c:2703
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s et %s sont des options incompatibles"
+
+#: pg_basebackup.c:2658
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "l'emplacement du répertoire des journaux de transactions ne peut pas être indiqué avec une cible de sauvegarde"
+
+#: pg_basebackup.c:2664
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "l'emplacement du répertoire des journaux de transactions doit être indiqué uniquement dans le mode plain"
+
+#: pg_basebackup.c:2673
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "l'emplacement du répertoire des journaux de transactions doit être indiqué avec un chemin absolu"
+
+#: pg_basebackup.c:2774
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "n'a pas pu créer le lien symbolique « %s » : %m"
+
+#: pg_basebackup.c:2776
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "les liens symboliques ne sont pas supportés sur cette plateforme"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s reçoit le flux des journaux de transactions PostgreSQL.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Options :\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr ""
+" -D, --directory=RÉPERTOIRE reçoit les journaux de transactions dans ce\n"
+" répertoire\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN quitte après avoir reçu le LSN spécifié\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr ""
+" --if-not-exists ne pas renvoyer une erreur si le slot existe\n"
+" déjà lors de sa création\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop ne boucle pas en cas de perte de la connexion\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr ""
+" --no-sync n'attend pas que les modifications soient\n"
+" proprement écrites sur disque\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SECS durée entre l'envoi de paquets de statut au\n"
+" (par défaut %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr ""
+" --synchronous vide le journal de transactions immédiatement\n"
+" après son écriture\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compresse comme indiqué\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Actions optionnelles :\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr ""
+" --create-slot crée un nouveau slot de réplication\n"
+" (pour le nom du slot, voir --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr ""
+" --drop-slot supprime un nouveau slot de réplication\n"
+" (pour le nom du slot, voir --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "segment terminé à %X/%X (timeline %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "arrêt du flux streaming à %X/%X (timeline %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "a basculé sur la timeline %u à %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "a reçu un signal d'interruption, quitte"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "n'a pas pu fermer le répertoire « %s » : %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "le segment « %s » a une taille incorrecte (%lld), ignoré"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "n'a pas pu ouvrir le fichier compressé « %s » : %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "n'a pas pu chercher dans le fichier compressé « %s » : %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "n'a pas pu lire le fichier compressé « %s » : %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "n'a pas pu lire le fichier compressé « %s » : a lu %d sur %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "le segment compressé « %s » a une taille %d non compressé incorrecte, ignoré"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "n'a pas pu créer le contexte de décompression LZ4 : %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "n'a pas pu lire le fichier « %s » : %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "n'a pas pu décompresser le fichier « %s » : %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "n'a pas pu libérer le contexte de décompression LZ4 : %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "le fichier segment compressé « %s » a une taille %zu décompressée incorrecte, ignoré"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "ne peut pas vérifier le fichier « %s » : la compression avec %s n'a pas été intégrée lors de la compilation"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "commence le flux des journaux à %X/%X (timeline %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "n'a pas pu analyser la position finale « %s »"
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "ne peut pas utiliser --create-slot avec --drop-slot"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "ne peut pas utiliser --synchronous avec --no-sync"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "aucun répertoire cible indiqué"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "la méthode de compression %s n'est pas encore supportée"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "la connexion de réplication utilisant le slot « %s » est spécifique à une base, ce qui est inattendu"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "suppression du slot de réplication « %s »"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "création du slot de réplication « %s »"
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "déconnecté"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "déconnecté, attente de %d secondes avant une nouvelle tentative"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s contrôle le flux des modifications logiques de PostgreSQL.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Action à réaliser :\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr ""
+" --start lance le flux dans un slot de réplication (pour\n"
+" le nom du slot, voir --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr ""
+" -f, --file=FICHIER trace la réception dans ce fichier, - pour\n"
+" stdout\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F --fsync-interval=SECS durée entre les fsyncs vers le fichier de sortie\n"
+" (par défaut %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr ""
+" -I, --startpos=LSN position de début du streaming dans le slot\n"
+" existant\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NOM[=VALEUR] passe l'option NOM avec la valeur optionnelle\n"
+" VALEUR au plugin en sortie\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr ""
+" -P, --plugin=PLUGIN utilise le plugin PLUGIN en sortie (par défaut\n"
+" %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOT nom du slot de réplication logique\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase active le décodage des transactions préparées lors de la création d'un slot\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=BASE base de données de connexion\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "confirmation d'écriture jusqu'à %X/%X et de synchronisation jusqu'à %X/%X (slot %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "n'a pas pu envoyer le paquet d'informations en retour : %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "commence le flux des journaux à %X/%X (slot %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "flux lancé"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "n'a pas pu ouvrir le journal applicatif « %s » : %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "socket invalide : %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "échec de %s() : %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "n'a pas pu recevoir des données du flux de WAL : %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "en-tête de flux trop petit : %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "entête non reconnu du flux : « %c »"
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "n'a pas pu écrire %d octets dans le journal de transactions « %s » : %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "fin inattendue du flux de réplication : %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "n'a pas pu analyser la position de départ « %s »"
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "aucun slot de réplication indiqué"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "aucun fichier cible indiqué"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "aucune base de données indiquée"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "au moins une action doit être indiquée"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "ne peut pas utiliser --create-slot ou --start avec --drop-slot"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "ne peut pas utiliser --create-slot ou --drop-slot avec --startpos"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos peut seulement être spécifié avec --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase peut seulement être spécifié avec --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "n'a pas pu établir une connexion de réplication spécifique à la base"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "position finale %X/%X atteinte par keepalive"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "position finale %X/%X atteinte à l'enregistrement WAL %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "n'a pas pu créer le fichier de statut d'archivage « %s » : %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "n'a pas pu fermer le fichier de statut d'archivage « %s » : %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "n'a pas pu obtenir la taille du journal de transactions « %s » : %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "n'a pas pu ouvrir le journal des transactions « %s » existant : %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "n'a pas pu synchroniser sur disque le journal de transactions « %s » existant : %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "le journal de transactions « %s » comprend %zd octet, cela devrait être 0 ou %d"
+msgstr[1] "le journal de transactions « %s » comprend %zd octets, cela devrait être 0 ou %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "n'a pas pu ouvrir le journal de transactions « %s » : %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "n'a pas pu déterminer la position de recherche dans le fichier d'archive « %s » : %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "pas de renommage de « %s », le segment n'est pas complet"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "n'a pas pu fermer le fichier « %s » : %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "le serveur a renvoyé un nom de fichier historique inattendu pour la timeline %u : %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "n'a pas pu créer le fichier historique de la timeline « %s » : %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "n'a pas pu écrire dans le fichier historique de la timeline « %s » : %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "version %s du serveur incompatible ; le client ne supporte pas le streaming de versions plus anciennes que %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "version %s du serveur incompatible ; le client ne supporte pas le streaming de versions plus récentes que %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "l'identifiant système ne correspond pas entre la sauvegarde des fichiers et la connexion de réplication"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "la timeline %u de départ n'est pas dans le serveur"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "réponse inattendue à la commande TIMELINE_HISTORY : a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "le serveur a renvoyé une timeline suivante %u inattendue, après la timeline %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "le serveur a arrêté l'envoi de la timeline %u à %X/%X, mais a indiqué que la timeline suivante, %u, commence à %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "le flux de réplication a été abandonné avant d'arriver au point d'arrêt"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "ensemble de résultats inattendu après la fin de la timeline : a récupéré %d lignes et %d champs, alors qu'il attendait %d lignes et %d champs"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "n'a pas pu analyser la position de départ de la prochaine timeline « %s »"
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "n'a pas pu synchroniser sur disque (fsync) le fichier « %s » : %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "a reçu l'enregistrement du journal de transactions pour le décalage %u sans fichier ouvert"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "a obtenu le décalage %08x pour les données du journal, attendait %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "n'a pas pu écrire %d octets dans le journal de transactions « %s » : %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "n'a pas pu envoyer le paquet de fin de copie : %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Mot de passe : "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "n'a pas pu se connecter au serveur"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "n'a pas pu effacer search_path : %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "n'a pas pu déterminer la configuration serveur de integer_datetimes"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "l'option de compilation integer_datetimes ne correspond pas au serveur"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "n'a pas pu récupéré la taille d'un segment WAL : a obtenu %d lignes et %d champs, attendait %d lignes et %d champs (ou plus)"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "la taille du segment WAL n'a pas pu être analysée"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "la taille d'un WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go mais le serveur distant a rapporté une valeur de %d octet"
+msgstr[1] "la taille d'un WAL doit être une puissance de deux comprise entre 1 Mo et 1 Go mais le serveur distant a rapporté une valeur de %d octets"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "n'a pas pu récupérer les options d'accès du groupe : a obtenu %d lignes et %d champs, attendait %d lignes et %d champs (ou plus)"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "l'option d'accès du groupe n'a pas pu être analysé : %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "n'a pas pu identifier le système : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs (ou plus)."
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "n'a pas pu lire le slot de réplication « %s » : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "le slot de réplication « %s » n'existe pas"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "attendait un slot de réplication physique, a obtenu le type « %s » à la place"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "n'a pas pu analyser le champ restart_lsn « %s » pour le slot de réplication « %s »"
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "n'a pas pu créer le slot de réplication « %s » : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "n'a pas pu supprimer le slot de réplication « %s » : a récupéré %d lignes et %d champs, attendait %d lignes et %d champs"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "n'a pas pu compresser les données"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "n'a pas pu réinitialiser le flux de compression"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "erreur d'implémentation : les fichiers tar ne peuvent pas avoir plus d'un fichier ouvert"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "n'a pas pu créer l'en-tête du fichier tar"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "n'a pas pu modifier les paramètres de compression"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "suppression non supportée avec la compression"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "n'a pas pu fermer le flux de compression"
+
+#~ msgid ""
+#~ "\n"
+#~ "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Rapporter les bogues à <pgsql-bugs@lists.postgresql.org>.\n"
+
+#, c-format
+#~ msgid ""
+#~ " --compression-method=METHOD\n"
+#~ " method to compress logs\n"
+#~ msgstr ""
+#~ " --compression-method=METHODE\n"
+#~ " méthode pour compresser les journaux\n"
+
+#~ msgid " --help show this help, then exit\n"
+#~ msgstr " --help affiche cette aide et quitte\n"
+
+#~ msgid " --version output version information, then exit\n"
+#~ msgstr " --version affiche la version et quitte\n"
+
+#~ msgid " -?, --help show this help, then exit\n"
+#~ msgstr " -?, --help affiche cette aide puis quitte\n"
+
+#~ msgid " -V, --version output version information, then exit\n"
+#~ msgstr " -V, --version affiche la version puis quitte\n"
+
+#, c-format
+#~ msgid " -Z, --compress=0-9 compress tar output with given compression level\n"
+#~ msgstr ""
+#~ " -Z, --compress=0-9 compresse la sortie tar avec le niveau de\n"
+#~ " compression indiqué\n"
+
+#, c-format
+#~ msgid " -Z, --compress=1-9 compress logs with given compression level\n"
+#~ msgstr ""
+#~ " -Z, --compress=0-9 compresse les journaux avec le niveau de\n"
+#~ " compression indiqué\n"
+
+#~ msgid " -x, --xlog include required WAL files in backup (fetch mode)\n"
+#~ msgstr ""
+#~ " -x, --xlog inclut les journaux de transactions nécessaires\n"
+#~ " dans la sauvegarde (mode fetch)\n"
+
+#~ msgid "%s: WAL directory \"%s\" not removed at user's request\n"
+#~ msgstr "%s : répertoire des journaux de transactions « %s » non supprimé à la demande de l'utilisateur\n"
+
+#~ msgid "%s: WAL directory location must be an absolute path\n"
+#~ msgstr ""
+#~ "%s : l'emplacement du répertoire des journaux de transactions doit être\n"
+#~ "indiqué avec un chemin absolu\n"
+
+#~ msgid "%s: WAL streaming can only be used in plain mode\n"
+#~ msgstr "%s : le flux de journaux de transactions peut seulement être utilisé en mode plain\n"
+
+#~ msgid "%s: cannot specify both --xlog and --xlog-method\n"
+#~ msgstr "%s : ne peut pas spécifier à la fois --xlog et --xlog-method\n"
+
+#~ msgid "%s: child process did not exit normally\n"
+#~ msgstr "%s : le processus fils n'a pas quitté normalement\n"
+
+#~ msgid "%s: child process exited with error %d\n"
+#~ msgstr "%s : le processus fils a quitté avec le code erreur %d\n"
+
+#~ msgid "%s: could not access directory \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu accéder au répertoire « %s » : %s\n"
+
+#~ msgid "%s: could not clear search_path: %s"
+#~ msgstr "%s : n'a pas pu effacer search_path : %s"
+
+#~ msgid "%s: could not close directory \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu fermer le répertoire « %s » : %s\n"
+
+#~ msgid "%s: could not close file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu fermer le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not close file %s: %s\n"
+#~ msgstr "%s : n'a pas pu fermer le fichier %s : %s\n"
+
+#~ msgid "%s: could not connect to server\n"
+#~ msgstr "%s : n'a pas pu se connecter au serveur\n"
+
+#~ msgid "%s: could not connect to server: %s"
+#~ msgstr "%s : n'a pas pu se connecter au serveur : %s"
+
+#~ msgid "%s: could not create archive status file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu créer le fichier de statut d'archivage « %s » : %s\n"
+
+#~ msgid "%s: could not create directory \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu créer le répertoire « %s » : %s\n"
+
+#~ msgid "%s: could not create file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu créer le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not create symbolic link \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu créer le lien symbolique « %s » : %s\n"
+
+#~ msgid "%s: could not fsync file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not fsync log file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu synchroniser sur disque le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not get current position in file %s: %s\n"
+#~ msgstr "%s : n'a pas pu obtenir la position courant dans le fichier %s : %s\n"
+
+#~ msgid "%s: could not identify system: %s"
+#~ msgstr "%s : n'a pas pu identifier le système : %s"
+
+#~ msgid "%s: could not identify system: %s\n"
+#~ msgstr "%s : n'a pas pu identifier le système : %s\n"
+
+#~ msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n"
+#~ msgstr ""
+#~ "%s : n'a pas pu identifier le système, a récupéré %d lignes et %d champs,\n"
+#~ "attendait %d lignes et %d champs (ou plus)\n"
+
+#~ msgid "%s: could not open WAL segment %s: %s\n"
+#~ msgstr "%s : n'a pas pu ouvrir le segment WAL %s : %s\n"
+
+#~ msgid "%s: could not open directory \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu ouvrir le répertoire « %s » : %s\n"
+
+#~ msgid "%s: could not open file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu ouvrir le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not open log file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu ouvrir le journal applicatif « %s » : %s\n"
+
+#~ msgid "%s: could not open timeline history file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu ouvrir le journal historique de la timeline « %s » : %s\n"
+
+#~ msgid "%s: could not open write-ahead log file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu ouvrir le journal de transactions « %s » : %s\n"
+
+#~ msgid "%s: could not pad WAL segment %s: %s\n"
+#~ msgstr "%s : n'a pas pu terminer le segment WAL %s : %s\n"
+
+#~ msgid "%s: could not pad transaction log file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu remplir de zéros le journal de transactions « %s » : %s\n"
+
+#~ msgid "%s: could not parse file mode\n"
+#~ msgstr "%s : n'a pas pu analyser le mode du fichier\n"
+
+#~ msgid "%s: could not parse file size\n"
+#~ msgstr "%s : n'a pas pu analyser la taille du fichier\n"
+
+#~ msgid "%s: could not parse log start position from value \"%s\"\n"
+#~ msgstr "%s : n'a pas pu analyser la position de départ des WAL à partir de la valeur « %s »\n"
+
+#~ msgid "%s: could not parse transaction log file name \"%s\"\n"
+#~ msgstr "%s : n'a pas pu analyser le nom du journal de transactions « %s »\n"
+
+#~ msgid "%s: could not read copy data: %s\n"
+#~ msgstr "%s : n'a pas pu lire les données du COPY : %s\n"
+
+#~ msgid "%s: could not read directory \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu lire le répertoire « %s » : %s\n"
+
+#~ msgid "%s: could not receive data from WAL stream: %s"
+#~ msgstr "%s : n'a pas pu recevoir des données du flux de WAL : %s"
+
+#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu renommer le fichier « %s » en « %s » : %s\n"
+
+#~ msgid "%s: could not rename file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu renommer le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not seek back to beginning of WAL segment %s: %s\n"
+#~ msgstr "%s : n'a pas pu se déplacer au début du segment WAL %s : %s\n"
+
+#~ msgid "%s: could not seek to beginning of transaction log file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu rechercher le début du journal de transaction « %s » : %s\n"
+
+#~ msgid "%s: could not send base backup command: %s"
+#~ msgstr "%s : n'a pas pu envoyer la commande de sauvegarde de base : %s"
+
+#~ msgid "%s: could not set permissions on directory \"%s\": %s\n"
+#~ msgstr "%s : n'a pas configurer les droits sur le répertoire « %s » : %s\n"
+
+#~ msgid "%s: could not set permissions on file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu configurer les droits sur le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not stat WAL segment %s: %s\n"
+#~ msgstr "%s : n'a pas pu récupérer les informations sur le segment WAL %s : %s\n"
+
+#~ msgid "%s: could not stat file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu récupérer les informations sur le fichier « %s » : %s\n"
+
+#~ msgid "%s: could not stat transaction log file \"%s\": %s\n"
+#~ msgstr ""
+#~ "%s : n'a pas pu récupérer les informations sur le journal de transactions\n"
+#~ "« %s » : %s\n"
+
+#~ msgid "%s: could not write to file \"%s\": %s\n"
+#~ msgstr "%s : n'a pas pu écrire dans le fichier « %s » : %s\n"
+
+#~ msgid "%s: data directory \"%s\" not removed at user's request\n"
+#~ msgstr "%s : répertoire des données « %s » non supprimé à la demande de l'utilisateur\n"
+
+#~ msgid "%s: directory \"%s\" exists but is not empty\n"
+#~ msgstr "%s : le répertoire « %s » existe mais n'est pas vide\n"
+
+#~ msgid "%s: failed to remove WAL directory\n"
+#~ msgstr "%s : échec de la suppression du répertoire des journaux de transactions\n"
+
+#~ msgid "%s: failed to remove contents of WAL directory\n"
+#~ msgstr "%s : échec de la suppression du contenu du répertoire des journaux de transactions\n"
+
+#~ msgid "%s: failed to remove contents of data directory\n"
+#~ msgstr "%s : échec de la suppression du contenu du répertoire des données\n"
+
+#~ msgid "%s: failed to remove data directory\n"
+#~ msgstr "%s : échec de la suppression du répertoire des données\n"
+
+#~ msgid "%s: invalid format of xlog location: %s\n"
+#~ msgstr "%s : format invalide de l'emplacement du journal de transactions : %s\n"
+
+#~ msgid "%s: invalid port number \"%s\"\n"
+#~ msgstr "%s : numéro de port invalide : « %s »\n"
+
+#~ msgid "%s: invalid socket: %s"
+#~ msgstr "%s : socket invalide : %s"
+
+#~ msgid "%s: keepalive message has incorrect size %d\n"
+#~ msgstr "%s : le message keepalive a une taille %d incorrecte\n"
+
+#~ msgid "%s: no start point returned from server\n"
+#~ msgstr "%s : aucun point de redémarrage renvoyé du serveur\n"
+
+#~ msgid "%s: out of memory\n"
+#~ msgstr "%s : mémoire épuisée\n"
+
+#~ msgid "%s: removing WAL directory \"%s\"\n"
+#~ msgstr "%s : suppression du répertoire des journaux de transactions « %s »\n"
+
+#~ msgid "%s: removing contents of WAL directory \"%s\"\n"
+#~ msgstr "%s : suppression du contenu du répertoire des journaux de transactions « %s »\n"
+
+#~ msgid "%s: removing contents of data directory \"%s\"\n"
+#~ msgstr "%s : suppression du contenu du répertoire des données « %s »\n"
+
+#~ msgid "%s: removing data directory \"%s\"\n"
+#~ msgstr "%s : suppression du répertoire des données « %s »\n"
+
+#~ msgid "%s: select() failed: %s\n"
+#~ msgstr "%s : échec de select() : %s\n"
+
+#~ msgid "%s: socket not open"
+#~ msgstr "%s : socket non ouvert"
+
+#~ msgid "%s: symlinks are not supported on this platform\n"
+#~ msgstr "%s : les liens symboliques ne sont pas supportés sur cette plateforme\n"
+
+#~ msgid "%s: timeline does not match between base backup and streaming connection\n"
+#~ msgstr ""
+#~ "%s : la timeline ne correspond pas entre la sauvegarde des fichiers et la\n"
+#~ "connexion de réplication\n"
+
+#~ msgid "%s: too many command-line arguments (first is \"%s\")\n"
+#~ msgstr "%s : trop d'arguments en ligne de commande (le premier étant « %s »)\n"
+
+#~ msgid "--create-slot and --no-slot are incompatible options"
+#~ msgstr "--create-slot et --no-slot sont des options incompatibles"
+
+#~ msgid "--no-manifest and --manifest-checksums are incompatible options"
+#~ msgstr "--no-manifest et --manifest-checksums sont des options incompatibles"
+
+#~ msgid "--no-manifest and --manifest-force-encode are incompatible options"
+#~ msgstr "--no-manifest et --manifest-force-encode sont des options incompatibles"
+
+#~ msgid "--progress and --no-estimate-size are incompatible options"
+#~ msgstr "--progress et --no-estimate-size sont des options incompatibles"
+
+#, c-format
+#~ msgid "This build does not support compression with %s."
+#~ msgstr "Cette construction ne supporte pas la compression avec %s."
+
+#, c-format
+#~ msgid "Try \"%s --help\" for more information.\n"
+#~ msgstr "Essayer « %s --help » pour plus d'informations.\n"
+
+#, c-format
+#~ msgid "cannot use --compress with --compression-method=%s"
+#~ msgstr "ne peut pas utiliser --compress avec --compression-method=%s"
+
+#, c-format
+#~ msgid "could not check file \"%s\""
+#~ msgstr "n'a pas pu vérifier le fichier « %s »"
+
+#~ msgid "could not connect to server: %s"
+#~ msgstr "n'a pas pu se connecter au serveur : %s"
+
+#, c-format
+#~ msgid "could not find replication slot \"%s\""
+#~ msgstr "n'a pas pu trouver le slot de réplication « %s »"
+
+#, c-format
+#~ msgid "could not get write-ahead log end position from server: %s"
+#~ msgstr "n'a pas pu obtenir la position finale des journaux de transactions à partir du serveur : %s"
+
+#~ msgid "deflate failed"
+#~ msgstr "échec en décompression"
+
+#~ msgid "deflateEnd failed"
+#~ msgstr "échec de deflateEnd"
+
+#~ msgid "deflateInit2 failed"
+#~ msgstr "échec de deflateInit2"
+
+#~ msgid "deflateParams failed"
+#~ msgstr "échec de deflateParams"
+
+#~ msgid "deflateReset failed"
+#~ msgstr "échec de deflateReset"
+
+#, c-format
+#~ msgid "fatal: "
+#~ msgstr "fatal : "
+
+#, c-format
+#~ msgid "invalid compression level \"%s\""
+#~ msgstr "niveau de compression « %s » invalide"
+
+#, c-format
+#~ msgid "invalid fsync interval \"%s\""
+#~ msgstr "intervalle fsync « %s » invalide"
+
+#, c-format
+#~ msgid "invalid port number \"%s\""
+#~ msgstr "numéro de port invalide : « %s »"
+
+#, c-format
+#~ msgid "invalid status interval \"%s\""
+#~ msgstr "intervalle « %s » invalide du statut"
+
+#, c-format
+#~ msgid "invalid tar block header size: %zu"
+#~ msgstr "taille invalide de l'en-tête de bloc du fichier tar : %zu"
+
+#, c-format
+#~ msgid "log streamer with pid %d exiting"
+#~ msgstr "le processus d'envoi des journaux de PID %d quitte"
+
+#, c-format
+#~ msgid "no value specified for --compress, switching to default"
+#~ msgstr "aucune valeur indiquée pour --compression, utilise la valeur par défaut"
+
+#~ msgid "select() failed: %m"
+#~ msgstr "échec de select() : %m"
+
+#, c-format
+#~ msgid "unknown compression option \"%s\""
+#~ msgstr "option de compression « %s » inconnue"
+
+#, c-format
+#~ msgid "unrecognized link indicator \"%c\""
+#~ msgstr "indicateur de lien « %c » non reconnu"
diff --git a/src/bin/pg_basebackup/po/it.po b/src/bin/pg_basebackup/po/it.po
new file mode 100644
index 0000000..37892c7
--- /dev/null
+++ b/src/bin/pg_basebackup/po/it.po
@@ -0,0 +1,1937 @@
+#
+# pg_basebackup.po
+# Italian message translation file for pg_basebackup
+#
+# For development and bug report please use:
+# https://github.com/dvarrazzo/postgresql-it
+#
+# Copyright (C) 2012-2017 PostgreSQL Global Development Group
+#
+# Daniele Varrazzo <daniele.varrazzo@gmail.com>, 2012-2017
+#
+# This file is distributed under the same license as the PostgreSQL package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL) 11\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-09-26 08:18+0000\n"
+"PO-Revision-Date: 2022-10-04 19:29+0200\n"
+"Last-Translator: Domenico Sgarbossa <sgarbossa.domenico@gmail.com>\n"
+"Language-Team: https://github.com/dvarrazzo/postgresql-it\n"
+"Language: it\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+"X-Generator: Poedit 3.1.1\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "errore: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "avvertimento: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "dettaglio: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "suggerimento: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "questa build non supporta la compressione con %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "trovata una stringa vuota in cui era prevista un'opzione di compressione"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "opzione di colonna \"%s\" non riconosciuta"
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "l'opzione di compressione \"%s\" richiede un valore"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "il valore per l'opzione di compressione \"%s\" deve essere un numero intero"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "l'algoritmo di compressione \"%s\" non accetta un livello di compressione"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "l'algoritmo di compressione \"%s\" prevede un livello di compressione compreso tra %d e %d (impostazione predefinita a %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "l'algoritmo di compressione \"%s\" non accetta un conteggio di lavoro"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "memoria esaurita\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "impossibile duplicare il puntatore nullo (errore interno)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "non è stato possibile ottenere informazioni sul file \"%s\": %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "apertura della directory \"%s\" fallita: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "lettura della directory \"%s\" fallita: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "apertura del file \"%s\" fallita: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "fsync del file \"%s\" fallito: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2256 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "non è stato possibile rinominare il file \"%s\" in \"%s\": %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "valore \"%s\" per \"%s\" non valido"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s deve essere compreso nell'intervallo %d..%d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1636
+#, c-format
+msgid "out of memory"
+msgstr "memoria esaurita"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1433 pg_basebackup.c:1727
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "scrittura nel file \"%s\" fallita: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1497 pg_basebackup.c:1706
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "creazione del file \"%s\" fallita: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "chiusura del file \"%s\" fallita: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "stato imprevisto durante l'estrazione dell'archivio"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:686 pg_basebackup.c:730
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "creazione della directory \"%s\" fallita: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "impostazione dei permessi sulla directory \"%s\" fallita: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "impossibile creare un collegamento simbolico da \"%s\" a \"%s\": %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "impossibile impostare i permessi sul file \"%s\": %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "impossibile creare il file compresso \"%s\": %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "impossibile duplicare lo stdout: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "impossibile aprire il file di output: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "impossibile impostare il livello di compressione %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "questa build non supporta la compressione gzip"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "impossibile scrivere nel file compresso \"%s\": %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "impossibile chiudere il file compresso \"%s\": %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "inizializzazione della libreria di compressione fallita"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "impossibile decomprimere i dati: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "stato imprevisto durante l'iniezione delle impostazioni di ripristino"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "impossibile creare il contesto di compressione lz4: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "questa build non supporta la compressione lz4"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "impossibile scrivere l'intestazione lz4: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "impossibile comprimere i dati: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "impossibile terminare la compressione lz4: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "impossibile inizializzare la libreria di compressione: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "il trailer del file tar supera i 2 blocchi"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "stato imprevisto durante l'analisi dell'archivio tar"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "il membro tar ha un nome vuoto"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "Il flusso COPY è terminato prima che l'ultimo file fosse terminato"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "impossibile creare il contesto di compressione zstd"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "impossibile impostare il livello di compressione zstd su %d: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "impossibile impostare il conteggio degli operatori di compressione su %d: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "questa build non supporta la compressione zstd"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "impossibile creare il contesto di decompressione zstd"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "rimozione della directory dei dati \"%s\""
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "impossibile rimuovere la directory dei dati"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "rimozione del contenuto della directory dei dati \"%s\""
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "impossibile rimuovere il contenuto della directory dei dati"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "rimozione della directory WAL \"%s\""
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "impossibile rimuovere la directory WAL"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "rimozione del contenuto della directory WAL \"%s\""
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "più segni \"=\" nella mappatura del tablespace"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "directory dati \"%s\" non rimossa su richiesta dell'utente"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "Directory WAL \"%s\" non rimossa su richiesta dell'utente"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "le modifiche alle directory del tablespace non verranno annullate"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "nome della directory troppo lungo"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "più segni \"=\" nella mappatura del tablespace"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "formato di mappatura tablespace non valido \"%s\", deve essere \"OLDDIR=NEWDIR\""
+
+#: pg_basebackup.c:351
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "la vecchia directory non è un percorso assoluto nella mappatura del tablespace: %s"
+
+#: pg_basebackup.c:355
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "nuova directory non è un percorso assoluto nella mappatura del tablespace: %s"
+
+#: pg_basebackup.c:377
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s crea un backup di base di un server PostgreSQL in esecuzione.\n"
+"\n"
+
+#: pg_basebackup.c:379 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Utilizzo:\n"
+
+#: pg_basebackup.c:380 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [OPZIONE]...\n"
+
+#: pg_basebackup.c:381
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Opzioni di controllo del'output:\n"
+
+#: pg_basebackup.c:382
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=DIRECTORY directory in cui ricevere il backup di base\n"
+
+#: pg_basebackup.c:383
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t formato di output (plain (default), tar)\n"
+
+#: pg_basebackup.c:384
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=RATE transfer rate massimo per trasferire la directory dei dati\n"
+" (in kB/s, oppure usa i suffissi \"k\" o \"M\")\n"
+
+#: pg_basebackup.c:386
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" scrivere la configurazione per la replica\n"
+
+#: pg_basebackup.c:388
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=TARGET[:DETTAGLIO]\n"
+" destinazione di backup (se diversa dal client)\n"
+
+#: pg_basebackup.c:390
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=VECCHIADIR=NUOVADIR\n"
+" sposta il tablespace da VECCHIADIR a NUOVADIR\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=WALDIR posizione della directory del write-ahead log\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" includi i file di WAL richiesti col metodo specificato\n"
+
+#: pg_basebackup.c:395
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip comprimi l'output tar\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METODO[:DETTAGLIO]\n"
+" comprimere su client o server come specificato\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none non comprime l'output tar\n"
+
+#: pg_basebackup.c:399
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Opzioni generali:\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" imposta punti di controllo più veloci o più radi\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot crea uno slot di replica\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL imposta l'etichetta del backup\n"
+
+#: pg_basebackup.c:404
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean non rimuovere i file in caso di errore\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " -N, --no-sync non aspettare che le modifiche siano scritte con sicurezza su disco\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress mostra informazioni sull'esecuzione\n"
+
+#: pg_basebackup.c:407 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=NOMESLOT slot di replicazione da usare\n"
+
+#: pg_basebackup.c:408 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose messaggi di output più numerosi\n"
+
+#: pg_basebackup.c:409 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version mostra informazioni sulla versione ed esci\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NESSUNO\n"
+" utilizzare l'algoritmo per i checksum manifest\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --codifica-forza-manifest\n"
+" hex codifica tutti i nomi di file in manifest\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-stimate-size non stima la dimensione del backup sul lato server\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-slot impedisci la creazione di uno slot di replica temporanea\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot impedisci la creazione di uno slot di replica temporaneo\n"
+
+#: pg_basebackup.c:417
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" non verificare i checksum\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help mostra questo aiuto ed esci\n"
+
+#: pg_basebackup.c:420 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Opzioni di connessione:\n"
+
+#: pg_basebackup.c:421 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONNSTR stringa di connessione\n"
+
+#: pg_basebackup.c:422 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=HOSTNAME host del server database o directory del socket\n"
+
+#: pg_basebackup.c:423 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT numero di porta del server database\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVAL\n"
+" intervallo tra i pacchetti di stato inviati al server\n"
+" (in secondi)\n"
+
+#: pg_basebackup.c:426 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NAME connettiti al database col nome utente specificato\n"
+
+#: pg_basebackup.c:427 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password non chiedere mai la password\n"
+
+#: pg_basebackup.c:428 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr ""
+" -W, --password forza la richiesta della password\n"
+" (dovrebbe essere automatico)\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Segnala i bug a <%s>.\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Pagina iniziale di %s: <%s>\n"
+
+#: pg_basebackup.c:472
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "impossibile leggere dalla pipe pronta: %m"
+
+#: pg_basebackup.c:475 pg_basebackup.c:622 pg_basebackup.c:2170
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "impossibile analizzare la posizione del registro write-ahead \"%s\""
+
+#: pg_basebackup.c:581 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "impossibile completare la scrittura dei file WAL: %m"
+
+#: pg_basebackup.c:631
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "impossibile creare pipe per il processo in background: %m"
+
+#: pg_basebackup.c:664
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "creato slot di replica temporanea \"%s\""
+
+#: pg_basebackup.c:667
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "slot di replica creato \"%s\""
+
+#: pg_basebackup.c:701
+#, c-format
+msgid "could not create background process: %m"
+msgstr "impossibile creare un processo in background: %m"
+
+#: pg_basebackup.c:710
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "impossibile creare thread in background: %m"
+
+#: pg_basebackup.c:749
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "la directory \"%s\" esiste ma non è vuota"
+
+#: pg_basebackup.c:755
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "accesso alla directory \"%s\" fallito: %m"
+
+#: pg_basebackup.c:832
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgstr[1] "%*s/%s kB (100%%), %d/%d tablespace %*s"
+
+#: pg_basebackup.c:844
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+
+#: pg_basebackup.c:860
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace"
+
+#: pg_basebackup.c:884
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "la velocità di trasferimento \"%s\" non è un valore valido"
+
+#: pg_basebackup.c:886
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "velocità di trasferimento non valida \"%s\": %m"
+
+#: pg_basebackup.c:893
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "la velocità di trasferimento deve essere maggiore di zero"
+
+#: pg_basebackup.c:923
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "unità --max-rate non valida: \"%s\""
+
+#: pg_basebackup.c:927
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "la velocità di trasferimento \"%s\" supera l'intervallo di numeri interi"
+
+#: pg_basebackup.c:934
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "la velocità di trasferimento \"%s\" non è compresa nell'intervallo"
+
+#: pg_basebackup.c:1030
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "impossibile ottenere il flusso di dati COPY: %s"
+
+#: pg_basebackup.c:1047 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "impossibile leggere i dati COPY: %s"
+
+#: pg_basebackup.c:1051
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "processo in background terminato in modo imprevisto"
+
+#: pg_basebackup.c:1122
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "impossibile iniettare manifest in un file tar compresso"
+
+#: pg_basebackup.c:1123
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "Usa la compressione lato client, invia l'output a una directory anziché all'output standard o usa %s."
+
+#: pg_basebackup.c:1139
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "impossibile analizzare l'archivio \"%s\""
+
+#: pg_basebackup.c:1140
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "È possibile analizzare solo gli archivi tar."
+
+#: pg_basebackup.c:1142
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Il formato normale richiede pg_basebackup per analizzare l'archivio."
+
+#: pg_basebackup.c:1144
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "L'utilizzo di - come directory di output richiede pg_basebackup per analizzare l'archivio."
+
+#: pg_basebackup.c:1146
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "L'opzione -R richiede pg_basebackup per analizzare l'archivio."
+
+#: pg_basebackup.c:1357
+#, c-format
+msgid "archives must precede manifest"
+msgstr "gli archivi devono precedere manifest"
+
+#: pg_basebackup.c:1372
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "nome archivio non valido: \"%s\""
+
+#: pg_basebackup.c:1444
+#, c-format
+msgid "unexpected payload data"
+msgstr "dati di carico utile imprevisti"
+
+#: pg_basebackup.c:1587
+#, c-format
+msgid "empty COPY message"
+msgstr "messaggio COPIA vuoto"
+
+#: pg_basebackup.c:1589
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "messaggio COPY non corretto di tipo %d, lunghezza %zu"
+
+#: pg_basebackup.c:1787
+#, c-format
+msgid "incompatible server version %s"
+msgstr "versione server incompatibile %s"
+
+#: pg_basebackup.c:1803
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Usa -X nessuno o -X fetch per disabilitare lo streaming del registro."
+
+#: pg_basebackup.c:1871
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "le destinazioni di backup non sono supportate da questa versione del server"
+
+#: pg_basebackup.c:1874
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "non è possibile scrivere la configurazione di ripristino quando viene utilizzata una destinazione di backup"
+
+#: pg_basebackup.c:1901
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "il server non supporta la compressione lato server"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "avvio del backup di base, in attesa del completamento del checkpoint"
+
+#: pg_basebackup.c:1915
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "in attesa del checkpoint"
+
+#: pg_basebackup.c:1928 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "impossibile inviare il comando di replica \"%s\": %s"
+
+#: pg_basebackup.c:1936
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "impossibile avviare il backup di base: %s"
+
+#: pg_basebackup.c:1939
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "il server ha restituito una risposta imprevista al comando BASE_BACKUP; ottenuto %d righe e %d campi, previsto %d righe e %d campi"
+
+#: pg_basebackup.c:1945
+#, c-format
+msgid "checkpoint completed"
+msgstr "posto di blocco completato"
+
+#: pg_basebackup.c:1960
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "punto di inizio registro write-ahead: %s sulla sequenza temporale %u"
+
+#: pg_basebackup.c:1968
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "impossibile ottenere l'intestazione del backup: %s"
+
+#: pg_basebackup.c:1971
+#, c-format
+msgid "no data returned from server"
+msgstr "nessun dato restituito dal server"
+
+#: pg_basebackup.c:2006
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "può scrivere solo un singolo tablespace su stdout, il database ha %d"
+
+#: pg_basebackup.c:2019
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "ricevitore WAL in background iniziale"
+
+#: pg_basebackup.c:2101
+#, c-format
+msgid "backup failed: %s"
+msgstr "backup fallito: %s"
+
+#: pg_basebackup.c:2104
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "nessuna posizione finale del registro write-ahead restituita dal server"
+
+#: pg_basebackup.c:2107
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "punto finale del registro write-ahead: %s"
+
+#: pg_basebackup.c:2118
+#, c-format
+msgid "checksum error occurred"
+msgstr "si è verificato un errore di checksum"
+
+#: pg_basebackup.c:2123
+#, c-format
+msgid "final receive failed: %s"
+msgstr "ricezione finale non riuscita: %s"
+
+#: pg_basebackup.c:2147
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "in attesa che il processo in background finisca lo streaming..."
+
+#: pg_basebackup.c:2151
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "impossibile inviare il comando alla pipe in background: %m"
+
+#: pg_basebackup.c:2156
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "non potevo aspettare il processo figlio: %m"
+
+#: pg_basebackup.c:2158
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "processo figlio %d interrotto, atteso %d"
+
+#: pg_basebackup.c:2160 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2180
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "non potevo aspettare il thread figlio: %m"
+
+#: pg_basebackup.c:2185
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "impossibile ottenere lo stato di uscita del thread figlio: %m"
+
+#: pg_basebackup.c:2188
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "thread figlio terminato con errore %u"
+
+#: pg_basebackup.c:2217
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "sincronizzazione dei dati su disco..."
+
+#: pg_basebackup.c:2242
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "rinominando backup_manifest.tmp in backup_manifest"
+
+#: pg_basebackup.c:2262
+#, c-format
+msgid "base backup completed"
+msgstr "backup di base completato"
+
+#: pg_basebackup.c:2351
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "formato di output \"%s\" non valido, deve essere \"normale\" o \"tar\""
+
+#: pg_basebackup.c:2395
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "opzione wal-method \"%s\" non valida, deve essere \"fetch\", \"stream\" o \"none\""
+
+#: pg_basebackup.c:2425
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "argomento checkpoint non valido \"%s\", deve essere \"fast\" o \"spread\""
+
+#: pg_basebackup.c:2476 pg_basebackup.c:2488 pg_basebackup.c:2510
+#: pg_basebackup.c:2522 pg_basebackup.c:2528 pg_basebackup.c:2580
+#: pg_basebackup.c:2591 pg_basebackup.c:2601 pg_basebackup.c:2607
+#: pg_basebackup.c:2614 pg_basebackup.c:2626 pg_basebackup.c:2638
+#: pg_basebackup.c:2646 pg_basebackup.c:2659 pg_basebackup.c:2665
+#: pg_basebackup.c:2674 pg_basebackup.c:2686 pg_basebackup.c:2697
+#: pg_basebackup.c:2705 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Prova \"%s --help\" per maggiori informazioni."
+
+#: pg_basebackup.c:2486 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "troppi argomenti della riga di comando (il primo è \"%s\")"
+
+#: pg_basebackup.c:2509
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "non è possibile specificare sia il formato che la destinazione del backup"
+
+#: pg_basebackup.c:2521
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "deve specificare la directory di output o la destinazione del backup"
+
+#: pg_basebackup.c:2527
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "non è possibile specificare sia la directory di output che la destinazione del backup"
+
+#: pg_basebackup.c:2557 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "algoritmo di compressione non riconosciuto: \"%s\""
+
+#: pg_basebackup.c:2563 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "specifica di compressione non valida: %s"
+
+#: pg_basebackup.c:2579
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "la compressione lato client non è possibile quando viene specificata una destinazione di backup"
+
+#: pg_basebackup.c:2590
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "solo i backup in modalità tar possono essere compressi"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "Non è possibile eseguire lo streaming di WAL quando viene specificata una destinazione di backup"
+
+#: pg_basebackup.c:2606
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "impossibile eseguire lo streaming di registri write-ahead in modalità tar su stdout"
+
+#: pg_basebackup.c:2613
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "gli slot di replica possono essere utilizzati solo con lo streaming WAL"
+
+#: pg_basebackup.c:2625
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot non può essere utilizzato con il nome dello slot"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2636 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s ha bisogno di uno slot da specificare usando --slot"
+
+#: pg_basebackup.c:2644 pg_basebackup.c:2684 pg_basebackup.c:2695
+#: pg_basebackup.c:2703
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s e %s sono opzioni incompatibili"
+
+#: pg_basebackup.c:2658
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "Non è possibile specificare il percorso della directory WAL insieme a una destinazione di backup"
+
+#: pg_basebackup.c:2664
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "Il percorso della directory WAL può essere specificato solo in modalità normale"
+
+#: pg_basebackup.c:2673
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "Il percorso della directory WAL deve essere un percorso assoluto"
+
+#: pg_basebackup.c:2774
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "creazione del link simbolico \"%s\" fallita: %m"
+
+#: pg_basebackup.c:2776
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "i collegamenti simbolici non sono supportati su questa piattaforma"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s serve a ricevere il flusso dei write-ahead log di PostgreSQL.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opzioni:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=DIR ricevi i file di write-ahead log in questa directory\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN esci dopo aver ricevuto la posizione LSN specificata\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr " --if-not-exists non dare un errore se esiste già uno slot con lo stesso nome\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop non ri-eseguire se la connessione è persa\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " --no-sync non aspettare che i cambiamenti siano scritti sul disco in sicurezza\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SEC\n"
+" tempo tra i pacchetti di status inviati al server (default: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous esegui il flush del write-ahead log immediatamente dopo la scrittura\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=METODO[:DETTAGLIO]\n"
+" comprimere come specificato\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Azioni opzionali:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr " --create-slot crea un nuovo slot di replica (per il nome vedi --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr " --drop-slot elimina lo slot di replica (per il nome vedi --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "segmento finito alle %X/%X (timeline %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "flusso di log interrotto alle %X/%X (timeline %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "passato alla sequenza temporale %u alle %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "segnale di interruzione ricevuto, in uscita"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "impossibile chiudere la directory \"%s\": %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "il file di segmento \"%s\" ha una dimensione errata %lld, saltando"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "impossibile aprire il file compresso \"%s\": %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "impossibile cercare nel file compresso \"%s\": %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "impossibile leggere il file compresso \"%s\": %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "impossibile leggere il file compresso \"%s\": leggere %d di %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "il file del segmento compresso \"%s\" ha una dimensione non compressa %d errata, saltando"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "impossibile creare il contesto di decompressione LZ4: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "lettura del file \"%s\" fallita: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "impossibile decomprimere il file \"%s\": %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "impossibile liberare il contesto di decompressione LZ4: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "il file del segmento compresso \"%s\" ha una dimensione non compressa %zu errata, saltando"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "impossibile controllare il file \"%s\": compressione con %s non supportata da questa build"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "avvio del flusso di log alle %X/%X (timeline %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "impossibile analizzare la posizione finale \"%s\""
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "non è possibile utilizzare --create-slot insieme a --drop-slot"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "impossibile utilizzare --synchronous insieme a --no-sync"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "nessuna directory di destinazione specificata"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "la compressione con %s non è ancora supportata"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "la connessione di replica che utilizza lo slot \"%s\" è inaspettatamente specifica del database"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "eliminazione dello slot di replica \"%s\""
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "creazione dello slot di replica \"%s\""
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "disconnesso"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "disconnesso; in attesa di %d secondi per riprovare"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s controlla i flussi di decodifica logica di PostgreSQL.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Azioni da effettuare:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr " --start avvia lo streaming in uno slot di replica (per il nome vedi --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=FILE riceve i log in questo file, - per stdout\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F --fsync-interval=SEC\n"
+" tempo tra i sync del file di output (default: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN dove deve partire lo streaming in uno slot esistente\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NOME[=VALORE]\n"
+" passa l'opzione NOME col valore opzionale VALORE\n"
+" al plugin di output\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN usa il plugin di output PLUGIN (default: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=NOMESLOT nome dello slot di replica logica\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase abilita la decodifica delle transazioni preparate durante la creazione di uno slot\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=NOMEDB database a cui connettersi\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "conferma scrittura fino a %X/%X, svuota fino a %X/%X (slot %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "impossibile inviare il pacchetto di feedback: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "avvio dello streaming del registro a %X/%X (slot %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "streaming avviato"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "apertura del file di log \"%s\" fallita: %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "socket non valido: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() non riuscito: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "ricezione dati dallo stream WAL fallita: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "intestazione streaming troppo piccola: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "intestazione streaming non riconosciuta: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "impossibile scrivere %d byte nel file di registro \"%s\": %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "interruzione imprevista del flusso di replica: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "impossibile analizzare la posizione iniziale \"%s\""
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "nessuno slot specificato"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "nessun file di destinazione specificato"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "nessun database specificato"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "è necessario specificare almeno un'azione"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "non può usare --create-slot o --start insieme a --drop-slot"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "non è possibile utilizzare --create-slot o --drop-slot insieme a --startpos"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos può essere specificato solo con --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase può essere specificato solo con --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "non è stato possibile stabilire una connessione di replica specifica del database"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "posizione finale %X/%X raggiunta da keepalive"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "posizione finale %X/%X raggiunta dal record WAL a %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "impossibile creare il file di stato dell'archivio \"%s\": %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "impossibile chiudere il file di stato dell'archivio \"%s\": %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "impossibile ottenere la dimensione del file di registro write-ahead \"%s\": %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "impossibile aprire il file di registro write-ahead esistente \"%s\": %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "impossibile sincronizzare il file di registro write-ahead esistente \"%s\": %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "il file di registro write-ahead \"%s\" contiene %zd byte, dovrebbe essere 0 o %d"
+msgstr[1] "il files di registro write-ahead \"%s\" contengono %zd byte, dovrebbe essere 0 o %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "impossibile aprire il file di registro write-ahead \"%s\": %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "impossibile determinare la posizione di ricerca nel file \"%s\": %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "non rinominando \"%s\", il segmento non è completo"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "impossibile chiudere il file \"%s\": %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "il server ha segnalato il nome del file della cronologia imprevisto per la sequenza temporale %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "impossibile creare il file della cronologia della sequenza temporale \"%s\": %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "impossibile scrivere il file della cronologia della sequenza temporale \"%s\": %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "versione server incompatibile %s; il client non supporta lo streaming da versioni del server precedenti a %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "versione server incompatibile %s; il client non supporta lo streaming da versioni del server successive a %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "l'identificatore di sistema non corrisponde tra il backup di base e la connessione in streaming"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "sequenza temporale di inizio %u non è presente nel server"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "risposta inaspettata al comando TIMELINE_HISTORY: ottenuto %d righe e %d campi, previsto %d righe e %d campi"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "il server ha segnalato la sequenza temporale successiva inaspettata %u, dopo la sequenza temporale %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "il server ha interrotto lo streaming della sequenza temporale %u alle %X/%X, ma ha segnalato che la sequenza temporale successiva %u inizia alle %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "flusso di replica è stato terminato prima del punto di arresto"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "set di risultati imprevisti dopo la fine della sequenza temporale: ottenuto %d righe e %d campi, previsti %d righe e %d campi"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "impossibile analizzare il punto iniziale della sequenza temporale successiva \"%s\""
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "impossibile sincronizzare il file \"%s\": %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "ha ricevuto il record di registro write-ahead per l'offset %u senza file aperti"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "ottenuto offset dati WAL %08x, previsto %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "impossibile scrivere %d byte nel file WAL \"%s\": %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "impossibile inviare il pacchetto di fine copia: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Password: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "non poteva collegarsi al server"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "pulizia del search_path fallita: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "impossibile determinare l'impostazione del server per integer_datetimes"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "integer_datetimes flag di compilazione non corrisponde al server"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "impossibile recuperare la dimensione del segmento WAL: ottenuto %d righe e %d campi, previsto %d righe e %d o più campi"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "Impossibile analizzare la dimensione del segmento WAL"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "La dimensione del segmento WAL deve essere una potenza di due tra 1 MB e 1 GB, ma il server remoto ha riportato un valore di %d byte"
+msgstr[1] "La dimensione dei segmenti WAL deve essere una potenza di due tra 1 MB e 1 GB, ma il server remoto ha riportato un valore di %d byte"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "impossibile recuperare il flag di accesso al gruppo: ottenuto %d righe e %d campi, previsto %d righe e %d o più campi"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "Impossibile analizzare il flag di accesso al gruppo: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "impossibile identificare il sistema: ottenuto %d righe e %d campi, previsto %d righe e %d o più campi"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "impossibile leggere lo slot di replica \"%s\": ottenuto %d righe e %d campi, previsto %d righe e %d campi"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "lo slot di replica \"%s\" non esiste"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "previsto uno slot di replica fisico, è stato invece ottenuto il tipo \"%s\"."
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "impossibile analizzare restart_lsn \"%s\" per lo slot di replica \"%s\""
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "impossibile creare lo slot di replica \"%s\": ottenuto %d righe e %d campi, previsto %d righe e %d campi"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "impossibile eliminare lo slot di replica \"%s\": ottenuto %d righe e %d campi, previsto %d righe e %d campi"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "compressione dei dati fallita"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "reset dello stream di compressione fallito"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "errore di implementazione: i file tar non possono avere più di un file aperto"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "creazione dell'intestazione del tar fallita"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "modifica dei parametri di compressione fallita"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "unlink non supportato con la compressione"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "chiusura dello stream di compressione fallita"
+
+#~ msgid " -Z, --compress=0-9 compress logs with given compression level\n"
+#~ msgstr " -Z, --compress=0-9 comprimi i log con questo livello di compressoine\n"
+
+#~ msgid " -Z, --compress=0-9 compress tar output with given compression level\n"
+#~ msgstr " -Z, --compress=0-9 comprimi l'output tar a questo livello di compressione\n"
+
+#~ msgid "%s: --create-slot and --no-slot are incompatible options\n"
+#~ msgstr "%s: --create-slot e --no-slot sono opzioni incompatibili\n"
+
+#~ msgid "%s: child process did not exit normally\n"
+#~ msgstr "%s: il processo figlio non è terminato normalmente\n"
+
+#~ msgid "%s: child process exited with error %d\n"
+#~ msgstr "%s: il processo figlio è terminato con errore %d\n"
+
+#~ msgid "%s: could not access directory \"%s\": %s\n"
+#~ msgstr "%s: accesso alla directory \"%s\" fallito: %s\n"
+
+#~ msgid "%s: could not clear search_path: %s"
+#~ msgstr "%s: pulizia del search_path fallita: %s"
+
+#~ msgid "%s: could not close directory \"%s\": %s\n"
+#~ msgstr "%s: chiusura della directory \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not close file \"%s\": %s\n"
+#~ msgstr "%s: chiusura del file \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not connect to server\n"
+#~ msgstr "%s: connessione al server fallita\n"
+
+#~ msgid "%s: could not connect to server: %s"
+#~ msgstr "%s: connessione al server fallita: %s"
+
+#~ msgid "%s: could not create archive status file \"%s\": %s\n"
+#~ msgstr "%s: creazione del file di stato dell'archivio \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not create directory \"%s\": %s\n"
+#~ msgstr "%s: creazione della directory \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not create file \"%s\": %s\n"
+#~ msgstr "%s: creazione del file \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not create symbolic link \"%s\": %s\n"
+#~ msgstr "%s: creazione del link simbolico \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not fsync file \"%s\": %s\n"
+#~ msgstr "%s: fsync del file \"%s\" fallito: %s\n"
+
+#~ msgid "%s: could not fsync log file \"%s\": %s\n"
+#~ msgstr "%s: fsync del file di log \"%s\" fallito: %s\n"
+
+#~ msgid "%s: could not get write-ahead log end position from server: %s"
+#~ msgstr "%s: non è stato possibile ottenere la posizione finale del write-ahead log dal server: %s"
+
+#~ msgid "%s: could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields\n"
+#~ msgstr "%s: identificazione del sistema fallita: ricevute %d righe e %d campi, attese %d righe e %d o più campi\n"
+
+#~ msgid "%s: could not open directory \"%s\": %s\n"
+#~ msgstr "%s: apertura della directory \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not open file \"%s\": %s\n"
+#~ msgstr "%s: apertura del file \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not open log file \"%s\": %s\n"
+#~ msgstr "%s: apertura del file di log \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not open write-ahead log file \"%s\": %s\n"
+#~ msgstr "%s: apertura del file di write-ahead log \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not read directory \"%s\": %s\n"
+#~ msgstr "%s: lettura della directory \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not receive data from WAL stream: %s"
+#~ msgstr "%s: ricezione dati dallo stream WAL fallita: %s"
+
+#~ msgid "%s: could not rename file \"%s\" to \"%s\": %s\n"
+#~ msgstr "%s: non è stato possibile rinominare il file di storia della timeline \"%s\" in \"%s\": %s\n"
+
+#~ msgid "%s: could not set permissions on directory \"%s\": %s\n"
+#~ msgstr "%s: impostazione dei permessi sulla directory \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not set permissions on file \"%s\": %s\n"
+#~ msgstr "%s: impostazione dei permessi sul file \"%s\" fallita: %s\n"
+
+#~ msgid "%s: could not stat file \"%s\": %s\n"
+#~ msgstr "%s: non è stato possibile ottenere informazioni sul file \"%s\": %s\n"
+
+#~ msgid "%s: could not write to file \"%s\": %s\n"
+#~ msgstr "%s: scrittura nel file \"%s\" fallita: %s\n"
+
+#~ msgid "%s: invalid compression level \"%s\"\n"
+#~ msgstr "%s: livello di compressione non valido \"%s\"\n"
+
+#~ msgid "%s: invalid fsync interval \"%s\"\n"
+#~ msgstr "%s: intervallo di fsync \"%s\" non valido\n"
+
+#~ msgid "%s: invalid port number \"%s\"\n"
+#~ msgstr "%s: numero di porta non valido \"%s\"\n"
+
+#~ msgid "%s: invalid status interval \"%s\"\n"
+#~ msgstr "%s: intervallo di status \"%s\" non valido\n"
+
+#~ msgid "%s: invalid tar block header size: %d\n"
+#~ msgstr "%s: dimensione del blocco di intestazione del file tar non valida: %d\n"
+
+#~ msgid "%s: out of memory\n"
+#~ msgstr "%s: memoria esaurita\n"
+
+#~ msgid "%s: select() failed: %s\n"
+#~ msgstr "%s: select() fallita: %s\n"
+
+#~ msgid "%s: symlinks are not supported on this platform\n"
+#~ msgstr "%s: questa piattaforma non supporta i link simbolici\n"
+
+#~ msgid "%s: unrecognized link indicator \"%c\"\n"
+#~ msgstr "%s: indicatore di link sconosciuto \"%c\"\n"
+
+#~ msgid "Try \"%s --help\" for more information.\n"
+#~ msgstr "Prova \"%s --help\" per maggiori informazioni.\n"
diff --git a/src/bin/pg_basebackup/po/ja.po b/src/bin/pg_basebackup/po/ja.po
new file mode 100644
index 0000000..8ff0f6e
--- /dev/null
+++ b/src/bin/pg_basebackup/po/ja.po
@@ -0,0 +1,1813 @@
+# pg_basebackup.po
+# Japanese message translation file for pg_basebackup
+#
+# Copyright (C) 2013-2022 PostgreSQL Global Development Group
+#
+# This file is distributed under the same license as the PostgreSQL package.
+#
+# <iwata.aya@jp.fujitsu.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL 15)\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-09-26 11:13+0900\n"
+"PO-Revision-Date: 2022-09-26 14:52+0900\n"
+"Last-Translator: Kyotaro Horiguchi <horikyota.ntt@gmail.com>\n"
+"Language-Team: Japan PostgreSQL Users Group <jpug-doc@ml.postgresql.jp>\n"
+"Language: ja\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 1.8.13\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "エラー: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "警告: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "詳細: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "ヒント: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "このビルドでは%sによる圧縮をサポートしていません"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "圧縮オプションがあるはずの場所に空文字列が見つかりました"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "認識できない圧縮オプション: \"%s\""
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "圧縮オプション\"%s\"には値が必要です"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "圧縮オプション\"%s\"の値は整数でなければなりません"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "圧縮アルゴリズム\"%s\"は圧縮レベルを受け付けません"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "圧縮アルゴリズム\"%s\"では%dから%dまでの圧縮レベルが指定可能です(デフォルトは%d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "圧縮アルゴリズム\"%s\"はワーカー数を受け付けません"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "メモリ不足です\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "null ポインタを複製できません (内部エラー)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "ファイル\"%s\"のstatに失敗しました: %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "ディレクトリ\"%s\"をオープンできませんでした: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "ディレクトリ\"%s\"を読み取れませんでした: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "ファイル\"%s\"をオープンできませんでした: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "ファイル\"%s\"をfsyncできませんでした: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2256 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "ファイル\"%s\"の名前を\"%s\"に変更できませんでした: %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "オプション\"%2$s\"に対する不正な値\"%1$s\""
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%sは%d..%dの範囲でなければなりません"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1636
+#, c-format
+msgid "out of memory"
+msgstr "メモリ不足です"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1433 pg_basebackup.c:1727
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "ファイル\"%s\"を書き込めませんでした: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1497 pg_basebackup.c:1706
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "ファイル\"%s\"を作成できませんでした: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "ファイル\"%s\"をクローズできませんでした: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "アーカイブの抽出中に想定外の状態"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:686 pg_basebackup.c:730
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "ディレクトリ\"%s\"を作成できませんでした: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "ディレクトリ\"%s\"に権限を設定できませんでした: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "\"%s\"から\"%s\"へのシンボリックリンクを作成できませんでした: %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "ファイル\"%s\"の権限を設定できませんでした: %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "圧縮ファイル\"%s\"を作成できませんでした: %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "標準出力の複製に失敗しました: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "出力ファイルをオープンできませんでした: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "圧縮レベルを%dに設定できませんでした: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "このビルドではgzip圧縮をサポートしていません"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "圧縮ファイル\"%s\"に書き込めませんでした: %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "圧縮ファイル\"%s\"をクローズすることができませんでした: %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "圧縮ライブラリを初期化できませんでした"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "データを伸張できませんでした: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "リカバリ設定の出力中に想定外の状態"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "lz4圧縮コンテクストを生成できませんでした: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "このビルドではlz4圧縮をサポートしていません"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "lz4ヘッダを出力できませんでした: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "データを圧縮できませんでした: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "lz4圧縮を終了できませんでした: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "圧縮ライブラリを初期化できませんでした: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "tarファイル後続ブロックが2ブロックを超えています"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "tarアーカイブのパース中に想定外の状態"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "tarメンバーの名前が空です"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "最後のファイルが終わる前にCOPYストリームが終了しました"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "zstd圧縮コンテクストを生成できませんでした"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "zstd圧縮レベルを%dに設定できませんでした: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "圧縮ワーカー数を%dに設定できませんでした: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "このビルドではzstd圧縮をサポートしていません"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "zstd伸張コンテクストを生成できませんでした"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "データディレクトリ\"%s\"を削除しています"
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "データディレクトリの削除に失敗しました"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "データディレクトリ\"%s\"の内容を削除しています"
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "データディレクトリの中身の削除に失敗しました"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "WAL ディレクトリ\"%s\"を削除しています"
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "WAL ディレクトリの削除に失敗しました"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "WAL ディレクトリ\"%s\"の中身を削除しています"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "WAL ディレクトリの中身の削除に失敗しました"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "ユーザーの要求により、データディレクトリ\"%s\"を削除しませんでした"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "ユーザーの要求により、WAL ディレクトリ\"%s\"を削除しませんでした"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "テーブル空間用ディレクトリへの変更は取り消されません"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "ディレクトリ名が長すぎます"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "テーブル空間のマッピングに複数の\"=\"記号があります"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "テーブル空間のマッピング形式\"%s\"が不正です。\"旧DIR=新DIR\"でなければなりません"
+
+#: pg_basebackup.c:351
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "テーブル空間のマッピングにおいて、旧ディレクトリが絶対パスではありません: %s"
+
+#: pg_basebackup.c:355
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "テーブル空間のマッピングにおいて、新ディレクトリが絶対パスではありません: %s"
+
+#: pg_basebackup.c:377
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%sは実行中のPostgreSQLサーバーのベースバックアップを取得します。\n"
+"\n"
+
+#: pg_basebackup.c:379 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "使用方法:\n"
+
+#: pg_basebackup.c:380 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [オプション]...\n"
+
+#: pg_basebackup.c:381
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"出力を制御するオプション:\n"
+
+#: pg_basebackup.c:382
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=DIRECTORY ベースバックアップをディレクトリ内に格納\n"
+
+#: pg_basebackup.c:383
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t 出力フォーマット(プレイン(デフォルト)またはtar)\n"
+
+#: pg_basebackup.c:384
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=RATE データディレクトリ転送の際の最大転送速度\n"
+" (kB/s 単位、または 接尾辞 \"k\" か\"M\" を使用)\n"
+
+#: pg_basebackup.c:386
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" レプリケーションのための設定を書き込む\n"
+
+#: pg_basebackup.c:388
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=ターゲット[:詳細]\n"
+" バックアップターゲット(クライアント以外の場合)\n"
+
+#: pg_basebackup.c:390
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=旧DIR=新DIR\n"
+" テーブル空間を旧DIRから新DIRに移動する\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=WALDIR 先行書き込みログ用ディレクトリの位置\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" 要求されたWALファイルを指定の方式でバックアップ\n"
+" に含める\n"
+
+#: pg_basebackup.c:395
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip tar の出力を圧縮する\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]方式[:詳細]\n"
+" 指定に従ってクライアント側またはサーバー側で圧縮\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none tar出力を圧縮しない\n"
+
+#: pg_basebackup.c:399
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"汎用オプション:\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" 高速または分散チェックポイント処理の指定\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot 新しいレプリケーションスロットを作成する\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL バックアップラベルの設定\n"
+
+#: pg_basebackup.c:404
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --noclean エラー発生後作成したファイルの削除を行わない\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " -N, --nosync ディスクへの安全な書き込みを待機しない\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress 進行状況の表示\n"
+
+#: pg_basebackup.c:407 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=スロット名 使用するレプリケーションスロット\n"
+
+#: pg_basebackup.c:408 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose 冗長メッセージの出力\n"
+
+#: pg_basebackup.c:409 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version バージョン情報を表示して終了\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" 目録チェックサムに使用するアルゴリズム\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" 目録中の全てのファイル名を16進エンコードする\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size サーバー側でバックアップサイズを見積もらない\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest バックアップ目録の作成を省略する\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot 一時レプリケーションスロットの作成を行わない\n"
+
+#: pg_basebackup.c:417
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" チェックサムを検証しない\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help このヘルプを表示して終了\n"
+
+#: pg_basebackup.c:420 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"接続オプション:\n"
+
+#: pg_basebackup.c:421 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONNSTR 接続文字列\n"
+
+#: pg_basebackup.c:422 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=HOSTNAME データベースサーバーホストまたはソケットディレクトリ\n"
+
+#: pg_basebackup.c:423 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT データベースサーバーのポート番号\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVAL\n"
+" サーバーへ送出するステータスパケットの間隔(秒単位)\n"
+
+#: pg_basebackup.c:426 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NAME 指定したデータベースユーザーで接続\n"
+
+#: pg_basebackup.c:427 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password パスワードの入力を要求しない\n"
+
+#: pg_basebackup.c:428 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr " -W, --password パスワード入力要求を強制(自動的に行われるはず)\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"バグは<%s>に報告してください。\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s ホームページ: <%s>\n"
+
+#: pg_basebackup.c:472
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "準備ができたパイプからの読み込みが失敗しました: %m"
+
+#: pg_basebackup.c:475 pg_basebackup.c:622 pg_basebackup.c:2170
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "先行書き込みログの位置\"%s\"をパースできませんでした"
+
+#: pg_basebackup.c:581 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "WALファイルの書き込みを終了できませんでした: %m"
+
+#: pg_basebackup.c:631
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "バックグランドプロセス用のパイプを作成できませんでした: \"%m"
+
+#: pg_basebackup.c:664
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "一時レプリケーションスロット\"%s\"を作成しました"
+
+#: pg_basebackup.c:667
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "レプリケーションスロット\"%s\"を作成していました"
+
+#: pg_basebackup.c:701
+#, c-format
+msgid "could not create background process: %m"
+msgstr "バックグラウンドプロセスを生成できませんでした: %m"
+
+#: pg_basebackup.c:710
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "バックグラウンドスレッドを生成できませんでした: %m"
+
+#: pg_basebackup.c:749
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "ディレクトリ\"%s\"は存在しますが空ではありません"
+
+#: pg_basebackup.c:755
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "ディレクトリ\"%s\"にアクセスできませんでした: %m"
+
+#: pg_basebackup.c:832
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d テーブル空間 %*s"
+
+#: pg_basebackup.c:844
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d テーブル空間 (%s%-*.*s)"
+
+#: pg_basebackup.c:860
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d テーブル空間"
+
+#: pg_basebackup.c:884
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "転送速度\"%s\"は無効な値です"
+
+#: pg_basebackup.c:886
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "転送速度\"%s\"は無効です: %m"
+
+#: pg_basebackup.c:893
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "転送速度は0より大きな値でなければなりません"
+
+#: pg_basebackup.c:923
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "--max-rate の単位が不正です: \"%s\""
+
+#: pg_basebackup.c:927
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "転送速度\"%s\"がintegerの範囲を超えています"
+
+#: pg_basebackup.c:934
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "転送速度\"%s\"が範囲外です"
+
+#: pg_basebackup.c:1030
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "COPYデータストリームを取得できませんでした: %s"
+
+#: pg_basebackup.c:1047 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "COPYデータを読み取ることができませんでした: %s"
+
+#: pg_basebackup.c:1051
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "バックグラウンドプロセスが突然終了しました"
+
+#: pg_basebackup.c:1122
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "圧縮tarファイルには目録は出力できません"
+
+#: pg_basebackup.c:1123
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "クライアントサイド圧縮を使用して標準出力ではなくディレクトリに出力する、または %s を使用してください。"
+
+#: pg_basebackup.c:1139
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "アーカイブ\"%s\"のパースができませんでした"
+
+#: pg_basebackup.c:1140
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "tarアーカイブのみパース可能です。"
+
+#: pg_basebackup.c:1142
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Plainフォーマットではpg_basebackupがアーカイブをパースする必要があります。"
+
+#: pg_basebackup.c:1144
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "出力ディレクトリに - を指定する際にはpg_basebackupがアーカイブをパースする必要があります。"
+
+#: pg_basebackup.c:1146
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "-Rオプションを指定する場合はpg_basebackupがアーカイブをパースする必要があります。"
+
+#: pg_basebackup.c:1357
+#, c-format
+msgid "archives must precede manifest"
+msgstr "アーカイブは目録より先にあるはずです"
+
+#: pg_basebackup.c:1372
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "不正なアーカイブ名: \"%s\""
+
+#: pg_basebackup.c:1444
+#, c-format
+msgid "unexpected payload data"
+msgstr "予期しないペイロードのデータ"
+
+#: pg_basebackup.c:1587
+#, c-format
+msgid "empty COPY message"
+msgstr "空のCOPYメッセージ"
+
+#: pg_basebackup.c:1589
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "タイプ%d、長さ%zuのCOPYメッセージのフォーマット異常"
+
+#: pg_basebackup.c:1787
+#, c-format
+msgid "incompatible server version %s"
+msgstr "非互換のサーバーバージョン \"%s\""
+
+#: pg_basebackup.c:1803
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "-X none または -X fetch でログストリーミングを無効にできます。"
+
+#: pg_basebackup.c:1871
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "バックアップターゲットはこのサーバーバージョンではサポートされません"
+
+#: pg_basebackup.c:1874
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "バックアップターゲットが使用されている場合にはリカバリ設定は出力できません"
+
+#: pg_basebackup.c:1901
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "サーバーはサーバーサイド圧縮をサポートしていません"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "ベースバックアップを開始しています - チェックポイントの完了を待機中"
+
+#: pg_basebackup.c:1915
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "チェックポイントを待っています"
+
+#: pg_basebackup.c:1928 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "レプリケーションコマンド\"%s\"を送信できませんでした: %s"
+
+#: pg_basebackup.c:1936
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "ベースバックアップを開始できませんでした: %s"
+
+#: pg_basebackup.c:1939
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "サーバーが BASE_BACKUP コマンドに期待していない応答を返しました; %d行 %d列を受信しましたが期待は %d列 %d行でした"
+
+#: pg_basebackup.c:1945
+#, c-format
+msgid "checkpoint completed"
+msgstr "チェックポイントが完了しました"
+
+#: pg_basebackup.c:1960
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "先行書き込みログの開始ポイント: タイムライン %2$u 上の %1$s"
+
+#: pg_basebackup.c:1968
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "バックアップヘッダを取得できませんでした: %s"
+
+#: pg_basebackup.c:1971
+#, c-format
+msgid "no data returned from server"
+msgstr "サーバーからデータが返されませんでした"
+
+#: pg_basebackup.c:2006
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "標準出力に書き出せるテーブル空間は1つだけですが、データベースには%d個あります"
+
+#: pg_basebackup.c:2019
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "バックグランドWAL受信処理を起動します"
+
+#: pg_basebackup.c:2101
+#, c-format
+msgid "backup failed: %s"
+msgstr "バックアップが失敗しました: %s"
+
+#: pg_basebackup.c:2104
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "サーバーから先行書き込みログの終了位置が返されませんでした"
+
+#: pg_basebackup.c:2107
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "先行書き込みログの終了ポイント: %s"
+
+#: pg_basebackup.c:2118
+#, c-format
+msgid "checksum error occurred"
+msgstr "チェックサムエラーが発生しました"
+
+#: pg_basebackup.c:2123
+#, c-format
+msgid "final receive failed: %s"
+msgstr "終端の受信に失敗しました: %s"
+
+#: pg_basebackup.c:2147
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "バックグランドプロセスがストリーミング処理が終わるまで待機します ..."
+
+#: pg_basebackup.c:2151
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "バックグランドへのパイプにコマンドを送信できませんでした: %m"
+
+#: pg_basebackup.c:2156
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "子プロセスの待機ができませんでした: %m"
+
+#: pg_basebackup.c:2158
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "子プロセス %d が終了しましたが、期待していたのは %d でした"
+
+#: pg_basebackup.c:2160 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2180
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "子スレッドの待機ができませんでした: %m"
+
+#: pg_basebackup.c:2185
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "子スレッドの終了ステータスを取得できませんでした: %m"
+
+#: pg_basebackup.c:2188
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "子スレッドがエラー%uで終了しました"
+
+#: pg_basebackup.c:2217
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "データをディスクに同期しています..."
+
+#: pg_basebackup.c:2242
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "backup_manifest.tmp の名前を backup_manifest に変更してください"
+
+#: pg_basebackup.c:2262
+#, c-format
+msgid "base backup completed"
+msgstr "ベースバックアップが完了しました"
+
+#: pg_basebackup.c:2351
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "不正な出力フォーマット\"%s\"、\"plain\"か\"tar\"でなければなりません"
+
+#: pg_basebackup.c:2395
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "不正な wal-method オプション\"%s\"、\"fetch\"、\"stream\" または \"none\" のいずれかでなければなりません"
+
+#: pg_basebackup.c:2425
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "不正な checkpoint の引数\"%s\"、\"fast\" または \"spreadでなければなりません"
+
+#: pg_basebackup.c:2476 pg_basebackup.c:2488 pg_basebackup.c:2510
+#: pg_basebackup.c:2522 pg_basebackup.c:2528 pg_basebackup.c:2580
+#: pg_basebackup.c:2591 pg_basebackup.c:2601 pg_basebackup.c:2607
+#: pg_basebackup.c:2614 pg_basebackup.c:2626 pg_basebackup.c:2638
+#: pg_basebackup.c:2646 pg_basebackup.c:2659 pg_basebackup.c:2665
+#: pg_basebackup.c:2674 pg_basebackup.c:2686 pg_basebackup.c:2697
+#: pg_basebackup.c:2705 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "詳細は\"%s --help\"を実行してください。"
+
+#: pg_basebackup.c:2486 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "コマンドライン引数が多過ぎます(先頭は\"%s\"です)"
+
+#: pg_basebackup.c:2509
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "フォーマットとバックアップターゲットの両方を同時には指定できません"
+
+#: pg_basebackup.c:2521
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "出力ディレクトリかバックアップターゲットを指定する必要があります"
+
+#: pg_basebackup.c:2527
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "出力先ディレクトリとバックアップターゲットの両方を同時には指定できません"
+
+#: pg_basebackup.c:2557 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "認識できない圧縮アルゴリズム\"%s\""
+
+#: pg_basebackup.c:2563 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "不正な圧縮指定: %s"
+
+#: pg_basebackup.c:2579
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "バックアップターゲットが指定されているとクライアントサイド圧縮はできません"
+
+#: pg_basebackup.c:2590
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "tarモードでのバックアップのみが圧縮可能です"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "バックアップターゲット指定されているとWALはストリーム出力できません"
+
+#: pg_basebackup.c:2606
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "標準出力への tar モードでは書き込み先行ログをストリーム出力できません"
+
+#: pg_basebackup.c:2613
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "レプリケーションスロットはWALストリーミングでのみ使用可能です"
+
+#: pg_basebackup.c:2625
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot はスロット名と同時には指定できません"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2636 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s は --slot でスロットを指定する必要があります"
+
+#: pg_basebackup.c:2644 pg_basebackup.c:2684 pg_basebackup.c:2695
+#: pg_basebackup.c:2703
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s と %s は非互換なオプションです"
+
+#: pg_basebackup.c:2658
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "WALディレクトリの位置はバックアップターゲットと同時には指定できません"
+
+#: pg_basebackup.c:2664
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "WALディレクトリの位置は plainモードでのみ指定可能です"
+
+#: pg_basebackup.c:2673
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "WALディレクトリの位置は、絶対パスでなければなりません"
+
+#: pg_basebackup.c:2774
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "シンボリックリンク\"%s\"を作成できませんでした: %m"
+
+#: pg_basebackup.c:2776
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "このプラットフォームでシンボリックリンクはサポートされていません"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%sはPostgreSQLの先行書き込みログストリームを受信します。\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"オプション:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=DIR 受信した先行書き込みログの格納ディレクトリ\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN 指定したLSNの受信後に終了\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr "   --if-not-exists スロットの作成時に既に存在していてもエラーとしない\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop 接続断の際にループしない\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " --no-sync ディスクへの安全な書き込みの待機を行わない\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SECS\n"
+" サーバーへ送出するステータスパケットの間隔\n"
+" (デフォルト: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous 先行書き込みログを書き込み後直ちにフラッシュ\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=方式[:詳細]\n"
+" 指定のとおり圧縮\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"追加の動作:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr ""
+" --create-slot 新しいレプリケーションスロットを作成する\n"
+" (スロット名については --slot を参照)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr ""
+" --drop-slot レプリケーションスロットを削除する\n"
+" (スロット名については --slot を参照)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "%X/%X (タイムライン %u)でセグメントが完了"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "%X/%X (タイムライン %u)でログのストリーミングを停止しました"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "%3$X/%2$Xで タイムライン%1$uに切り替えました"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "割り込みシグナルを受信、終了します"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "ディレクトリ\"%s\"をクローズできませんでした: %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "セグメントファイル\"%s\"のサイズ%lldが間違っています、スキップします"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "圧縮ファイル\"%s\"を開けませんでした: %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "圧縮ファイル\"%s\"でseekできませんでした: %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "圧縮ファイル\"%s\"を読めませんでした: %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "圧縮ファイル\"%1$s\"を読めませんでした: %3$zuバイトのうち%2$dバイトを読み込み済み"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "圧縮セグメントファイル\"%s\"の展開後サイズ%dが不正です、スキップします"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "LZ4伸張コンテキストを作成できませんでした: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "ファイル\"%s\"の読み取りに失敗しました: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "ファイル\"%s\"を伸張できませんでした: %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "LZ4伸張コンテクストを解放きませんでした: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "圧縮セグメントファイル\"%s\"の伸張後のサイズ%zuが不正です、スキップします"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "ファイル\"%s\"の確認ができません: %sによる圧縮はこのビルドではサポートされません"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "%X/%X (タイムライン %u)からログのストリーミングを開始"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "終了位置\"%s\"をパースできませんでした"
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "--create-slot は --drop-slot と同時には指定できません"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "--synchronous は --no-sync と同時には指定できません"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "格納先ディレクトリが指定されていません"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "%sによる圧縮`まだサポートされていません"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "スロット\"%s\"を使用するレプリケーション接続で、想定に反してデータベースが指定されています"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "レプリケーションスロット\"%s\"を削除しています"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "レプリケーションスロット\"%s\"を作成しています"
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "切断しました"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "切断しました; %d秒待機して再試行します"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s はPostgreSQLの論理デコードストリームを制御します。\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"実行する動作:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr ""
+" --start レプリケーションスロットでストリーミングを開始する\n"
+" (スロット名については --slot を参照)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=FILE このファイルにログを受け取る、 - で標準出力\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F --fsync-interval=SECS\n"
+" 出力ファイルへのfsync時間間隔(デフォルト: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN 既存スロット内のストリーミング開始位置\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NAME[=VALUE]\n"
+" 出力プラグインにオプションNAMEをオプション値VALUEと\n"
+" ともに渡す\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN 出力プラグインPLUGINを使う(デフォルト: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOTNAME 論理レプリケーションスロットの名前\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase スロット作成時にプリペアドトランザクションのデコードを有効にする\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=DBNAME 接続先データベース\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "PrecPpg%X/%Xまでの書き込みと、%X/%X (スロット %s)までのフラッシュを確認しています"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "フィードバックパケットを送信できませんでした: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "%X/%X (スロット %s)からログのストリーミングを開始します"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "ストリーミングを開始しました"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "ロックファイル\"%s\"をオープンできませんでした: %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "無効なソケット: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() が失敗しました: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "WAL ストリームからデータを受信できませんでした: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "ストリーミングヘッダが小さ過ぎます: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "ストリーミングヘッダを認識できませんでした: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "%dバイトをログファイル\"%s\"に書き込めませんでした: %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "レプリケーションストリームが突然終了しました: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "開始位置\"%s\"をパースできませんでした"
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "スロットが指定されていません"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "ターゲットファイルが指定されていません"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "データベースが指定されていません"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "少なくとも一つのアクションを指定する必要があります"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "--create-slot や --start は --drop-slot と同時には指定できません"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "--create-slot や --drop-slot は --startpos と同時には指定できません"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos は --start が指定されているときにのみ指定可能です"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phaseは--create-slotが指定されているときにのみ指定可能です"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "データベース指定のレプリケーション接続が確立できませんでした"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "キープアライブで終了位置 %X/%X に到達しました "
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "%X/%X のWALレコードで終了位置 %X/%X に到達しました"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "アーカイブステータスファイル\"%s\"を作成できませんでした: %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "アーカイブステータスファイル\"%s\"をクローズできませんでした: %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "先行書き込みログファイル\"%s\"のサイズを取得できませんでした: %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "既存の先行書き込みログファイル\"%s\"をオープンできませんでした: %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "既存の先行書き込みログファイル\"%s\"をfsyncできませんでした: %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "先行書き込みログファイル\"%s\"は%zdバイトですが、0または%dであるはずです"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "先行書き込みログファイル\"%s\"をオープンできませんでした: %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "ファイル\"%s\"のシーク位置を取得できませんでした: %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "\"%s\"の名前を変更しません、セグメントが完成していません"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "ファイル\"%s\"をクローズできませんでした: %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "サーバーがタイムライン%uに対する想定外の履歴ファイル名を通知してきました: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "タイムライン履歴ファイル\"%s\"を作成できませんでした: %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "タイムライン履歴ファイル\"%s\"に書き込めませんでした: %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "非互換のサーバーバージョン%s、クライアントは%sより古いサーバーバージョンからのストリーミングをサポートしていません"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "非互換のサーバーバージョン%s、クライアントは%sより新しいサーバーバージョンからのストリーミングをサポートしていません"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "システム識別子がベースバックアップとストリーミング接続の間で一致しません"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "開始タイムライン%uがサーバーに存在しません"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "TIMELINE_HISTORYコマンドへの想定外の応答: 受信したのは%d行%d列、想定は%d行%d列"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "サーバーがタイムライン%2$uに続いて想定外のタイムライン%1$uを通知してきました"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "サーバーはタイムライン%uのストリーミングを%X/%Xで停止しました、しかし次のタイムライン%uが%X/%Xから開始すると通知してきています"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "レプリケーションストリームが停止ポイントより前で終了しました"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "タイムライン終了後に想定外の結果セット: 受信したのは%d行%d列、想定は%d行%d列"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "次のタイムラインの開始ポイント\"%s\"をパースできませんでした"
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "ファイル\"%s\"をfsyncできませんでした: %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "ファイルがオープンされていない状態で、オフセット%uに対する先行書き込みログレコードを受信しました"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "WALデータオフセット%08xを受信、想定は%08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "WALファイル\"%2$s\"に%1$dバイト書き込めませんでした: %3$s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "コピー終端パケットを送信できませんでした: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "パスワード: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "サーバーに接続できませんでした"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "search_pathを消去できませんでした: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "integer_datetimesのサーバー設定を取得できませんでした"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "integer_datetimesコンパイル時フラグがサーバーと一致しません"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "WALセグメントサイズを取得できませんでした: 受信したのは%d行で%d列、想定は%d行で%d列以上"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "WALセグメントサイズがパースできませんでした"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "WALセグメントのサイズ指定は1MBと1GBの間の2の累乗でなければなりません、しかし対向サーバーは%dバイトと報告してきました"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "グループアクセスフラグを取得できませんでした: 受信したのは%d行で%d列、想定は%d行で%d列以上"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "グループアクセスフラグがパースできませんでした: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "システムを識別できませんでした: 受信したのは%d行%d列、想定は%d行%d列以上"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "レプリケーションスロット\"%s\"を読み取れませんでした: 受信したのは%d行%d列、想定は%d行%d列"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "レプリケーションスロット\"%s\"は存在しません"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "物理レプリケーションスロットが必要ですが、タイプは\"%s\"でした"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "レプリケーションスロット\"%2$s\"のrestart_lsn\"%1$s\"をパースできませんでした"
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "レプリケーションスロット\"%s\"を作成できませんでした: 受信したのは%d行%d列、想定は%d行%d列"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "レプリケーションスロット\"%s\"を削除できませんでした: 受信したのは%d行%d列、想定は%d行%d列"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "データを圧縮できませんでした"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "圧縮ストリームをリセットできませんでした"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "実装エラー:tar ファイルが複数のオープンされたファイルを保持できません"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "tar ヘッダを作成できませんでした"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "圧縮用パラメーターを変更できませんでした"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "圧縮モードにおける unlink はサポートしていません"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "圧縮ストリームをクローズできませんでした"
diff --git a/src/bin/pg_basebackup/po/ka.po b/src/bin/pg_basebackup/po/ka.po
new file mode 100644
index 0000000..82f7b89
--- /dev/null
+++ b/src/bin/pg_basebackup/po/ka.po
@@ -0,0 +1,1997 @@
+# Georgian message translation file for pg_basebackup
+# Copyright (C) 2022 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_basebackup (PostgreSQL) package.
+# Temuri Doghonadze <temuri.doghonadze@gmail.com>, 2022.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL) 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-09-25 19:48+0000\n"
+"PO-Revision-Date: 2022-09-25 22:06+0200\n"
+"Last-Translator: Temuri Doghonadze <temuri.doghonadze@gmail.com>\n"
+"Language-Team: Georgian <nothing>\n"
+"Language: ka\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 3.1.1\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "შეცდომა: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "გაფრთხილება: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "დეტალები: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "მინიშნება: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "ამ აგებაში %s-ით შეკუმშვის მხარდაჭრა არ არსებობს"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "შეკუმშვის პარამეტრების მაგიერ მოწოდებული სტრიქონი ცარიელია"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "შეკუმშვის უცნობი პარამეტრი: \"%s\""
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "შეკუმშვის პარამეტრ \"%s\"-ს მნიშვნელობა სჭირდება"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "შემუმშვის პარამეტრ \"%s\"-ის ნიშვნელობა მთელი რიცხვი უნდა იყოს"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "შეკუმშვის ალგორითმს \"%s\" შეკუმშვის დონე არ მიეთითება"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid ""
+"compression algorithm \"%s\" expects a compression level between %d and %d "
+"(default at %d)"
+msgstr ""
+"შეკუმშვის ალგორითმის \"%s\" შეკუმშვის დონე %d-სა და %d-ს შორის უნდა იყოს "
+"(ნაგულისხმები %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "შეკუმშვის ალგორითმს \"%s\" დამხმარე პროცესების რაოდენობა არ მიეთითება"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "არასაკმარისი მეხსიერება\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "ნულოვანი მაჩვენებლის დუბლირება შეუძლებელია (შიდა შეცდომა)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "ფაილი \"%s\" არ არსებობს: %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "საქაღალდის (%s) გახსნის შეცდომა: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "საქაღალდის (%s) წაკითხვის შეცდომა: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "ფაილის (%s) გახსნის შეცდომა: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "ფაილის (%s) fsync-ის შეცდომა: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2256 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "გადარქმევის შეცდომა %s - %s: %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "არასწორი მნიშვნელობა \"%s\" პარამეტრისთვის %s"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s არაა საზღვრებში %d-დან %d-მდე"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1636
+#, c-format
+msgid "out of memory"
+msgstr "არასაკმარისი მეხსიერება"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1433 pg_basebackup.c:1727
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "ფაილში (%s) ჩაწერის შეცდომა: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1497 pg_basebackup.c:1706
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "ფაილის (%s) შექმნის შეცდომა: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "ფაილის (%s) დახურვის შეცდომა: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "არქივის გაშლის მოულოდნელი მდგომარეობა"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:686 pg_basebackup.c:730
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "საქაღალდის (%s) შექმნის შეცდომა: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "საქაღალდეზე \"%s\" წვდომების დაყენების შეცდომა: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "%s-დან %s-მდე სიმბმულის შექმნა შეუძლებელია: %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "ფაილზე \"%s\" წვდომების დაყენების შეცდომა: %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "ვერ შექმნა შეკუმშული ფაილი \"%s\": %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "stdout-ის დუბლირების შეცდომა: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "გამოტანის ფაილის გახსნის შეცდომა: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "შეკუმშვის დონის დაყენების შეცდომა %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "ამ აგებაში gzip შეკუმშვის მხარდაჭერა არ არსებობს"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "შეკუმშული ფაილში (\"%s\") ჩაწერის შეცდომა: %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "შეკუმშული ფაილის (\"%s\") დახურვის შეცდომა: %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "შეკუმშვის ბიბლიოთეკის ინიციალიზაციის შეცდომა"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "მონაცემების გაშლის შეცდომა: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "უცნობი მდგომარეობა აღდგენის ინფორმაციის ჩასმისას"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "lz4 შეკუმშვის კონტექსტის შექმნის შეცდომა: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "ამ აგებაში lz4 შეკუმშვის მხარდაჭერა არ არსებობს"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "lz4 თავსართის ჩაწერის შეცდოა: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "მონაცემების შეკუმშვა შეუძლებელია: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "lz4 შეკუმშვის დასრულების შეცდომა: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "შეკუმშვის ბიბლიოთეკის ინიციალიზება ვერ მოხერხდა: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "tar ფაილის ბოლოსართი 2 ბლოკს სცდება"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "მოულოდნელი მდგომარეობა tar არქივის დამუშავებისას"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "tar-ის წევრს ცარიელი სახელი აქვს"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "COPY-ის ნაკადი ბოლო ფაილის დასრულებამდე დასრულდა"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "zstd შეკუმშვის კონტექსტის შექმნის შეცდომა"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "zstd შეკუმშვის დონის %d-ზე დაყენების შეცდომა: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "შეკუმშვის დამხმარე პროცესების რიცხვის %d-ზე დაყენების შეცდომა: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "ამ აგებაში zstd შეკუმშვის მხარდაჭერა არ არსებობს"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "zstd გაშლის კონტექსტის შექმნის შეცდომა"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "მონაცემების საქაღალდის წაშლა \"%s\""
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "მონაცემების საქაღალდის წაშლის შეცდომა"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "მონაცემების საქაღალდის შემცველობის წაშლა \"%s\""
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "მონაცემების საქაღალდის შემცველობის წაშლის შეცდომა"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "მიმდინარეობს WAL საქაღალდის წაშლა \"%s\""
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "შეცდომა WAL საქაღალდის წაშლისას"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "მიმდინარეობს WAL საქაღალდის (\"%s\") შემცველობის წაშლა"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "შეცდომა WAL საქაღალდის შემცველობის წაშლისას"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "მონაცემების საქაღალდე \"%s\" მომხმარებლის მოთხოვნისას არ წაიშლება"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "WAL საქაღალდე \"%s\" მომხმარებლის მოთხოვნისას არ წაიშლება"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "ცხრილების სივრცის საქაღალდეების ცვლილებების დაბრუნება შეუძლებელია"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "საქაღალდის სახელი ძალიან გრძელია"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "ცხრილების სივრცის მიბმაში ერთზე მეტი \"=\" ნიშანია"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "ცხრილების მიბმის არასწორი ფორმატი \"%s\", უნდა იყოს \"OLDDIR=NEWDIR\""
+
+#: pg_basebackup.c:351
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "ძველი საქაღალდის ბილიკი ცხრილის სივრცის მიბმაში აბსოლუტური არაა: %s"
+
+#: pg_basebackup.c:355
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "ახალი საქაღალდის ბილიკი ცხრილის სივრცის მიბმაში აბსოლუტური არაა: %s"
+
+#: pg_basebackup.c:377
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s გაშვებული PostgreSQL სერვერის მარქაფს იღებს.\n"
+"\n"
+
+#: pg_basebackup.c:379 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "გამოყენება:\n"
+
+#: pg_basebackup.c:380 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [პარამეტრი]...\n"
+
+#: pg_basebackup.c:381
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"პარამეტრები, რომლებიც აკონტროლებენ გამოტანას:\n"
+
+#: pg_basebackup.c:382
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=საქაღლდე იღებს ბაზის სარეზერვო ასლს საქაღალდეში\n"
+
+#: pg_basebackup.c:383
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr ""
+" -F, --format=p|t გამოტანის ფორმატი (plain (ნაგულისხმები), tar)\n"
+
+#: pg_basebackup.c:384
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=RATE მაქსიმალური სიჩქარე მონაცემთა საქაღალდის "
+"გადასაცემისას\n"
+" (kB/s-ში, ან გამოიყენეთ სუფიქსი \"k\" ან \"M\")\n"
+
+#: pg_basebackup.c:386
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" რეპლიკაციის კონფიგურაციის ჩაწერა \n"
+
+#: pg_basebackup.c:388
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=TARGET[:DETAIL]\n"
+" სამიზნის მარქაფი(თუ კლიენტისგან განსხვავებულია)\n"
+
+#: pg_basebackup.c:390
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" ცხრილების სივრცის OLDDIR -დან NEWDIR-ში გადატანა\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr ""
+" --waldir=WALDIR წინასწარ ჩაწერადი ჟურნალის (WAL) საქაღალდის "
+"მდებარეობა\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" საჭირო WAL ფაილების მითითებული მეთოდით ჩასმა\n"
+
+#: pg_basebackup.c:395
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip შექნილი tar ფაილის შეკუმშვა\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" შეკუმშვის ჩართვა სერვერზე ან კლიენტზე, "
+"მითითებისამებრ\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none შექმნილი tar არქივი არ შეიკუმშება\n"
+
+#: pg_basebackup.c:399
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"ზოგადი პარამეტრები:\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" სწრაფი ან გაფანტული საკონტროლო წერტილები\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot რეპლიკაციის სლოტის შექმნა\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL მარქაფის ჭდის შექმნა\n"
+
+#: pg_basebackup.c:404
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean შეცდომის შემთხვევაში არ გაასუფთავო\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid ""
+" -N, --no-sync do not wait for changes to be written safely to "
+"disk\n"
+msgstr ""
+" -N, --no-sync არ დაველოდო ცვლილებების დისკზე უსაფრთხოდ "
+"ჩაწერას\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress მიმდინარეობის ინფორმაციის ჩვენება\n"
+
+#: pg_basebackup.c:407 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=SLOTNAME გამოსაყენებელი სლოტი\n"
+
+#: pg_basebackup.c:408 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose დამატებითი ინფორმაციის გამოტანა\n"
+
+#: pg_basebackup.c:409 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version ვერსიის ინფორმაციის გამოტანა და გასვლა\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" მანიფესტების საკონტროლო ჯამის გამოსათვლელი "
+"ალფორითმი\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" მანიფესტში ყველა ფაილის სახელის თექვსმეტობითში "
+"კოდირება\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size მარქაფის ზომა სერვერის მხარეს არ გაიზომება\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest მარქაფის მანიფესტი არ შეიქმნება\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid ""
+" --no-slot prevent creation of temporary replication slot\n"
+msgstr ""
+" --no-slot რეპლიკაციის დროებითი სლოტის შექმნის თავიდან "
+"აცილება\n"
+
+#: pg_basebackup.c:417
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" საკონტროლო ჯამები არ შემოწმდება\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help ამ დახმარების ჩვენება და გასვლა\n"
+
+#: pg_basebackup.c:420 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"შეერთების პარამეტრები:\n"
+
+#: pg_basebackup.c:421 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONNSTR კავშირის სტრიქონი\n"
+
+#: pg_basebackup.c:422 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr ""
+" -h, --host=HOSTNAME მონაცემთა ბაზის სერვერის ჰოსტის ან სოკეტის "
+"საქაღალდე\n"
+
+#: pg_basebackup.c:423 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT მონაცემთა ბაზის სერვერის პორტი\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in "
+"seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVAL=INTERVAL\n"
+" სერვერზე გაგზავნილ სტატუსის პაკეტებს შორის "
+"დაყოვნება(წამებში)\n"
+
+#: pg_basebackup.c:426 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=მომხმარებელი ბაზის მომხმარებლის სახელი\n"
+
+#: pg_basebackup.c:427 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password არასოდეს მკითხო პაროლი\n"
+
+#: pg_basebackup.c:428 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid ""
+" -W, --password force password prompt (should happen "
+"automatically)\n"
+msgstr ""
+" -W, --password პაროლის ყოველთვის კითხვა (ავტომატურად უნდა "
+"ხდებოდეს)\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"შეცდომების შესახებ მიწერეთ: %s\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s-ის საწყისი გვერდია: <%s>\n"
+
+#: pg_basebackup.c:472
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "მზა ფაიფიდან წაკითხვის შეცდომა: %m"
+
+#: pg_basebackup.c:475 pg_basebackup.c:622 pg_basebackup.c:2170
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "წინასწარ-ჩაწერადი ჟურნალის მდებარეობის დამუშავების შეცდომა: %s"
+
+#: pg_basebackup.c:581 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "\"WAL\" ფაილების ჩაწერის დასრულების შეცდომა: %m"
+
+#: pg_basebackup.c:631
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "ფონური პროცესისთვის ფაიფის შექმნის შეცდომა: %m"
+
+#: pg_basebackup.c:664
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "შექმნილია რეპლიკაციის დროებითი სლოტი %s"
+
+#: pg_basebackup.c:667
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "შექმნილია რეპლიკაციის სლოტი %s"
+
+#: pg_basebackup.c:701
+#, c-format
+msgid "could not create background process: %m"
+msgstr "ფონური პროცესის შექმნის შეცდომა: %m"
+
+#: pg_basebackup.c:710
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "ფონური ნაკადის შექმნის შეცდომა: %m"
+
+#: pg_basebackup.c:749
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "საქაღალდე \"%s\" არსებობს, მაგრამ ცარიელი არაა"
+
+#: pg_basebackup.c:755
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "საქაღალდის (%s) წვდომის შეცდომა: %m"
+
+#: pg_basebackup.c:832
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s კბ (100%%), %d/%d ცხრილების სივრცე %*s"
+msgstr[1] "%*s/%s კბ (100%%), %d/%d ცხრილების სივრცე %*s"
+
+#: pg_basebackup.c:844
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s კბ (%d%%), %d/%d ცხრილების სივრცე (%s%-*.*s)"
+msgstr[1] "%*s/%s კბ (%d%%), %d/%d ცხრილების სივრცე (%s%-*.*s)"
+
+#: pg_basebackup.c:860
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s კბ (%d%%), %d/%d ცხრილების სივრცე"
+msgstr[1] "%*s/%s კბ (%d%%), %d/%d ცხრილების სივრცე"
+
+#: pg_basebackup.c:884
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "გადაცემის სიჩქარის არასწორი მნიშვნელობა: %s"
+
+#: pg_basebackup.c:886
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "გადაცემის არასწორი სიჩქარე \"%s\": %m"
+
+#: pg_basebackup.c:893
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "გადაცემის სიჩქარე ნულზე მეტი უნდა იყოს"
+
+#: pg_basebackup.c:923
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "--max-rate -ის არასწორი ერთეული: \"%s\""
+
+#: pg_basebackup.c:927
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "გადაცემის სიჩქარე მთელი რიცხვის დიაპაზონს აღემატება: %s"
+
+#: pg_basebackup.c:934
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "გადაცემის სიჩქარის მნიშვნელობა დიაპაზონს გარეთაა: %s"
+
+#: pg_basebackup.c:1030
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "\"COPY\"-ის მონაცემების ნაკადის მიღების შეცდომა: %s"
+
+#: pg_basebackup.c:1047 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "\"COPY\"-ის მონაცემების წაკითხვის შეცდომა: %s"
+
+#: pg_basebackup.c:1051
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "ფონური პროცესი მოულოდნელად დასრულდა"
+
+#: pg_basebackup.c:1122
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "შეკუმშულ tar ფაილში მანიფესტის შეჩურთვა შეუძლებელია"
+
+#: pg_basebackup.c:1123
+#, c-format
+msgid ""
+"Use client-side compression, send the output to a directory rather than "
+"standard output, or use %s."
+msgstr ""
+"გამოიყენეთ კლიენტის მხარეს შეკუმშვა და გააგზავნეთ გამონატანი საქაღალდეში "
+"stdout-ის მაგიერ, ან გამოიყენეთ %s."
+
+#: pg_basebackup.c:1139
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "არქივის დამუშავების შეცდომა: %s"
+
+#: pg_basebackup.c:1140
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "შესაძლებელია მხოლოდ tar არქივების დამუშავება."
+
+#: pg_basebackup.c:1142
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Plain-ის ფორმატი არქივის დასამუშავებლად pg_basebackup-ს მოითხოვს."
+
+#: pg_basebackup.c:1144
+#, c-format
+msgid ""
+"Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr ""
+"გამოსატან საქაღალდედ - -ის მითითება არქივის დასამუშავებლად pg_basebackup-ს "
+"მოითხოვს."
+
+#: pg_basebackup.c:1146
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "-R პარამეტრს არქივის დასამუშავებლად pg_basebackup-ს მოითხოვს."
+
+#: pg_basebackup.c:1357
+#, c-format
+msgid "archives must precede manifest"
+msgstr "არქივები წინ უნდა უსწრებდეს მანიფესტს"
+
+#: pg_basebackup.c:1372
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "არქივის არასწორი სახელი: \"%s\""
+
+#: pg_basebackup.c:1444
+#, c-format
+msgid "unexpected payload data"
+msgstr "მოულოდნელი შიგთავსი"
+
+#: pg_basebackup.c:1587
+#, c-format
+msgid "empty COPY message"
+msgstr "შეტყობინება COPY ცარიელია"
+
+#: pg_basebackup.c:1589
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "არასწორი COPY შეტყობინება ტიპით %d, სიგრძე %zu"
+
+#: pg_basebackup.c:1787
+#, c-format
+msgid "incompatible server version %s"
+msgstr "სერვერის შეუთავსებელი ვერსია %s"
+
+#: pg_basebackup.c:1803
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "ჟურნალის ნაკადის გასათიშად -X none ან -X fetch გამოიყენეთ."
+
+#: pg_basebackup.c:1871
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "სერვერის ამ ვერსიას მარქაფის სამიზნის მხარდაჭერა არ გააჩნია"
+
+#: pg_basebackup.c:1874
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr ""
+"აღდგენის კონფიგურაციის ჩაწერა მაშინ, როცა მარქაფის სამიზნე გამოიყენება, "
+"შეუძლებელია"
+
+#: pg_basebackup.c:1901
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "სერვერს თავის მხარეს შეკუმშვის მხარდაჭერა არ გააჩნია"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "ბაზის მარქაფის პროფესი დაიწყო. ველოდები საკონტროლო წერტილის დასასრულს"
+
+#: pg_basebackup.c:1915
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "საკონტროლო წერტილის მოლოდინი"
+
+#: pg_basebackup.c:1928 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "რეპლიკაციის ბრძანების (\"%s\") გაგზავნის შეცდომა: %s"
+
+#: pg_basebackup.c:1936
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "ბაზის მარქაფის ინიციალიზაციის შეცდომა: %s"
+
+#: pg_basebackup.c:1939
+#, c-format
+msgid ""
+"server returned unexpected response to BASE_BACKUP command; got %d rows and "
+"%d fields, expected %d rows and %d fields"
+msgstr ""
+"სერვერმა BASE_BACKUP ბრძანებაზე მოულოდნელი პასუხი დააბრუნა; მივიღე %d "
+"მწკრივი და %d ველი, მოველოდი %d მწკრივს და %d ველს"
+
+#: pg_basebackup.c:1945
+#, c-format
+msgid "checkpoint completed"
+msgstr "საკონტროლო წერტილი დასრულებულია"
+
+#: pg_basebackup.c:1960
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "წინასწარ-ჩაწერადი ჟურნალის საწყისი წერტილი: %s დროს ხაზზე %u"
+
+#: pg_basebackup.c:1968
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "მარქაფის თავსართის მიღების შეცდომა: %s"
+
+#: pg_basebackup.c:1971
+#, c-format
+msgid "no data returned from server"
+msgstr "სერვერიდან მონაცემები არ დაბრუნებულა"
+
+#: pg_basebackup.c:2006
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr ""
+"stdout-ში მხოლოდ ერთი ცხრილების სივრცის ჩაწერა შეუძლია. ბაზას კი %d აქვს"
+
+#: pg_basebackup.c:2019
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "ფონური WAL მიმღების გაშვება"
+
+#: pg_basebackup.c:2101
+#, c-format
+msgid "backup failed: %s"
+msgstr "მარქაფის შეცდომა: %s"
+
+#: pg_basebackup.c:2104
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "სერვერიდან წინასწარ-ჩაწერადი ჟურნალის ბოლო პოზიცია არ დაბრუნებულა"
+
+#: pg_basebackup.c:2107
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "წინასწარ-ჩაწერადი ჟურნალის ბოლო წერტილი: %s"
+
+#: pg_basebackup.c:2118
+#, c-format
+msgid "checksum error occurred"
+msgstr "საკონტროლო ჯამის შეცდომა"
+
+#: pg_basebackup.c:2123
+#, c-format
+msgid "final receive failed: %s"
+msgstr "მიღების დასრულების შეცდომა: %s"
+
+#: pg_basebackup.c:2147
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "ფონური პროცესის მიერ ნაკადის დასრულების მოლოდინი ..."
+
+#: pg_basebackup.c:2151
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "ფონური ფაიფისთვის ბრძანების გაგზავნის შეცდომა: %m"
+
+#: pg_basebackup.c:2156
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "შვულეულ პროცესს ვერ დაველოდები: %m"
+
+#: pg_basebackup.c:2158
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "%d შვილი მოკვდა, მოველოდი %d"
+
+#: pg_basebackup.c:2160 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2180
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "შვილეულ ნაკადს ვერ დაველოდები %m"
+
+#: pg_basebackup.c:2185
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "შვილეული ნაკადის გამოსვლის სტატუსის მიღების შეცდომა: %m"
+
+#: pg_basebackup.c:2188
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "შვილეული ნაკადის შეცდომა: %u"
+
+#: pg_basebackup.c:2217
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "მონაცემების სინქრონიზაცია დისკზე ..."
+
+#: pg_basebackup.c:2242
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "backup_manifest.tmp -ის სახელის გადარქმევა backup_manifest"
+
+#: pg_basebackup.c:2262
+#, c-format
+msgid "base backup completed"
+msgstr "ბაზის მარქაფი დასრულდა"
+
+#: pg_basebackup.c:2351
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "\"%s\"-ის არასწორი გამოტანის ფორმატი. უნდა იყოს: \"plain\" ან \"tar\""
+
+#: pg_basebackup.c:2395
+#, c-format
+msgid ""
+"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr ""
+"wal-method-ის არასწორი მნიშვნელობა: %s. უნდა იყოს \"fetch\", \"stream\" ან "
+"\"none\""
+
+#: pg_basebackup.c:2425
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr ""
+"საკონტროლო წერტილის არასწორი არგუმენტი %s: უნდა იყოს \"fast\" an \"spread\""
+
+#: pg_basebackup.c:2476 pg_basebackup.c:2488 pg_basebackup.c:2510
+#: pg_basebackup.c:2522 pg_basebackup.c:2528 pg_basebackup.c:2580
+#: pg_basebackup.c:2591 pg_basebackup.c:2601 pg_basebackup.c:2607
+#: pg_basebackup.c:2614 pg_basebackup.c:2626 pg_basebackup.c:2638
+#: pg_basebackup.c:2646 pg_basebackup.c:2659 pg_basebackup.c:2665
+#: pg_basebackup.c:2674 pg_basebackup.c:2686 pg_basebackup.c:2697
+#: pg_basebackup.c:2705 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "მეტი ინფორმაციისთვის სცადეთ '%s --help'."
+
+#: pg_basebackup.c:2486 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "მეტისმეტად ბევრი ბრძანების-სტრიქონის არგუმენტი (პირველია \"%s\")"
+
+#: pg_basebackup.c:2509
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "ერთდროულად შეუძლებელია ორივე, ფორმატის და მარქაფის სამიზნის მითითება"
+
+#: pg_basebackup.c:2521
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "გამოტანის საქაღალდის ან მარქაფის სამიზნის მითითება აუცილებელია"
+
+#: pg_basebackup.c:2527
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr ""
+"ორივე, გამოტანის საქაღალდის და მარქაფის სამიზნის მითითება ერთდროულად "
+"შეუძლებელია"
+
+#: pg_basebackup.c:2557 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "შეკუმშვის უცხო ალგორითმი: \"%s\""
+
+#: pg_basebackup.c:2563 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "შეკუმშვის არასწორი სპეციფიკაცია: %s"
+
+#: pg_basebackup.c:2579
+#, c-format
+msgid ""
+"client-side compression is not possible when a backup target is specified"
+msgstr ""
+"როცა მარქაფის სამიზნე მითითებულია, კლიენტის-მხრის შეკუმშვის მითითება "
+"შეუძლებელია"
+
+#: pg_basebackup.c:2590
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "შესაძლებელია მხოლოდ tar რეჟიმის მარქაფების შეკუმშვა"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "WAL-ის ნაკადი მაშინ, როცა მარქაფის სამიზნე მითითებულია, შეუძლებელია"
+
+#: pg_basebackup.c:2606
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr ""
+"წინასწარ-ჩაწერადი ჟურნალის ნაკადის tar-ის რეჟიმში stdout-ზე გამოტანა "
+"შეუძლებელია"
+
+#: pg_basebackup.c:2613
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr ""
+"რეპლიკაციის სლოტების გამოყენება მხოლოდ WAL ნაკადთან ერთადაა შესაძლებელი"
+
+#: pg_basebackup.c:2625
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot სლოტის სახელთან ერთად არ გამოიყენება"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2636 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s-სთვის საჭიროა სლოტის მითითება --slot პარამეტრის საშუალებით"
+
+#: pg_basebackup.c:2644 pg_basebackup.c:2684 pg_basebackup.c:2695
+#: pg_basebackup.c:2703
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "პარამეტრები %s და %s შეუთავსებელია"
+
+#: pg_basebackup.c:2658
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr ""
+"WAL საქაღალდის მდებარეობა მარქაფის სამიზნესთან ერთად მითითებული არ შეიძლება "
+"იყოს"
+
+#: pg_basebackup.c:2664
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr ""
+"WAL-ის საქაღალდის მდებარეობის მითითება მხოლოდ უბრალო რეჟიმშია შესაძლებელი"
+
+#: pg_basebackup.c:2673
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "WAL საქაღალდის მდებარეობა აბსოლუტური ბილიკი უნდა იყოს"
+
+#: pg_basebackup.c:2774
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "სიმბმულის შექმნის შეცდომა %s: %m"
+
+#: pg_basebackup.c:2776
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "სიმბმულები ამ პლატფორმაზე მხარდაჭერილი არაა"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s PostgreSQL-ის ნაკადური წინასწარ-ჩაწერადი ჟურნალს ახდენს.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"პარამეტრები:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid ""
+" -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr ""
+" -D, --directory=DIR წინასწარ-ჩაწერადი ჟურნალის ფაილების მითითებულ "
+"საქაღალდეში ჩაწერა\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN გამოსვლა მითითებული LSN-ის მიღების შემდეგ\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid ""
+" --if-not-exists do not error if slot already exists when creating a "
+"slot\n"
+msgstr ""
+" --if-not-exists სლოტის შექმნისას მისი არსებობის შემთხვევაში ფაქტი "
+"შეცდომად არ ჩაითვლება\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop შეერთების დაკარგვისას თავიდან არ ცდა\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid ""
+" --no-sync do not wait for changes to be written safely to "
+"disk\n"
+msgstr ""
+" --no-sync არ დაველოდო ცვლილებების დისკზე უსაფრთხოდ "
+"ჩაწერას\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server "
+"(default: %d)\n"
+msgstr ""
+" -s, --status-interval=SECS\n"
+" შუალედი სერვერზე სტატუსის პაკეტების გაგზავნებს "
+"შორის (ნაგულისხმები: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid ""
+" --synchronous flush write-ahead log immediately after writing\n"
+msgstr ""
+" --synchronous მისი ჩაწერის შემდეგ წინასწარ-ჩაწერადი ჟურნალის "
+"დაუყოვნებლივი გასუფთავება\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=მეთოდი[:წვრილმანი]\n"
+" შეკუმშვის მითითება\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"არასავალდებულო ქმედებები:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid ""
+" --create-slot create a new replication slot (for the slot's name "
+"see --slot)\n"
+msgstr ""
+" --create-slot ახალი რეპლიკაციის სლოტის შექმნა (სლოტის სახელისთვის "
+"იხილეთ --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid ""
+" --drop-slot drop the replication slot (for the slot's name see "
+"--slot)\n"
+msgstr ""
+" --drop-slot რეპლიკაციის სლოტის გადაგდება (რეპლიკაციის "
+"სახელისთვის იხილეთ --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "სეგმენტის დასრულების მისამართია %X/%X (დროის ხაზი %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "ჟურნალის ნაკადი შეჩერდა მისამართზე %X/%X (დროის ხაზი %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "გადავერთე %u-ე დროის ხაზზე მისამართით %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "მიღებულია შეწყვეტის სიგნალი. გამოსვლა"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "საქაღალდის %s-ზე დახურვის შეცდომა: %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "სეგმენტის ფაილის \"%s\" არასწორი ზომა %lld, გამოტოვება"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "შეკუმშული ფაილის (\"%s\") გახსნის შეცდომა: %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "შეკუმშული ფაილში (\"%s\") გადახვევის შეცდომა: %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "შეკუმშული ფაილის (\"%s\") წაკითხვის შეცდომა: %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "შეკუმშული ფაილის (\"%s\") წაკითხვის შეცდომა: წაკითხულია %d %zu-დან"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid ""
+"compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "შეკუმშული სეგმენტის ფაილის \"%s\" არასწორი გაშლილი ზომა %d, გამოტოვება"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "lz4 შეკუმშვის კონტექსტის შექმნის შეცდომა: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "ფაილის (%s) წაკითხვის შეცდომა: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "ფაილის (\"%s\") გაშლის შეცდომა: %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "lz4 შეკუმშვის კონტექსტის გასუფთავების შეცდომა: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid ""
+"compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr ""
+"შეკუმშული სეგმენტის ფაილის \"%s\" არასწორი გაშლილი ზომა %zu, გამოტოვება"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid ""
+"cannot check file \"%s\": compression with %s not supported by this build"
+msgstr ""
+"ფაილის (%s) შემოწმება შეუძლებელია: ამ აგებაში %s-ით შეკუმშვა მხარდაჭერილი "
+"არაა"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "ჟურნალის ნაკადი დაიწყო მისამართზე %X/%X (დროის ხაზი %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "ბოლო პოზიციის დამუშავების შეცდომა: %s"
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "--create-slot -ს და --drop-slot -ს ერთად ვერ გამოიყენებთ"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "--synchronous -ს --no-sync -თან ერთად ვერ გამოიყენებთ"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "სამიზნე საქაღალდე მითითებული არაა"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "%s-სთან დაკავშირების მხარდაჭერა ჯერ არ არსებობს"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid ""
+"replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "რეპლიკაციის შეერთება სლოტით \"%s\" მოულოდნელად ბაზაზეა დამოკიდებული"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "რეპლიკაციის სლოტის წაშლა: %s"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "რეპლიკაციის სლოტის შექმნა \"%s\""
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "გათიშულია"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "გათიშულია; თავიდან ცდამდე დაყოვნება %d წამია"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s PostgreSQL_ის ლოგიკური გაშიფვრის ნაკადებს აკონტროლებს.\n"
+"\n"
+" \n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"შესასრულებელი ქმედებები:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid ""
+" --start start streaming in a replication slot (for the "
+"slot's name see --slot)\n"
+msgstr ""
+" --start რეპლიკაციის სლოტში ნაკადის გაშვება (სლოტის "
+"სახელისთვის იხილეთ --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr ""
+" -f, --file=FILE ჟურნალის მითითებულ ფაილში მიღება. stdout-ისთვის -\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: "
+"%d)\n"
+msgstr ""
+" -F --fsync-interval=SECS\n"
+" შუალედი გამოსატანი ფაილის fsync-ებს შორის "
+"(ნაგულისხმები: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid ""
+" -I, --startpos=LSN where in an existing slot should the streaming "
+"start\n"
+msgstr " -I, --startpos=LSN ნაკადის დასაწყისი არსებული სლოტისთვის\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=სახელი[=მნიშვნელობა]\n"
+" გამოტანის დამატებისთვის მითითებული სახელის, "
+"არასავალდებულო მნიშვნელობით,\n"
+" გადაცემა\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr ""
+" -P, --plugin=PLUGIN გამოტანის მითითებული დამატების გამოყენება "
+"(ნაგულისხმები: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOTNAME ლოგიკური რეპლიკაციის სლოტის სახელი\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid ""
+" -t, --two-phase enable decoding of prepared transactions when "
+"creating a slot\n"
+msgstr ""
+" -t, --two-phase სლოტის შექმნისას მომზადებული ტრანზაქციების "
+"დეკოდერის ჩართვა\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=DBNAME მისაერთებელი ბაზის სახელი\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "ჩაწერის დადასტურება %X/%X-მდე, %X/%X-მდე მოცილება (სლოტი %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "უკუკავშირის პაკეტის გაგზავნის შეცდომა: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "ჟურნალის ნაკადის დაწყება მისამართზე %X/%X (სლოტი %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "ნაკადი ინიცირებულია"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "ჟურნალის ფაილის გახსნის შეცდომა \"%s\": %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "არასწორი სოკეტი: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s()-ის შეცდომა: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "\"WAL\" ნაკადიდან მონაცემების მიღების შეცდომა: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "ნაკადის თავსართი ძალიან პატარაა: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "ნაკადის უცნობი თავსართი: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "%d ბაიტის ჩაწერის შეცდომა ჟურნალის ფაილში \"%s\": %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "რეპლიკაციის ნაკადის მოულოდნელი დასასრული: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "საწყისი მდებარეობის დამუშავების შეცდომა: %s"
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "სლოტი მითითებული არაა"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "სამიზნე ფაილი მითითებული არაა"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "ბაზა მითითებული არაა"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "საჭიროა, სულ ცოტა, ერთი ქმედების მითითება"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "--create-slot -ს და ---start-ს -drop-slot -თან ერთად ვერ გამოიყენებთ"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr ""
+"--create-slot -ს და --drop-slot-ს --startpos -თან ერთად ვერ გამოიყენებთ"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos -ის მითითება მხოლოდ --start -თან ერთად შეიძლება"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase -ის მითითება მხოლოდ --create-slot -თან ერთად შეიძლება"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "ბაზაზე-დამოკიდებული რეპლიკაციის შეერთების დამყარების შეცდომა"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "ბოლო მდებარეობა %X/%X keepalive-ის მიერ მიღწეული"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "ბოლო მდებარეობა %X/%X WAL ჩანაწერის მიერ მიღწეულია მისამართზე %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "არქივის სტატუსის ფაილის \"%s\" შექმნის შეცდომა: %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "არქივის სტატუსის ფაილის \"%s\" დახურვის შეცდომა: %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "წინასწარ-ჩაწერადი ჟურნალის ფაილის \"%s\" ზომის მიღების შეცდომა: %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "წინასწარ-ჩაწერადი ჟურნალის არსებული ფაილის \"%s\" გახსნის შეცდომა: %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr ""
+"წინასწარ-ჩაწერადი ჟურნალის არსებული ფაილის \"%s\" fsync()-ის შეცდომა: %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] ""
+"წინასწარ-ჩაწერადი ჟურნალის ფაილს \"%s\" აქვს %zd ბაიტი. უნდა იყოს 0 ან %d"
+msgstr[1] ""
+"წინასწარ-ჩაწერადი ჟურნალის ფაილს \"%s\" აქვს %zd ბაიტი. უნდა იყოს 0 ან %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "წინასწარ-ჩაწერადი ჟურნალის არსებული ფაილის \"%s\" გახსნის შეცდომა: %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "ფაილში %s გადახვევის მდებარეობის დადგენა შეუძლებელია: %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "\"%s\"-ის სახელი არ შეიცვლება. სეგმენტი დაუსრულებელია"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "ფაილის (\"%s\") დახურვის შეცდომა: %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr ""
+"სერვერის პასუხში მოულოდნელი ისტორიის ფაილის სახელია, დროის ხაზისთვის %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "დროის ხაზის ისტორიის ფაილის (%s) შექმნის შეცდომა: %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "დროის ხაზის ისტორიის ფაილის (%s) ჩაწერის შეცდომა: %s"
+
+#: receivelog.c:400
+#, c-format
+msgid ""
+"incompatible server version %s; client does not support streaming from "
+"server versions older than %s"
+msgstr ""
+"სერვერის შეუთავსებელი ვერსია %s: კლიენტს ნაკადის მხარდაჭერა სერვერებიდან, "
+"რომლის ვერსიაც დაბალია %s-ზე, არ გააჩნია"
+
+#: receivelog.c:409
+#, c-format
+msgid ""
+"incompatible server version %s; client does not support streaming from "
+"server versions newer than %s"
+msgstr ""
+"სერვერის შეუთავსებელი ვერსია %s: კლიენტს ნაკადის მხარდაჭერა სერვერებიდან, "
+"რომლის ვერსიაც მაღალია %s-ზე, არ გააჩნია"
+
+#: receivelog.c:514
+#, c-format
+msgid ""
+"system identifier does not match between base backup and streaming connection"
+msgstr ""
+"სისტემის იდენტიფიკატორი ბაზს მარქაფსა და ნაკადურ შეერთებას შორის არ ემთხვევა"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "დაწყების დროის ხაზი %u სერვერზე არ არსებობს"
+
+#: receivelog.c:561
+#, c-format
+msgid ""
+"unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"მოულოდნელი პასუხი TIMELINE_HISTORY ბრძანებაზე: მივიღე %d მწკრივი და %d ველი, "
+"ველოდებოდი %d მწკრივს და %d ველს"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr ""
+"სერვერის პასუხში მოულოდნელი შემდეგი დროის ხაზია (%u), დროის ხაზის შემდეგ: %u"
+
+#: receivelog.c:638
+#, c-format
+msgid ""
+"server stopped streaming timeline %u at %X/%X, but reported next timeline %u "
+"to begin at %X/%X"
+msgstr ""
+"სერვერმა შეწყვიტა დროის ხაზის %u ნაკადი მისამართზე %X/%X, მაგრამ მოიწერა, "
+"რომ შემდეგი დროის ხაზი %u მისამართზე %X/%X იწყება"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "რეპლიკაციის ნაკადი გაჩერების წერტილამდე შეწყდა"
+
+#: receivelog.c:724
+#, c-format
+msgid ""
+"unexpected result set after end-of-timeline: got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"მოულოდნელი შედეგების ნაკრები დროის-ხაზის-დამთავრების შემდეგ: მივიღე %d "
+"მწკრივი და %d ველი. მოველოდი %d მწკრივს და %d ველს"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "შემდეგი დროის ხაზის დაწყების წერტილის (%s) დამუშავების შეცდომა"
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "ფაილის (\"%s\") fsync-ის შეცდომა: %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr ""
+"მიღებულია წინასწარ-ჩაწერადი ჟურნალის ჩანაწერი წანაცვლებისთვის %u მაშინ, როცა "
+"ფაილები ღია არაა"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "მიღებული WAL მონაცემის წანაცვლება %08x, მოველოდი %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "%d ბაიტის WAL ფაილში (\"%s\") ჩაწერის შეცდომა: %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "copy-end პაკეტის გაგზავნის შეცდომა: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "პაროლი: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "სერვერთან მიერთების პრობლემა"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "search_path-ის გასუფთავების პრობლემა: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "სერვერის პარამეტრის \"integer_datetimes\" დადგენა შეუძლებელია"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "აგებისას მითითებული ალამი integer_datetimes სერვერისას არ ემთხვვევა"
+
+#: streamutil.c:299
+#, c-format
+msgid ""
+"could not fetch WAL segment size: got %d rows and %d fields, expected %d "
+"rows and %d or more fields"
+msgstr ""
+"შეცდომა WAL-ის სეგმენტის ზომის მიღებისას: მივიღე %d მწკრივი და %d ველი. "
+"მოველოდი %d მწკრივს და %d ან მეტ ველს"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "WAL სეგმენტის ზომის დამუშავების შეცდომა"
+
+#: streamutil.c:327
+#, c-format
+msgid ""
+"WAL segment size must be a power of two between 1 MB and 1 GB, but the "
+"remote server reported a value of %d byte"
+msgid_plural ""
+"WAL segment size must be a power of two between 1 MB and 1 GB, but the "
+"remote server reported a value of %d bytes"
+msgstr[0] ""
+"WAL-ის სეგმენტის ზომა ორის ხარისხი უნდა იყოს 1 მბ-სა და 1გბ-ს შორის, მაგრამ "
+"დაშორებულმა სერვერმა %d ბაიტიანი მნიშვნელობა დააბრუნა"
+msgstr[1] ""
+"WAL-ის სეგმენტის ზომა ორის ხარისხი უნდა იყოს 1 მბ-სა და 1გბ-ს შორის, მაგრამ "
+"დაშორებულმა სერვერმა %d ბაიტიანი მნიშვნელობა დააბრუნა"
+
+#: streamutil.c:372
+#, c-format
+msgid ""
+"could not fetch group access flag: got %d rows and %d fields, expected %d "
+"rows and %d or more fields"
+msgstr ""
+"ჯგუფის წვდომის ალმის გამოთხოვის შეცდომა: მივიღე %d მწკრივი და %d ველი. "
+"მოველოდი %d მწკრივს და %d ან მეტ ველს"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "ჯგუფის წვდომის ალმის დამუშავების შეცდომა: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid ""
+"could not identify system: got %d rows and %d fields, expected %d rows and "
+"%d or more fields"
+msgstr ""
+"სისტემის ამოცნობის შეცდომა: მივიღე %d მწკრივი და %d ველი. მოველოდი %d "
+"მწკრივს და %d ან მეტ ველს"
+
+#: streamutil.c:513
+#, c-format
+msgid ""
+"could not read replication slot \"%s\": got %d rows and %d fields, expected "
+"%d rows and %d fields"
+msgstr ""
+"რეპლიკაციის სლოტის (\"%s\") წაკითხვის შეცდომა: მივიღე %d მწკრივი და %d ველი. "
+"მოველოდი %d მწკრივს და %d ველს"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "რეპლიკაციის სლოტი \"%s\"არ არსებობს"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "მოველოდი ფიზიკური რეპლიკაციის სლოტს. მივიღე: %s"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr ""
+"restart_lsn \"%s\"-ის დამუშავების შეცდომა რეპლიკაციის სლოტისთვის \"%s\""
+
+#: streamutil.c:667
+#, c-format
+msgid ""
+"could not create replication slot \"%s\": got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"რეპლიკაციის სლოტის (\"%s\") შექმნის შეცდომა: მივიღე %d მწკრივი და %d ველი. "
+"მოველოდი %d მწკრივს და %d ველს"
+
+#: streamutil.c:711
+#, c-format
+msgid ""
+"could not drop replication slot \"%s\": got %d rows and %d fields, expected "
+"%d rows and %d fields"
+msgstr ""
+"რეპლიკაციის სლოტის (\"%s\") გადაგდების შეცდომა: მივიღე %d მწკრივი და %d "
+"ველი. მოველოდი %d მწკრივს და %d ველს"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "მონაცემების შეკუმშვის შეცდომა"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "შეკუმშვის ნაკადის თავიდან დაწყების შეცდომა"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "განხორციელების შეცდომა: tar ფაილებს ერთზე მეტი ღია ფაილი ვერ ექნებათ"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "tar-ის თავსართის შექმნის შეცდომა"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "შეკუმშვის პარამეტრების შეცვლა შეუძლებელა"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "წაშლა შეკუმშვით მხარდაუჭერელია"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "შეკუმშვის ნაკადის დახურვის შეცდომა"
+
+#, c-format
+#~ msgid "unknown compression option \"%s\""
+#~ msgstr "შეკუმშვის უცნობი პარამეტრი: \"%s\""
+
+#, c-format
+#~ msgid "log streamer with pid %d exiting"
+#~ msgstr "ჟურნალის ნაკადის პროცესი pid-ით %d ასრულებს მუშაობას"
+
+#, c-format
+#~ msgid "could not check file \"%s\""
+#~ msgstr "ფაილის შემოწმება შეუძლებელია: %s"
+
+#, c-format
+#~ msgid "This build does not support compression with %s."
+#~ msgstr "ამ აგებაში %s-ით შეკუმშვის მხარდაჭრა არ არსებობს."
+
+#, c-format
+#~ msgid "no value specified for --compress, switching to default"
+#~ msgstr ""
+#~ "--compress -ის მნიშვნელობა მითითებული არაა. გამოიყენება ნაგულისხმები"
+
+#, c-format
+#~ msgid "could not find replication slot \"%s\""
+#~ msgstr "რეპლიკაციის სლოტი არ არსებობს: %s"
diff --git a/src/bin/pg_basebackup/po/ko.po b/src/bin/pg_basebackup/po/ko.po
new file mode 100644
index 0000000..3c12349
--- /dev/null
+++ b/src/bin/pg_basebackup/po/ko.po
@@ -0,0 +1,1917 @@
+# LANGUAGE message translation file for pg_basebackup
+# Copyright (C) 2015 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Ioseph Kim <ioseph@uri.sarang.net>, 2015
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL) 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2023-04-12 00:47+0000\n"
+"PO-Revision-Date: 2023-04-06 17:17+0900\n"
+"Last-Translator: Ioseph Kim <ioseph@uri.sarang.net>\n"
+"Language-Team: Korean <kr@postgresql.org>\n"
+"Language: ko\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "오류: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "경고: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "상세정보: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "힌트: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "이 버전은 %s 압축 기능을 포함 하지 않고 빌드 되었습니다."
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "압축 옵션을 지정하는 자리에 빈 문자열이 있습니다."
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "인식할 수 없는 압축 옵션: \"%s\""
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "\"%s\" 압축 옵션에는 그 지정값이 필요합니다."
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "\"%s\" 압축 옵션 값은 정수여야 합니다."
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "\"%s\" 압축 알고리즘은 압축 수준을 지정할 수 없습니다."
+
+#: ../../common/compression.c:342
+#, c-format
+msgid ""
+"compression algorithm \"%s\" expects a compression level between %d and %d "
+"(default at %d)"
+msgstr ""
+"\"%s\" 압축 알고리즘은 압축 수준값으로 %d에서 %d까지만 허용함 (기본값 %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "\"%s\" 압축 알고리즘은 병렬 작업 수를 지정할 수 없습니다."
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "메모리 부족\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "null 포인터를 복제할 수 없음(내부 오류)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "\"%s\" 파일의 상태값을 알 수 없음: %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "\"%s\" 디렉터리 열 수 없음: %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "\"%s\" 디렉터리를 읽을 수 없음: %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "\"%s\" 파일을 열 수 없음: %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "\"%s\" 파일 fsync 실패: %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2266 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "\"%s\" 파일을 \"%s\" 파일로 이름을 바꿀 수 없음: %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "\"%s\" 값은 \"%s\" 옵션값으로 유효하지 않음"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s 값은 %d부터 %d까지 지정할 수 있습니다."
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1646
+#, c-format
+msgid "out of memory"
+msgstr "메모리 부족"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1443 pg_basebackup.c:1737
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "\"%s\" 파일 쓰기 실패: %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1507 pg_basebackup.c:1716
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "\"%s\" 파일을 만들 수 없음: %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "\"%s\" 파일을 닫을 수 없음: %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "아카이브 추출 중 예상치 못한 상태값 발견"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:696 pg_basebackup.c:740
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "\"%s\" 디렉터리를 만들 수 없음: %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "\"%s\" 디렉터리 액세스 권한을 지정할 수 없음: %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "\"%s\" 파일을 \"%s\" 심볼릭 링크로 만들 수 없음: %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "파일 \"%s\" 의 접근권한을 지정할 수 없음: %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "\"%s\" 압축 파일 만들기 실패: %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "stdout을 중복할 수 없음: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "출력파일을 열 수 없음: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "잘못된 압축 수위 %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "이 버전은 gzip 압축 기능을 포함 하지 않고 빌드 되었습니다."
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "\"%s\" 압축 파일 쓰기 실패: %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "\"%s\" 압축 파일 닫기 실패: %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "압축 라이브러리를 초기화할 수 없음"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "압축 풀기 실패: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "복원 관련 설정을 추가 하는 도중 예상치 못한 상태 발견"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "lz4 압축 컨텍스트 정보를 생성할 수 없습니다: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "이 버전은 lz4 압축 기능을 포함 하지 않고 빌드 되었습니다."
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "lz4 헤더를 쓸 수 없음: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "자료를 압축할 수 없음: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "lz4 압축을 끝낼 수 없음: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "압축 라이브러리를 초기화 할 수 없음: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "tar 파일 끝부분에서 2 블록이 초과됨"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "tar 아카이브 분석 중 예상치 못한 상태 발견"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "tar 맴버에 이름이 없음"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "마지막 파일을 끝내기 전에 COPY 스트림이 끝났음"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "zstd 압축 컨텍스트를 만들 수 없음"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "zstd 압축 수준을 %d 값으로 지정할 수 없음: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "압축용 병렬 작업자 수를 %d 값으로 지정할 수 없음: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "이 버전은 zstd 압축 기능을 포함 하지 않고 빌드 되었습니다."
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "zstd 압축 컨텍스트를 만들 수 없음"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "\"%s\" 디렉터리를 지우는 중"
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "데이터 디렉터리 삭제 실패"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "\"%s\" 데이터 디렉터리의 내용을 지우는 중"
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "데이터 디렉터리의 내용을 지울 수 없음"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "\"%s\" WAL 디렉터리를 지우는 중"
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "WAL 디렉터리 삭제 실패"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "\"%s\" WAL 디렉터리 내용을 지우는 중"
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "WAL 디렉터리의 내용을 지울 수 없음"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "사용자 요청으로 \"%s\" 데이터 디렉터리를 지우지 않았음"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "사용자 요청으로 \"%s\" WAL 디렉터리를 지우지 않았음"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "아직 마무리 되지 않은 테이블스페이스 디렉터리 변경함"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "디렉터리 이름이 너무 김"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "테이블스페이스 맵핑 하는 곳에서 \"=\" 문자가 중복 되어 있음"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr ""
+"\"%s\" 형식의 테이블스페이스 맵핑이 잘못 되었음, \"OLDDIR=NEWDIR\" 형식이어"
+"야 함"
+
+#: pg_basebackup.c:361
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "테이블스페이스 맵핑용 옛 디렉터리가 절대 경로가 아님: %s"
+
+#: pg_basebackup.c:365
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "테이블스페이스 맵핑용 새 디렉터리가 절대 경로가 아님: %s"
+
+#: pg_basebackup.c:387
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s 프로그램은 운영 중인 PostgreSQL 서버에 대해서 베이스 백업을 하는 도구입니"
+"다.\n"
+"\n"
+
+#: pg_basebackup.c:389 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "사용법:\n"
+
+#: pg_basebackup.c:390 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [옵션]...\n"
+
+#: pg_basebackup.c:391
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"출력물을 제어야하는 옵션들:\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=디렉터리 베이스 백업 결과물이 저장될 디렉터리\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t 출력 형식 (plain (초기값), tar)\n"
+
+#: pg_basebackup.c:394
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=속도 최대 전송 속도\n"
+" (단위는 kB/s, 또는 숫자 뒤에 \"k\" 또는 \"M\" 단위 "
+"문자 지정 가능)\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" 복제를 위한 환경 설정 함\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=TARGET[:DETAIL]\n"
+" 백업 타겟 지정 (이곳 또는 다른 곳)\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=옛DIR=새DIR\n"
+" 테이블스페이스 디렉터리 새 맵핑\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=WALDIR 트랜잭션 로그 디렉터리 지정\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" 필요한 WAL 파일을 백업하는 방법\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip tar 출력물을 압축\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" 압축 관련 설정\n"
+
+#: pg_basebackup.c:408
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none tar 출력에서 압축 안함\n"
+
+#: pg_basebackup.c:409
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"일반 옵션들:\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" 체크포인트 방법\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot 새 복제 슬롯을 만듬\n"
+
+#: pg_basebackup.c:413
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=라벨 백업 라벨 지정\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean 오류 발생 시 정리하지 않음\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid ""
+" -N, --no-sync do not wait for changes to be written safely to "
+"disk\n"
+msgstr " -N, --no-sync 디스크 쓰기 뒤 sync 작업 생략\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress 진행 과정 보여줌\n"
+
+#: pg_basebackup.c:417 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=슬롯이름 지정한 복제 슬롯을 사용함\n"
+
+#: pg_basebackup.c:418 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose 자세한 작업 메시지 보여줌\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version 버전 정보 보여주고 마침\n"
+
+#: pg_basebackup.c:420
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" 사용할 manifest 체크섬 알고리즘\n"
+
+#: pg_basebackup.c:422
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" manifest 내 모든 파일 이름을 16진수 인코딩함\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size 서버측 백업 크기를 예상하지 않음\n"
+
+#: pg_basebackup.c:425
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest 백업 매니페스트 만들지 않음\n"
+
+#: pg_basebackup.c:426
+#, c-format
+msgid ""
+" --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot 임시 복제 슬롯 만들지 않음\n"
+
+#: pg_basebackup.c:427
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" 체크섬 검사 안함\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help 이 도움말을 보여주고 마침\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"연결 옵션들:\n"
+
+#: pg_basebackup.c:431 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=접속문자열 서버 접속 문자열\n"
+
+#: pg_basebackup.c:432 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=호스트이름 접속할 데이터베이스 서버나 소켓 디렉터리\n"
+
+#: pg_basebackup.c:433 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=포트 데이터베이스 서버 포트 번호\n"
+
+#: pg_basebackup.c:434
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in "
+"seconds)\n"
+msgstr ""
+" -s, --status-interval=초\n"
+" 초 단위 매번 서버로 상태 패킷을 보냄\n"
+
+#: pg_basebackup.c:436 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=사용자 접속할 특정 데이터베이스 사용자\n"
+
+#: pg_basebackup.c:437 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password 비밀번호 물어 보지 않음\n"
+
+#: pg_basebackup.c:438 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid ""
+" -W, --password force password prompt (should happen "
+"automatically)\n"
+msgstr ""
+" -W, --password 항상 비밀번호 프롬프트 보임 (자동으로 판단 함)\n"
+
+#: pg_basebackup.c:439 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"문제점 보고 주소: <%s>\n"
+
+#: pg_basebackup.c:440 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s 홈페이지: <%s>\n"
+
+#: pg_basebackup.c:482
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "준비된 파이프로부터 읽기 실패: %m"
+
+#: pg_basebackup.c:485 pg_basebackup.c:632 pg_basebackup.c:2180
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "트랜잭션 로그 위치 \"%s\" 분석 실패"
+
+#: pg_basebackup.c:591 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "WAL 파일 쓰기 마무리 실패: %m"
+
+#: pg_basebackup.c:641
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "백그라운드 프로세스를 위한 파이프 만들기 실패: %m"
+
+#: pg_basebackup.c:674
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "\"%s\" 임시 복제 슬롯을 만듦"
+
+#: pg_basebackup.c:677
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "\"%s\" 이름의 복제 슬롯을 만듦"
+
+#: pg_basebackup.c:711
+#, c-format
+msgid "could not create background process: %m"
+msgstr "백그라운드 프로세스 만들기 실패: %m"
+
+#: pg_basebackup.c:720
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "백그라운드 스래드 만들기 실패: %m"
+
+#: pg_basebackup.c:759
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "\"%s\" 디렉터리가 있지만 비어 있지 않음"
+
+#: pg_basebackup.c:765
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "\"%s\" 디렉터리를 액세스할 수 없습니다: %m"
+
+#: pg_basebackup.c:842
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d 테이블스페이스 %*s"
+
+#: pg_basebackup.c:854
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d 테이블스페이스 (%s%-*.*s)"
+
+#: pg_basebackup.c:870
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d 테이블스페이스"
+
+#: pg_basebackup.c:894
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "\"%s\" 전송 속도는 잘못된 값임"
+
+#: pg_basebackup.c:896
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "잘못된 전송 속도 \"%s\": %m"
+
+#: pg_basebackup.c:903
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "전송 속도는 0보다 커야 함"
+
+#: pg_basebackup.c:933
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "잘못된 --max-rate 단위: \"%s\""
+
+#: pg_basebackup.c:937
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "\"%s\" 전송 속도는 정수형 범위가 아님"
+
+#: pg_basebackup.c:944
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "\"%s\" 전송 속도는 범위 초과"
+
+#: pg_basebackup.c:1040
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "COPY 데이터 스트림을 사용할 수 없음: %s"
+
+#: pg_basebackup.c:1057 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "COPY 자료를 읽을 수 없음: %s"
+
+#: pg_basebackup.c:1061
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "백그라운드 프로세스가 예상치 않게 종료됨"
+
+#: pg_basebackup.c:1132
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "압축된 tar 파일에는 manifest를 넣을 수 없습니다."
+
+#: pg_basebackup.c:1133
+#, c-format
+msgid ""
+"Use client-side compression, send the output to a directory rather than "
+"standard output, or use %s."
+msgstr ""
+"결과물을 표준 출력으로 보내지 말고, 디렉터리로 보낸 뒤 클라이언트 측에서 압"
+"축 하거나, %s 옵션을 사용하세요."
+
+#: pg_basebackup.c:1149
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "\"%s\" 아카이브를 구문분석할 수 없음"
+
+#: pg_basebackup.c:1150
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "tar 형식만 구문분석할 수 있음"
+
+#: pg_basebackup.c:1152
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "아카이브를 분석하기 위해서는 일반 양식이어야 합니다."
+
+#: pg_basebackup.c:1154
+#, c-format
+msgid ""
+"Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "아카이브를 분석하기 위해 출력 디렉터리 이름으로 - 문자를 사용하세요."
+
+#: pg_basebackup.c:1156
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "아카이브를 분석하기 위해 -R 옵션을 사용하세요."
+
+#: pg_basebackup.c:1367
+#, c-format
+msgid "archives must precede manifest"
+msgstr "아카이브 작업은 매니페스트보다 앞서야합니다"
+
+#: pg_basebackup.c:1382
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "잘못된 아카이브 이름: \"%s\""
+
+#: pg_basebackup.c:1454
+#, c-format
+msgid "unexpected payload data"
+msgstr "비정상 payload 자료"
+
+#: pg_basebackup.c:1597
+#, c-format
+msgid "empty COPY message"
+msgstr "빈 COPY 메시지"
+
+#: pg_basebackup.c:1599
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "타입 %d의 잘못된 COPY 메시지, 길이: %zu"
+
+#: pg_basebackup.c:1797
+#, c-format
+msgid "incompatible server version %s"
+msgstr "호환하지 않는 서버 버전 %s"
+
+#: pg_basebackup.c:1813
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr ""
+"트랜잭션 로그 스트리밍을 사용하지 않으려면 -X none 또는 -X fetch 옵션을 사용"
+"하세요."
+
+#: pg_basebackup.c:1881
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "이 서버는 백업 타켓을 지원하지 않음."
+
+#: pg_basebackup.c:1884
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "백업 타겟을 사용할 때는 원 환경 설정을 기록할 수 없습니다."
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "이 서버는 서버 측 압축을 지원하지 않습니다"
+
+#: pg_basebackup.c:1921
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "베이스 백업을 초기화 중, 체크포인트 완료를 기다리는 중"
+
+#: pg_basebackup.c:1925
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "체크포인트가 끝나길 기다리는 중"
+
+#: pg_basebackup.c:1938 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "\"%s\" 복제 명령을 보낼 수 없음: %s"
+
+#: pg_basebackup.c:1946
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "베이스 백업을 초기화 할 수 없음: %s"
+
+#: pg_basebackup.c:1949
+#, c-format
+msgid ""
+"server returned unexpected response to BASE_BACKUP command; got %d rows and "
+"%d fields, expected %d rows and %d fields"
+msgstr ""
+"서버가 BASE_BACKUP 명령에 대해서 잘못된 응답을 했습니다; 응답값: %d 로우, %d "
+"필드, (기대값: %d 로우, %d 필드)"
+
+#: pg_basebackup.c:1955
+#, c-format
+msgid "checkpoint completed"
+msgstr "체크포인트 완료"
+
+#: pg_basebackup.c:1970
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "트랙잭션 로그 시작 위치: %s, 타임라인: %u"
+
+#: pg_basebackup.c:1978
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "백업 헤더를 구할 수 없음: %s"
+
+#: pg_basebackup.c:1981
+#, c-format
+msgid "no data returned from server"
+msgstr "서버가 아무런 자료도 주지 않았음"
+
+#: pg_basebackup.c:2016
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr ""
+"표준 출력으로는 하나의 테이블스페이스만 쓸 수 있음, 데이터베이스는 %d 개의 테"
+"이블 스페이스가 있음"
+
+#: pg_basebackup.c:2029
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "백그라운드 WAL 수신자 시작 중"
+
+#: pg_basebackup.c:2111
+#, c-format
+msgid "backup failed: %s"
+msgstr "백업 실패: %s"
+
+#: pg_basebackup.c:2114
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "서버에서 트랜잭션 로그 마지막 위치가 수신 되지 않았음"
+
+#: pg_basebackup.c:2117
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "트랜잭션 로그 마지막 위치: %s"
+
+#: pg_basebackup.c:2128
+#, c-format
+msgid "checksum error occurred"
+msgstr "체크섬 오류 발생"
+
+#: pg_basebackup.c:2133
+#, c-format
+msgid "final receive failed: %s"
+msgstr "수신 작업 마무리 실패: %s"
+
+#: pg_basebackup.c:2157
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "스트리밍을 끝내기 위해서 백그라운드 프로세스를 기다리는 중 ..."
+
+#: pg_basebackup.c:2161
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "백그라운드 파이프로 명령을 보낼 수 없음: %m"
+
+#: pg_basebackup.c:2166
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "하위 프로세스를 기다릴 수 없음: %m"
+
+#: pg_basebackup.c:2168
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "%d 개의 하위 프로세스가 종료됨, 기대값 %d"
+
+#: pg_basebackup.c:2170 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2190
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "하위 스레드를 기다릴 수 없음: %m"
+
+#: pg_basebackup.c:2195
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "하위 스레드 종료 상태가 정상적이지 않음: %m"
+
+#: pg_basebackup.c:2198
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "하위 스레드가 비정상 종료됨: 오류 코드 %u"
+
+#: pg_basebackup.c:2227
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "자료를 디스크에 동기화 하는 중 ... "
+
+#: pg_basebackup.c:2252
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "backup_manifest.tmp 파일을 backup_manifest로 바꾸는 중"
+
+#: pg_basebackup.c:2272
+#, c-format
+msgid "base backup completed"
+msgstr "베이스 백업 완료"
+
+#: pg_basebackup.c:2361
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "\"%s\" 값은 잘못된 출력 형식, \"plain\" 또는 \"tar\" 만 사용 가능"
+
+#: pg_basebackup.c:2405
+#, c-format
+msgid ""
+"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr ""
+"\"%s\" 값은 잘못된 wal-method 옵션값, \"fetch\", \"stream\" 또는 \"none\"만 "
+"사용 가능"
+
+#: pg_basebackup.c:2435
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "잘못된 체크포인트 옵션값 \"%s\", \"fast\" 또는 \"spread\"만 사용 가능"
+
+#: pg_basebackup.c:2486 pg_basebackup.c:2498 pg_basebackup.c:2520
+#: pg_basebackup.c:2532 pg_basebackup.c:2538 pg_basebackup.c:2590
+#: pg_basebackup.c:2601 pg_basebackup.c:2611 pg_basebackup.c:2617
+#: pg_basebackup.c:2624 pg_basebackup.c:2636 pg_basebackup.c:2648
+#: pg_basebackup.c:2656 pg_basebackup.c:2669 pg_basebackup.c:2675
+#: pg_basebackup.c:2684 pg_basebackup.c:2696 pg_basebackup.c:2707
+#: pg_basebackup.c:2715 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "자세한 사항은 \"%s --help\" 명령으로 살펴보세요."
+
+#: pg_basebackup.c:2496 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "너무 많은 명령행 인자를 지정했습니다. (처음 \"%s\")"
+
+#: pg_basebackup.c:2519
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "백업 양식과 백업 타겟을 함께 사용할 수 없음"
+
+#: pg_basebackup.c:2531
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "출력 디렉터리를 지정하거나, 백업 타겟을 지정하세요."
+
+#: pg_basebackup.c:2537
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "출력 디렉터리와 백업 타겟은 함께 지정할 수 없음"
+
+#: pg_basebackup.c:2567 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "알 수 없는 압축 알고리즘: \"%s\""
+
+#: pg_basebackup.c:2573 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "잘못된 압축 정보: %s"
+
+#: pg_basebackup.c:2589
+#, c-format
+msgid ""
+"client-side compression is not possible when a backup target is specified"
+msgstr "백업 타켓을 사용할 때는 클라이언트 측 압축을 사용할 수 없습니다."
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "tar 형식만 압축을 사용할 수 있음"
+
+#: pg_basebackup.c:2610
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "백업 타겟을 지정할 때는 WAL 스트리밍을 사용할 수 없습니다."
+
+#: pg_basebackup.c:2616
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "tar 방식에서 stdout으로 트랜잭션 로그 스트리밍 불가"
+
+#: pg_basebackup.c:2623
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "복제 슬롯은 WAL 스트리밍 방식에서만 사용할 수 있음"
+
+#: pg_basebackup.c:2635
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "슬롯 이름을 지정한 경우 --no-slot 옵션을 사용할 수 없음"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2646 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s 옵션은 --slot 옵션을 함께 사용해야 함"
+
+#: pg_basebackup.c:2654 pg_basebackup.c:2694 pg_basebackup.c:2705
+#: pg_basebackup.c:2713
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s 옵션과 %s 옵션은 함께 사용할 수 없음"
+
+#: pg_basebackup.c:2668
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "트랜잭션 로그 디렉터리 위치는 백업 타켓과 함께 지정할 수 없음"
+
+#: pg_basebackup.c:2674
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "트랜잭션 로그 디렉터리 위치는 plain 모드에서만 사용할 수 있음"
+
+#: pg_basebackup.c:2683
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "트랜잭션 로그 디렉터리 위치는 절대 경로여야 함"
+
+#: pg_basebackup.c:2784
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "\"%s\" 심벌릭 링크를 만들 수 없음: %m"
+
+#: pg_basebackup.c:2786
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "이 플랫폼에서는 심볼 링크가 지원되지 않음"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s 프로그램은 PostgreSQL 스트리밍 트랜잭션 로그를 수신하는 도구입니다.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"옵션들:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid ""
+" -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr ""
+" -D, --directory=DIR 지정한 디렉터리로 트랜잭션 로그 파일을 백업함\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN 지정한 LSN까지 받고 종료함\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid ""
+" --if-not-exists do not error if slot already exists when creating a "
+"slot\n"
+msgstr ""
+" --if-not-exists 슬롯을 새로 만들 때 이미 있어도 오류 내지 않음\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop 접속이 끊겼을 때 재연결 하지 않음\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid ""
+" --no-sync do not wait for changes to be written safely to "
+"disk\n"
+msgstr " --no-sync 디스크 쓰기 뒤 sync 작업 생략\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server "
+"(default: %d)\n"
+msgstr ""
+" -s, --status-interval=초\n"
+" 지정한 초 간격으로 서버로 상태 패킷을 보냄 (초기값: "
+"%d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid ""
+" --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous 쓰기 작업 후 즉시 트랜잭션 로그를 플러시 함\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" 압축 관련 속성 지정\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"추가 기능:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid ""
+" --create-slot create a new replication slot (for the slot's name "
+"see --slot)\n"
+msgstr ""
+" --create-slot 새 복제 슬롯을 만듬 (--slot 옵션에서 슬롯 이름 지"
+"정)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid ""
+" --drop-slot drop the replication slot (for the slot's name see "
+"--slot)\n"
+msgstr ""
+" --drop-slot 복제 슬롯 삭제 (--slot 옵션에서 슬롯 이름 지정)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "마무리된 세그먼트 위치: %X/%X (타임라인 %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "로그 스트리밍 중지된 위치: %X/%X (타임라인 %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "전환됨: 타임라인 %u, 위치 %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "인터럽터 시그널을 받음, 종료함"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "\"%s\" 디렉터리를 닫을 수 없음: %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "\"%s\" 조각 파일은 잘못된 크기임: %lld, 무시함"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "\"%s\" 압축 파일 열기 실패: %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "\"%s\" 압축 파일 작업 위치 찾기 실패: %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "\"%s\" 압축 파일 읽기 실패: %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "\"%s\" 압축 파일을 읽을 수 없음: %d 읽음, 전체 %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid ""
+"compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "\"%s\" 압축 파일은 압축 풀었을 때 잘못된 크기임: %d, 무시함"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "LZ4 압축 컨텍스트 정보를 생성할 수 없습니다: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "\"%s\" 파일을 읽을 수 없음: %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "\"%s\" 파일 압축 풀기 실패: %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "LZ4 압축 해제 컨텍스트 반환 실패: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid ""
+"compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "\"%s\" 압축된 조각 파일은 압축 풀었을 때 잘못된 크기임: %zu, 무시함"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid ""
+"cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "\"%s\" 파일 검사 실패: %s 압축을 지원 안하게 빌드되었음"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "로그 스트리밍 시작 위치: %X/%X (타임라인 %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "시작 위치 구문이 잘못됨 \"%s\""
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "--create-slot 옵션과 --drop-slot 옵션을 함께 사용할 수 없음"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "--synchronous 옵션과 --no-sync 옵션을 함께 사용할 수 없음"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "대상 디렉터리를 지정하지 않음"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "%s 압축을 아직 지원하지 않음"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid ""
+"replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "\"%s\" 슬롯을 이용한 복제 연결은 이 데이터베이스에서 사용할 수 없음"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "\"%s\" 이름의 복제 슬롯을 삭제 중"
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "\"%s\" 이름의 복제 슬롯을 만드는 중"
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "연결 끊김"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "연결 끊김; 다시 연결 하기 위해 %d 초를 기다리는 중"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s 프로그램은 논리 디코딩 스트림을 제어하는 도구입니다.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"성능에 관계된 기능들:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid ""
+" --start start streaming in a replication slot (for the "
+"slot's name see --slot)\n"
+msgstr ""
+" --start 복제 슬롯을 이용한 스트리밍 시작 (--slot 옵션에서 슬"
+"롯 이름 지정)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=파일 작업 로그를 해당 파일에 기록, 표준 출력은 -\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: "
+"%d)\n"
+msgstr ""
+" -F --fsync-interval=초\n"
+" 지정한 초 간격으로 파일 fsync 작업을 함 (초기값: "
+"%d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid ""
+" -I, --startpos=LSN where in an existing slot should the streaming "
+"start\n"
+msgstr " -I, --startpos=LSN 스트리밍을 시작할 기존 슬롯 위치\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=이름[=값]\n"
+" 출력 플러그인에서 사용할 옵션들의 옵션 이름과 그 "
+"값\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN 사용할 출력 플러그인 (초기값: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=슬롯이름 논리 복제 슬롯 이름\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid ""
+" -t, --two-phase enable decoding of prepared transactions when "
+"creating a slot\n"
+msgstr ""
+" -t, --two-phase 슬롯을 만들 때 미리 준비된 트랜잭션 디코딩 활성화\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=디비이름 접속할 데이터베이스\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "쓰기 확인 위치: %X/%X, 플러시 위치 %X/%X (슬롯 %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "피드백 패킷을 보낼 수 없음: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "로그 스트리밍 시작 함, 위치: %X/%X (슬롯 %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "스트리밍 초기화 됨"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "\"%s\" 잠금파일을 열 수 없음: %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "잘못된 소켓: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() 실패: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "WAL 스트림에서 자료 받기 실패: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "스트리밍 헤더 크기가 너무 작음: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "알 수 없는 스트리밍 헤더: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "%d 바이트 쓰기 실패, 대상 로그파일 \"%s\": %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "복제 스트림의 예상치 못한 종료: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "시작 위치 구문이 잘못됨 \"%s\""
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "슬롯을 지정하지 않았음"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "대상 파일을 지정하지 않았음"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "데이터베이스 지정하지 않았음"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "적어도 하나 이상의 작업 방법을 지정해야 함"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr ""
+"--create-slot 옵션 또는 --start 옵션은 --drop-slot 옵션과 함께 사용할 수 없음"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr ""
+" --create-slot 옵션이나 --drop-slot 옵션은 --startpos 옵션과 함께 쓸 수 없음"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos 옵션은 --start 옵션과 함께 사용해야 함"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase 옵션은 --create-slot 옵션을 쓸 때만 사용 가능함"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "데이터베이스 의존적인 복제 연결을 할 수 없음"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "keepalive에 의해서 %X/%X 마지막 위치에 도달했음"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "%X/%X 마지막 위치가 WAL 레코드 %X/%X 위치에서 도달했음"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "\"%s\" archive status 파일을 만들 수 없습니다: %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "\"%s\" archive status 파일을 닫을 수 없습니다: %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "\"%s\" WAL 파일 크기를 알 수 없음: %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "이미 있는 \"%s\" 트랜잭션 로그 파일을 열 수 없음: %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "이미 있는 \"%s\" WAL 파일 fsync 실패: %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] ""
+"\"%s\" 트랜잭션 로그파일의 크기가 %zd 바이트임, 0 또는 %d 바이트여야 함"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "\"%s\" WAL 파일을 열 수 없음: %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "\"%s\" 파일의 시작 위치를 결정할 수 없음: %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "\"%s\" 이름 변경 실패, 세그먼트가 완료되지 않았음"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "\"%s\" 파일을 닫을 수 없음: %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "타임라인 %u 번을 위한 내역 파일 이름이 잘못 되었음: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "\"%s\" 타임라인 내역 파일을 만들 수 없음: %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "\"%s\" 타임라인 내역 파일에 쓸 수 없음: %s"
+
+#: receivelog.c:400
+#, c-format
+msgid ""
+"incompatible server version %s; client does not support streaming from "
+"server versions older than %s"
+msgstr ""
+"%s 서버 버전은 호환되지 않음; 클라이언트는 %s 버전 보다 오래된 서버의 스트리"
+"밍은 지원하지 않음"
+
+#: receivelog.c:409
+#, c-format
+msgid ""
+"incompatible server version %s; client does not support streaming from "
+"server versions newer than %s"
+msgstr ""
+"%s 서버 버전은 호환되지 않음; 클라이언트는 %s 버전 보다 새로운 서버의 스트리"
+"밍은 지원하지 않음"
+
+#: receivelog.c:514
+#, c-format
+msgid ""
+"system identifier does not match between base backup and streaming connection"
+msgstr "시스템 식별자가 베이스 백업과 스트리밍 연결에서 서로 다름"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "%u 타임라인으로 시작하는 것을 서버에서 제공 하지 않음"
+
+#: receivelog.c:561
+#, c-format
+msgid ""
+"unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"TIMELINE_HISTORY 명령 결과가 잘못됨: 받은 값: 로우수 %d, 필드수 %d, 예상값: "
+"로우수 %d, 필드수 %d"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "서버가 잘못된 다음 타임라인 번호 %u 보고함, 이전 타임라인 번호 %u"
+
+#: receivelog.c:638
+#, c-format
+msgid ""
+"server stopped streaming timeline %u at %X/%X, but reported next timeline %u "
+"to begin at %X/%X"
+msgstr ""
+"서버의 중지 위치: 타임라인 %u, 위치 %X/%X, 하지만 보고 받은 위치: 타임라인 "
+"%u 위치 %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "복제 스트림이 중지 위치 전에 종료 되었음"
+
+#: receivelog.c:724
+#, c-format
+msgid ""
+"unexpected result set after end-of-timeline: got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"타임라인 끝에 잘못된 결과가 발견 됨: 로우수 %d, 필드수 %d / 예상값: 로우수 "
+"%d, 필드수 %d"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "다음 타임라인 시작 위치 분석 실패 \"%s\""
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "\"%s\" 파일 fsync 실패: %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "%u 위치의 수신된 트랜잭션 로그 레코드에 파일을 열 수 없음"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "잘못된 WAL 자료 위치 %08x, 기대값 %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "%d 바이트를 \"%s\" WAL 파일에 쓸 수 없음: %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "copy-end 패킷을 보낼 수 없음: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "암호: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "서버 접속 실패"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "search_path를 지울 수 없음: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "integer_datetimes 서버 설정을 알 수 없음"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "integer_datetimes 컴파일 플래그가 서버와 일치하지 않음"
+
+#: streamutil.c:299
+#, c-format
+msgid ""
+"could not fetch WAL segment size: got %d rows and %d fields, expected %d "
+"rows and %d or more fields"
+msgstr ""
+"WAL 조각 크기 계산 실패: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, 필드수 %d "
+"이상"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "WAL 조각 크기 분석 못함"
+
+#: streamutil.c:327
+#, c-format
+msgid ""
+"WAL segment size must be a power of two between 1 MB and 1 GB, but the "
+"remote server reported a value of %d byte"
+msgid_plural ""
+"WAL segment size must be a power of two between 1 MB and 1 GB, but the "
+"remote server reported a value of %d bytes"
+msgstr[0] ""
+"WAL 조각 파일 크기는 1MB에서 1GB사이 2의 제곱 크기여야 하는데, 원격 서버는 "
+"%d 바이트입니다."
+
+#: streamutil.c:372
+#, c-format
+msgid ""
+"could not fetch group access flag: got %d rows and %d fields, expected %d "
+"rows and %d or more fields"
+msgstr ""
+"그룹 접근 플래그를 가져올 수 없음: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, "
+"필드수 %d 이상"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "그룹 접근 플래그를 분석 못함: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid ""
+"could not identify system: got %d rows and %d fields, expected %d rows and "
+"%d or more fields"
+msgstr ""
+"시스템을 식별할 수 없음: 로우수 %d, 필드수 %d, 예상값: 로우수 %d, 필드수 %d "
+"이상"
+
+#: streamutil.c:513
+#, c-format
+msgid ""
+"could not read replication slot \"%s\": got %d rows and %d fields, expected "
+"%d rows and %d fields"
+msgstr ""
+"\"%s\" 복제 슬롯을 읽을 수 없음: 로우수 %d, 필드수 %d, 기대값 로우수 %d, 필드"
+"수 %d"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "\"%s\" 이름의 복제 슬롯이 없습니다"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "물리 복제 슬롯을 사용해야 함, \"%s\" 복제 슬롯임"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "\"%s\" restart_lsn 위치를 해석할 수 없음, 해당 슬롯: \"%s\""
+
+#: streamutil.c:667
+#, c-format
+msgid ""
+"could not create replication slot \"%s\": got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"\"%s\" 복제 슬롯을 만들 수 없음: 로우수 %d, 필드수 %d, 기대값 로우수 %d, 필드"
+"수 %d"
+
+#: streamutil.c:711
+#, c-format
+msgid ""
+"could not drop replication slot \"%s\": got %d rows and %d fields, expected "
+"%d rows and %d fields"
+msgstr ""
+"\"%s\" 복제 슬롯을 삭제할 수 없음: 로우수 %d, 필드수 %d, 기대값 로우수 %d, 필"
+"드수 %d"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "자료를 압축할 수 없음"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "압축 스트림을 리셋할 수 없음"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "구현 오류: tar 파일은 하나 이상 열 수 없음"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "tar 해더를 만들 수 없음"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "압축 매개 변수를 바꿀 수 없음"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "압축 상태에서 파일 삭제는 지원하지 않음"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "압축 스트림을 닫을 수 없음"
diff --git a/src/bin/pg_basebackup/po/ru.po b/src/bin/pg_basebackup/po/ru.po
new file mode 100644
index 0000000..07bb56d
--- /dev/null
+++ b/src/bin/pg_basebackup/po/ru.po
@@ -0,0 +1,2178 @@
+# Russian message translation file for pg_basebackup
+# Copyright (C) 2012-2016 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Alexander Lakhin <exclusion@gmail.com>, 2012-2017, 2018, 2019, 2020, 2021, 2022.
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_basebackup (PostgreSQL current)\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-11-01 14:40+0300\n"
+"PO-Revision-Date: 2022-09-29 12:01+0300\n"
+"Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n"
+"Language-Team: Russian <pgsql-ru-general@postgresql.org>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "ошибка: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "предупреждение: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "подробности: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "подсказка: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "эта сборка программы не поддерживает сжатие %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "вместо указания параметра сжатия получена пустая строка"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "нераспознанный параметр сжатия: \"%s\""
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "для параметра сжатия \"%s\" требуется значение"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "значение параметра сжатия \"%s\" должно быть целочисленным"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "для алгоритма сжатия \"%s\" нельзя задать уровень сжатия"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid ""
+"compression algorithm \"%s\" expects a compression level between %d and %d "
+"(default at %d)"
+msgstr ""
+"для алгоритма сжатия \"%s\" ожидается уровень сжатия от %d до %d (по "
+"умолчанию %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "для алгоритма сжатия \"%s\" нельзя задать число потоков"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "нехватка памяти\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "попытка дублирования нулевого указателя (внутренняя ошибка)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "не удалось получить информацию о файле \"%s\": %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "не удалось открыть каталог \"%s\": %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "не удалось прочитать каталог \"%s\": %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "не удалось открыть файл \"%s\": %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "не удалось синхронизировать с ФС файл \"%s\": %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2266 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "не удалось переименовать файл \"%s\" в \"%s\": %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "неверное значение \"%s\" для параметра %s"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "значение %s должно быть в диапазоне %d..%d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1646
+#, c-format
+msgid "out of memory"
+msgstr "нехватка памяти"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1443 pg_basebackup.c:1737
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "не удалось записать в файл \"%s\": %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1507 pg_basebackup.c:1716
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "не удалось создать файл \"%s\": %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "не удалось закрыть файл \"%s\": %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "неожиданное состояние при извлечении архива"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:696 pg_basebackup.c:740
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "не удалось создать каталог \"%s\": %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "не удалось установить права для каталога \"%s\": %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "не удалось создать символическую ссылку \"%s\" в \"%s\": %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "не удалось установить права доступа для файла \"%s\": %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "не удалось создать сжатый файл \"%s\": %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "не удалось продублировать stdout: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "не удалось открыть выходной файл: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "не удалось установить уровень сжатия %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "эта сборка программы не поддерживает сжатие gzip"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "не удалось записать сжатый файл \"%s\": %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "не удалось закрыть сжатый файл \"%s\": %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "не удалось инициализировать библиотеку сжатия"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "не удалось распаковать данные: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "неожиданное состояние при внедрении параметров восстановления"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "не удалось создать контекст сжатия lz4: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "эта сборка программы не поддерживает сжатие lz4"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "не удалось записать заголовок lz4: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "не удалось сжать данные: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "не удалось завершить сжатие lz4: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "не удалось инициализировать библиотеку сжатия: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "окончание файла tar занимает больше 2 блоков"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "неожиданное состояние при разборе архива tar"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "пустое имя у компонента tar"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "поток COPY закончился до завершения последнего файла"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "не удалось создать контекст сжатия zstd"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "не удалось установить для zstd уровень сжатия %d: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "не удалось установить для zstd число потоков %d: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "эта сборка программы не поддерживает сжатие zstd"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "не удалось создать контекст распаковки zstd"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "удаление каталога данных \"%s\""
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "ошибка при удалении каталога данных"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "удаление содержимого каталога данных \"%s\""
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "ошибка при удалении содержимого каталога данных"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "удаление каталога WAL \"%s\""
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "ошибка при удалении каталога WAL"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "удаление содержимого каталога WAL \"%s\""
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "ошибка при удалении содержимого каталога WAL"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "каталог данных \"%s\" не был удалён по запросу пользователя"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "каталог WAL \"%s\" не был удалён по запросу пользователя"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "изменения в каталогах табличных пространств не будут отменены"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "слишком длинное имя каталога"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "несколько знаков \"=\" в сопоставлении табличного пространства"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr ""
+"сопоставление табл. пространства записано неверно: \"%s\"; должно быть "
+"\"СТАРЫЙ_КАТАЛОГ=НОВЫЙ_КАТАЛОГ\""
+
+#: pg_basebackup.c:361
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr ""
+"старый каталог в сопоставлении табл. пространства задан не абсолютным путём: "
+"%s"
+
+#: pg_basebackup.c:365
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr ""
+"новый каталог в сопоставлении табл. пространства задан не абсолютным путём: "
+"%s"
+
+#: pg_basebackup.c:387
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s делает базовую резервную копию работающего сервера PostgreSQL.\n"
+"\n"
+
+#: pg_basebackup.c:389 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Использование:\n"
+
+#: pg_basebackup.c:390 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [ПАРАМЕТР]...\n"
+
+#: pg_basebackup.c:391
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Параметры, управляющие выводом:\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=КАТАЛОГ сохранить базовую копию в указанный каталог\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr ""
+" -F, --format=p|t формат вывода (p (по умолчанию) - простой, t - "
+"tar)\n"
+
+#: pg_basebackup.c:394
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=СКОРОСТЬ макс. скорость передачи данных в целевой каталог\n"
+" (в КБ/с, либо добавьте суффикс \"k\" или \"M\")\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" записать конфигурацию для репликации\n"
+
+# well-spelled: ИНФО
+#: pg_basebackup.c:398
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=ПОЛУЧАТЕЛЬ[:ДОП_ИНФО]\n"
+" получатель копии (если отличается от client)\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=СТАРЫЙ_КАТАЛОГ=НОВЫЙ_КАТАЛОГ\n"
+" перенести табличное пространство из старого "
+"каталога\n"
+" в новый\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr ""
+" --waldir=КАТАЛОГ_WAL\n"
+" расположение каталога с журналом предзаписи\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" включить в копию требуемые файлы WAL, используя\n"
+" заданный метод\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip сжать выходной tar\n"
+
+# well-spelled: ИНФО
+#: pg_basebackup.c:406
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]МЕТОД[:ДОП_ИНФО]\n"
+" выполнять сжатие на клиенте или сервере как "
+"указано\n"
+
+#: pg_basebackup.c:408
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none не сжимать вывод tar\n"
+
+#: pg_basebackup.c:409
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Общие параметры:\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" режим быстрых или распределённых контрольных точек\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot создать слот репликации\n"
+
+#: pg_basebackup.c:413
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=МЕТКА установить метку резервной копии\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean не очищать после ошибок\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid ""
+" -N, --no-sync do not wait for changes to be written safely to "
+"disk\n"
+msgstr ""
+" -N, --no-sync не ждать завершения сохранения данных на диске\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress показывать прогресс операции\n"
+
+#: pg_basebackup.c:417 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=ИМЯ_СЛОТА использовать заданный слот репликации\n"
+
+#: pg_basebackup.c:418 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose выводить подробные сообщения\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version показать версию и выйти\n"
+
+#: pg_basebackup.c:420
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" алгоритм подсчёта контрольных сумм в манифесте\n"
+
+# skip-rule: capital-letter-first
+# well-spelled: шестнадц
+#: pg_basebackup.c:422
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" записывать все имена файлов в манифесте в шестнадц. "
+"виде\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr ""
+" --no-estimate-size не рассчитывать размер копии на стороне сервера\n"
+
+#: pg_basebackup.c:425
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest отключить создание манифеста копии\n"
+
+#: pg_basebackup.c:426
+#, c-format
+msgid ""
+" --no-slot prevent creation of temporary replication slot\n"
+msgstr ""
+" --no-slot предотвратить создание временного слота репликации\n"
+
+#: pg_basebackup.c:427
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" не проверять контрольные суммы\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help показать эту справку и выйти\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Параметры подключения:\n"
+
+#: pg_basebackup.c:431 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=СТРОКА строка подключения\n"
+
+#: pg_basebackup.c:432 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=ИМЯ имя сервера баз данных или каталог сокетов\n"
+
+#: pg_basebackup.c:433 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=ПОРТ номер порта сервера БД\n"
+
+#: pg_basebackup.c:434
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in "
+"seconds)\n"
+msgstr ""
+" -s, --status-interval=ИНТЕРВАЛ\n"
+" интервал между передаваемыми серверу\n"
+" пакетами состояния (в секундах)\n"
+
+#: pg_basebackup.c:436 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr ""
+" -U, --username=NAME connect as specified database user\n"
+" -U, --username=ИМЯ имя пользователя баз данных\n"
+
+#: pg_basebackup.c:437 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password не запрашивать пароль\n"
+
+#: pg_basebackup.c:438 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid ""
+" -W, --password force password prompt (should happen "
+"automatically)\n"
+msgstr ""
+" -W, --password запрашивать пароль всегда (обычно не требуется)\n"
+
+#: pg_basebackup.c:439 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Об ошибках сообщайте по адресу <%s>.\n"
+
+#: pg_basebackup.c:440 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Домашняя страница %s: <%s>\n"
+
+#: pg_basebackup.c:482
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "не удалось прочитать из готового канала: %m"
+
+#: pg_basebackup.c:485 pg_basebackup.c:632 pg_basebackup.c:2180
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "не удалось разобрать положение в журнале предзаписи \"%s\""
+
+#: pg_basebackup.c:591 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "не удалось завершить запись файлов WAL: %m"
+
+#: pg_basebackup.c:641
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "не удалось создать канал для фонового процесса: %m"
+
+#: pg_basebackup.c:674
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "создан временный слот репликации \"%s\""
+
+#: pg_basebackup.c:677
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "создан слот репликации \"%s\""
+
+#: pg_basebackup.c:711
+#, c-format
+msgid "could not create background process: %m"
+msgstr "не удалось создать фоновый процесс: %m"
+
+#: pg_basebackup.c:720
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "не удалось создать фоновый поток выполнения: %m"
+
+#: pg_basebackup.c:759
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "каталог \"%s\" существует, но он не пуст"
+
+#: pg_basebackup.c:765
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "ошибка доступа к каталогу \"%s\": %m"
+
+#: pg_basebackup.c:842
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s КБ (100%%), табличное пространство %d/%d %*s"
+msgstr[1] "%*s/%s КБ (100%%), табличное пространство %d/%d %*s"
+msgstr[2] "%*s/%s КБ (100%%), табличное пространство %d/%d %*s"
+
+#: pg_basebackup.c:854
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s КБ (%d%%), табличное пространство %d/%d (%s%-*.*s)"
+msgstr[1] "%*s/%s КБ (%d%%), табличное пространство %d/%d (%s%-*.*s)"
+msgstr[2] "%*s/%s КБ (%d%%), табличное пространство %d/%d (%s%-*.*s)"
+
+#: pg_basebackup.c:870
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s КБ (%d%%), табличное пространство %d/%d"
+msgstr[1] "%*s/%s КБ (%d%%), табличное пространство %d/%d"
+msgstr[2] "%*s/%s КБ (%d%%), табличное пространство %d/%d"
+
+#: pg_basebackup.c:894
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "неверное значение (\"%s\") для скорости передачи данных"
+
+#: pg_basebackup.c:896
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "неверная скорость передачи данных \"%s\": %m"
+
+#: pg_basebackup.c:903
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "скорость передачи должна быть больше 0"
+
+#: pg_basebackup.c:933
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "неверная единица измерения в --max-rate: \"%s\""
+
+#: pg_basebackup.c:937
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "скорость передачи \"%s\" вне целочисленного диапазона"
+
+#: pg_basebackup.c:944
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "скорость передачи \"%s\" вне диапазона"
+
+#: pg_basebackup.c:1040
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "не удалось получить поток данных COPY: %s"
+
+#: pg_basebackup.c:1057 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "не удалось прочитать данные COPY: %s"
+
+#: pg_basebackup.c:1061
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "фоновый процесс завершился неожиданно"
+
+#: pg_basebackup.c:1132
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "манифест нельзя внедрить в сжатый архив tar"
+
+#: pg_basebackup.c:1133
+#, c-format
+msgid ""
+"Use client-side compression, send the output to a directory rather than "
+"standard output, or use %s."
+msgstr ""
+"Примените сжатие на стороне клиента, передайте вывод в каталог, а не в "
+"стандартный вывод, или используйте %s."
+
+#: pg_basebackup.c:1149
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "обработать архив \"%s\" невозможно"
+
+#: pg_basebackup.c:1150
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Возможна обработка только архивов tar."
+
+#: pg_basebackup.c:1152
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr ""
+"Когда используется простой формат, программа pg_basebackup должна обработать "
+"архив."
+
+#: pg_basebackup.c:1154
+#, c-format
+msgid ""
+"Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr ""
+"Когда в качестве выходного каталога используется \"-\", программа "
+"pg_basebackup должна обработать архив."
+
+#: pg_basebackup.c:1156
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr ""
+"Когда используется ключ -R, программа pg_basebackup должна обработать архив."
+
+#: pg_basebackup.c:1367
+#, c-format
+msgid "archives must precede manifest"
+msgstr "архивы должны предшествовать манифесту"
+
+#: pg_basebackup.c:1382
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "неверное имя архива: \"%s\""
+
+#: pg_basebackup.c:1454
+#, c-format
+msgid "unexpected payload data"
+msgstr "неожиданно получены данные"
+
+#: pg_basebackup.c:1597
+#, c-format
+msgid "empty COPY message"
+msgstr "пустое сообщение COPY"
+
+#: pg_basebackup.c:1599
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "неправильное сообщение COPY типа %d, длины %zu"
+
+#: pg_basebackup.c:1797
+#, c-format
+msgid "incompatible server version %s"
+msgstr "несовместимая версия сервера %s"
+
+#: pg_basebackup.c:1813
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Укажите -X none или -X fetch для отключения трансляции журнала."
+
+#: pg_basebackup.c:1881
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "получатели копий не поддерживаются данной версией сервера"
+
+#: pg_basebackup.c:1884
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr ""
+"при использовании получателя копии записать конфигурацию восстановления "
+"нельзя"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "сервер не поддерживает сжатие на стороне сервера"
+
+#: pg_basebackup.c:1921
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr ""
+"начинается базовое резервное копирование, ожидается завершение контрольной "
+"точки"
+
+#: pg_basebackup.c:1925
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "ожидание контрольной точки"
+
+#: pg_basebackup.c:1938 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "не удалось передать команду репликации \"%s\": %s"
+
+#: pg_basebackup.c:1946
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "не удалось инициализировать базовое резервное копирование: %s"
+
+#: pg_basebackup.c:1949
+#, c-format
+msgid ""
+"server returned unexpected response to BASE_BACKUP command; got %d rows and "
+"%d fields, expected %d rows and %d fields"
+msgstr ""
+"сервер вернул неожиданный ответ на команду BASE_BACKUP; получено строк: %d, "
+"полей: %d, а ожидалось строк: %d, полей: %d"
+
+#: pg_basebackup.c:1955
+#, c-format
+msgid "checkpoint completed"
+msgstr "контрольная точка завершена"
+
+#: pg_basebackup.c:1970
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "стартовая точка в журнале предзаписи: %s на линии времени %u"
+
+#: pg_basebackup.c:1978
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "не удалось получить заголовок резервной копии: %s"
+
+#: pg_basebackup.c:1981
+#, c-format
+msgid "no data returned from server"
+msgstr "сервер не вернул данные"
+
+#: pg_basebackup.c:2016
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr ""
+"в stdout можно вывести только одно табличное пространство, всего в СУБД их %d"
+
+#: pg_basebackup.c:2029
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "запуск фонового процесса считывания WAL"
+
+#: pg_basebackup.c:2111
+#, c-format
+msgid "backup failed: %s"
+msgstr "ошибка при создании копии: %s"
+
+#: pg_basebackup.c:2114
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "сервер не передал конечную позицию в журнале предзаписи"
+
+#: pg_basebackup.c:2117
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "конечная точка в журнале предзаписи: %s"
+
+#: pg_basebackup.c:2128
+#, c-format
+msgid "checksum error occurred"
+msgstr "выявлена ошибка контрольной суммы"
+
+#: pg_basebackup.c:2133
+#, c-format
+msgid "final receive failed: %s"
+msgstr "ошибка в конце передачи: %s"
+
+#: pg_basebackup.c:2157
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "ожидание завершения потоковой передачи фоновым процессом..."
+
+#: pg_basebackup.c:2161
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "не удалось отправить команду в канал фонового процесса: %m"
+
+#: pg_basebackup.c:2166
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "сбой при ожидании дочернего процесса: %m"
+
+#: pg_basebackup.c:2168
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "завершился дочерний процесс %d вместо ожидаемого %d"
+
+#: pg_basebackup.c:2170 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2190
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "сбой при ожидании дочернего потока: %m"
+
+#: pg_basebackup.c:2195
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "не удалось получить состояние завершения дочернего потока: %m"
+
+#: pg_basebackup.c:2198
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "дочерний поток завершился с ошибкой %u"
+
+#: pg_basebackup.c:2227
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "сохранение данных на диске..."
+
+#: pg_basebackup.c:2252
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "переименование backup_manifest.tmp в backup_manifest"
+
+#: pg_basebackup.c:2272
+#, c-format
+msgid "base backup completed"
+msgstr "базовое резервное копирование завершено"
+
+#: pg_basebackup.c:2361
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "неверный формат вывода \"%s\", должен быть \"plain\" или \"tar\""
+
+#: pg_basebackup.c:2405
+#, c-format
+msgid ""
+"invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr ""
+"неверный аргумент для wal-method — \"%s\", допускается только \"fetch\", "
+"\"stream\" или \"none\""
+
+#: pg_basebackup.c:2435
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr ""
+"неверный аргумент режима контрольных точек \"%s\"; должен быть \"fast\" или "
+"\"spread\""
+
+#: pg_basebackup.c:2486 pg_basebackup.c:2498 pg_basebackup.c:2520
+#: pg_basebackup.c:2532 pg_basebackup.c:2538 pg_basebackup.c:2590
+#: pg_basebackup.c:2601 pg_basebackup.c:2611 pg_basebackup.c:2617
+#: pg_basebackup.c:2624 pg_basebackup.c:2636 pg_basebackup.c:2648
+#: pg_basebackup.c:2656 pg_basebackup.c:2669 pg_basebackup.c:2675
+#: pg_basebackup.c:2684 pg_basebackup.c:2696 pg_basebackup.c:2707
+#: pg_basebackup.c:2715 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Для дополнительной информации попробуйте \"%s --help\"."
+
+#: pg_basebackup.c:2496 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "слишком много аргументов командной строки (первый: \"%s\")"
+
+#: pg_basebackup.c:2519
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "указать и формат, и получателя копии одновременно нельзя"
+
+#: pg_basebackup.c:2531
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "необходимо указать выходной каталог или получателя копии"
+
+#: pg_basebackup.c:2537
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "указать и выходной каталог, и получателя копии одновременно нельзя"
+
+#: pg_basebackup.c:2567 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "нераспознанный алгоритм сжатия: \"%s\""
+
+#: pg_basebackup.c:2573 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "неправильное указание сжатия: %s"
+
+#: pg_basebackup.c:2589
+#, c-format
+msgid ""
+"client-side compression is not possible when a backup target is specified"
+msgstr "сжатие на стороне клиента невозможно при указании получателя копии"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "сжиматься могут только резервные копии в архиве tar"
+
+#: pg_basebackup.c:2610
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "потоковая передача WAL невозможна при указании получателя копии"
+
+#: pg_basebackup.c:2616
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "транслировать журналы предзаписи в режиме tar в поток stdout нельзя"
+
+#: pg_basebackup.c:2623
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "слоты репликации можно использовать только при потоковой передаче WAL"
+
+#: pg_basebackup.c:2635
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot нельзя использовать с именем слота"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2646 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "для %s необходимо задать слот с помощью параметра --slot"
+
+#: pg_basebackup.c:2654 pg_basebackup.c:2694 pg_basebackup.c:2705
+#: pg_basebackup.c:2713
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "параметры %s и %s несовместимы"
+
+#: pg_basebackup.c:2668
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "расположение каталога WAL нельзя указать вместе с получателем копии"
+
+#: pg_basebackup.c:2674
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "расположение каталога WAL можно указать только в режиме plain"
+
+#: pg_basebackup.c:2683
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "расположение каталога WAL должно определяться абсолютным путём"
+
+#: pg_basebackup.c:2784
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "не удалось создать символическую ссылку \"%s\": %m"
+
+#: pg_basebackup.c:2786
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "символические ссылки не поддерживаются в этой ОС"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s получает транслируемые журналы предзаписи PostgreSQL.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Параметры:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid ""
+" -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr ""
+" -D, --directory=ПУТЬ сохранять файлы журнала предзаписи в данный "
+"каталог\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr ""
+" -E, --endpos=LSN определяет позицию, после которой нужно "
+"остановиться\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid ""
+" --if-not-exists do not error if slot already exists when creating a "
+"slot\n"
+msgstr ""
+" --if-not-exists не выдавать ошибку при попытке создать уже "
+"существующий слот\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop прерывать работу при потере соединения\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid ""
+" --no-sync do not wait for changes to be written safely to "
+"disk\n"
+msgstr ""
+" --no-sync не ждать надёжного сохранения изменений на диске\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server "
+"(default: %d)\n"
+msgstr ""
+" -s, --status-interval=СЕК\n"
+" интервал между отправкой статусных пакетов серверу "
+"(по умолчанию: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid ""
+" --synchronous flush write-ahead log immediately after writing\n"
+msgstr ""
+" --synchronous сбрасывать журнал предзаписи сразу после записи\n"
+
+# well-spelled: ИНФО
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=МЕТОД[:ДОП_ИНФО]\n"
+" выполнять сжатие как указано\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Дополнительные действия:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid ""
+" --create-slot create a new replication slot (for the slot's name "
+"see --slot)\n"
+msgstr ""
+" --create-slot создать новый слот репликации (имя слота задаёт "
+"параметр --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid ""
+" --drop-slot drop the replication slot (for the slot's name see "
+"--slot)\n"
+msgstr ""
+" --drop-slot удалить слот репликации (имя слота задаёт параметр "
+"--slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "завершён сегмент %X/%X (линия времени %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "завершена передача журнала с позиции %X/%X (линия времени %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "переключение на линию времени %u (позиция %X/%X)"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "получен сигнал прерывания, работа завершается"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "не удалось закрыть каталог \"%s\": %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "файл сегмента \"%s\" имеет неправильный размер %lld, файл пропускается"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "не удалось открыть сжатый файл \"%s\": %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "ошибка позиционирования в сжатом файле \"%s\": %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "не удалось прочитать сжатый файл \"%s\": %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "не удалось прочитать сжатый файл \"%s\" (прочитано байт: %d из %zu)"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid ""
+"compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr ""
+"файл сжатого сегмента \"%s\" имеет неправильный исходный размер %d, файл "
+"пропускается"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "не удалось создать контекст распаковки LZ4: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "не удалось прочитать файл \"%s\": %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "не удалось распаковать файл \"%s\": %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "не удалось освободить контекст распаковки LZ4: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid ""
+"compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr ""
+"файл сжатого сегмента \"%s\" имеет неправильный исходный размер %zu, файл "
+"пропускается"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid ""
+"cannot check file \"%s\": compression with %s not supported by this build"
+msgstr ""
+"не удалось проверить файл \"%s\": сжатие методом %s не поддерживается данной "
+"сборкой"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "начало передачи журнала с позиции %X/%X (линия времени %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "не удалось разобрать конечную позицию \"%s\""
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "--create-slot нельзя применять вместе с --drop-slot"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "--synchronous нельзя применять вместе с --no-sync"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "целевой каталог не указан"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "метод сжатия %s ещё не поддерживается"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid ""
+"replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr ""
+"подключение для репликации через слот \"%s\" оказалось привязано к базе "
+"данных"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "удаление слота репликации \"%s\""
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "создание слота репликации \"%s\""
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "отключение"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "отключение; через %d сек. последует повторное подключение"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s управляет потоками логического декодирования PostgreSQL.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Действие, которое будет выполнено:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid ""
+" --start start streaming in a replication slot (for the "
+"slot's name see --slot)\n"
+msgstr ""
+" --start начать передачу в слоте репликации (имя слота "
+"задаёт параметр --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr ""
+" -f, --file=ФАЙЛ сохранять журнал в этот файл, - обозначает stdout\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: "
+"%d)\n"
+msgstr ""
+" -F --fsync-interval=СЕК\n"
+" периодичность сброса на диск выходного файла (по "
+"умолчанию: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid ""
+" -I, --startpos=LSN where in an existing slot should the streaming "
+"start\n"
+msgstr ""
+" -I, --startpos=LSN определяет, с какой позиции в существующем слоте "
+"начнётся передача\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=ИМЯ[=ЗНАЧЕНИЕ]\n"
+" передать параметр с заданным именем и "
+"необязательным\n"
+" значением модулю вывода\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr ""
+" -P, --plugin=МОДУЛЬ использовать заданный модуль вывода (по умолчанию: "
+"%s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=ИМЯ_СЛОТА имя слота логической репликации\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid ""
+" -t, --two-phase enable decoding of prepared transactions when "
+"creating a slot\n"
+msgstr ""
+" -t, --two-phase включить декодирование подготовленных транзакций "
+"при создании слота\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=ИМЯ_БД целевая база данных\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "подтверждается запись до %X/%X, синхронизация с ФС до %X/%X (слот %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "не удалось отправить пакет ответа: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "начало передачи журнала с позиции %X/%X (слот %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "передача запущена"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "не удалось открыть файл протокола \"%s\": %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "неверный сокет: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "ошибка в %s(): %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "не удалось получить данные из потока WAL: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "заголовок потока слишком мал: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "нераспознанный заголовок потока: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "не удалось записать %d Б в файл журнала \"%s\": %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "неожиданный конец потока репликации: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "не удалось разобрать начальную позицию \"%s\""
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "слот не указан"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "целевой файл не задан"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "база данных не задана"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "необходимо задать минимум одно действие"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "--create-slot или --start нельзя применять вместе с --drop-slot"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "--create-slot или --drop-slot нельзя применять вместе с --startpos"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos можно задать только вместе с --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase можно задать только вместе с --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr ""
+"не удалось установить подключение для репликации к определённой базе данных"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "конечная позиция %X/%X достигнута при обработке keepalive"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "конечная позиция %X/%X достигнута при обработке записи WAL %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "не удалось создать файл статуса архива \"%s\": %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "не удалось закрыть файл статуса архива \"%s\": %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "не удалось получить размер файла журнала предзаписи \"%s\": %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "не удалось открыть существующий файл журнала предзаписи \"%s\": %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr ""
+"не удалось сбросить на диск существующий файл журнала предзаписи \"%s\": %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] ""
+"файл журнала предзаписи \"%s\" имеет размер %zd Б, а должен — 0 или %d"
+msgstr[1] ""
+"файл журнала предзаписи \"%s\" имеет размер %zd Б, а должен — 0 или %d"
+msgstr[2] ""
+"файл журнала предзаписи \"%s\" имеет размер %zd Б, а должен — 0 или %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "не удалось открыть файл журнала предзаписи \"%s\": %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "не удалось определить текущую позицию в файле \"%s\": %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "файл сегмента \"%s\" не переименовывается, так как он неполный"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "не удалось закрыть файл \"%s\": %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "сервер сообщил неожиданное имя файла истории для линии времени %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "не удалось создать файл истории линии времени \"%s\": %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "не удалось записать файл истории линии времени \"%s\": %s"
+
+#: receivelog.c:400
+#, c-format
+msgid ""
+"incompatible server version %s; client does not support streaming from "
+"server versions older than %s"
+msgstr ""
+"несовместимая версия сервера %s; клиент не поддерживает репликацию с "
+"серверов версии ниже %s"
+
+#: receivelog.c:409
+#, c-format
+msgid ""
+"incompatible server version %s; client does not support streaming from "
+"server versions newer than %s"
+msgstr ""
+"несовместимая версия сервера %s; клиент не поддерживает репликацию с "
+"серверов версии выше %s"
+
+#: receivelog.c:514
+#, c-format
+msgid ""
+"system identifier does not match between base backup and streaming connection"
+msgstr ""
+"системный идентификатор базовой резервной копии отличается от идентификатора "
+"потоковой передачи"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "на сервере нет начальной линии времени %u"
+
+#: receivelog.c:561
+#, c-format
+msgid ""
+"unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"сервер вернул неожиданный ответ на команду TIMELINE_HISTORY; получено строк: "
+"%d, полей: %d, а ожидалось строк: %d, полей: %d"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "сервер неожиданно сообщил линию времени %u после линии времени %u"
+
+#: receivelog.c:638
+#, c-format
+msgid ""
+"server stopped streaming timeline %u at %X/%X, but reported next timeline %u "
+"to begin at %X/%X"
+msgstr ""
+"сервер прекратил передачу линии времени %u в %X/%X, но сообщил, что "
+"следующая линии времени %u начнётся в %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "поток репликации закончился до точки остановки"
+
+#: receivelog.c:724
+#, c-format
+msgid ""
+"unexpected result set after end-of-timeline: got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"сервер вернул неожиданный набор данных после конца линии времени; получено "
+"строк: %d, полей: %d, а ожидалось строк: %d, полей: %d"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "не удалось разобрать начальную точку следующей линии времени \"%s\""
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "не удалось синхронизировать с ФС файл \"%s\": %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "получена запись журнала предзаписи по смещению %u, но файл не открыт"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "получено смещение данных WAL %08x, но ожидалось %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "не удалось записать %d Б в файл WAL \"%s\": %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "не удалось отправить пакет \"конец COPY\": %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Пароль: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "не удалось подключиться к серверу"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "не удалось очистить search_path: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "не удалось получить настройку сервера integer_datetimes"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "флаг компиляции integer_datetimes не соответствует настройке сервера"
+
+#: streamutil.c:299
+#, c-format
+msgid ""
+"could not fetch WAL segment size: got %d rows and %d fields, expected %d "
+"rows and %d or more fields"
+msgstr ""
+"не удалось извлечь размер сегмента WAL; получено строк: %d, полей: %d "
+"(ожидалось: %d и %d (или более))"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "разобрать размер сегмента WAL не удалось"
+
+#: streamutil.c:327
+#, c-format
+msgid ""
+"WAL segment size must be a power of two between 1 MB and 1 GB, but the "
+"remote server reported a value of %d byte"
+msgid_plural ""
+"WAL segment size must be a power of two between 1 MB and 1 GB, but the "
+"remote server reported a value of %d bytes"
+msgstr[0] ""
+"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 "
+"ГБ, но удалённый сервер сообщил значение: %d"
+msgstr[1] ""
+"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 "
+"ГБ, но удалённый сервер сообщил значение: %d"
+msgstr[2] ""
+"размер сегмента WAL должен задаваться степенью 2 в интервале от 1 МБ до 1 "
+"ГБ, но удалённый сервер сообщил значение: %d"
+
+#: streamutil.c:372
+#, c-format
+msgid ""
+"could not fetch group access flag: got %d rows and %d fields, expected %d "
+"rows and %d or more fields"
+msgstr ""
+"не удалось извлечь флаг доступа группы; получено строк: %d, полей: %d "
+"(ожидалось: %d и %d (или более))"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "не удалось разобрать флаг доступа группы: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid ""
+"could not identify system: got %d rows and %d fields, expected %d rows and "
+"%d or more fields"
+msgstr ""
+"не удалось идентифицировать систему; получено строк: %d, полей: %d "
+"(ожидалось: %d и %d (или более))"
+
+#: streamutil.c:513
+#, c-format
+msgid ""
+"could not read replication slot \"%s\": got %d rows and %d fields, expected "
+"%d rows and %d fields"
+msgstr ""
+"прочитать из слота репликации \"%s\" не удалось; получено строк: %d, полей: "
+"%d (ожидалось: %d и %d)"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "слот репликации \"%s\" не существует"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "ожидался слот физической репликации, вместо этого получен тип \"%s\""
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr ""
+"не удалось разобрать позицию restart_lsn \"%s\" для слота репликации \"%s\""
+
+#: streamutil.c:667
+#, c-format
+msgid ""
+"could not create replication slot \"%s\": got %d rows and %d fields, "
+"expected %d rows and %d fields"
+msgstr ""
+"создать слот репликации \"%s\" не удалось; получено строк: %d, полей: %d "
+"(ожидалось: %d и %d)"
+
+#: streamutil.c:711
+#, c-format
+msgid ""
+"could not drop replication slot \"%s\": got %d rows and %d fields, expected "
+"%d rows and %d fields"
+msgstr ""
+"удалить слот репликации \"%s\" не получилось; получено строк: %d, полей: %d "
+"(ожидалось: %d и %d)"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "не удалось сжать данные"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "не удалось сбросить поток сжатых данных"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr ""
+"ошибка реализации: в файлах tar не может быть больше одно открытого файла"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "не удалось создать заголовок tar"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "не удалось изменить параметры сжатия"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "со сжатием закрытие файла с удалением не поддерживается"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "не удалось закрыть поток сжатых данных"
+
+#~ msgid "unknown compression option \"%s\""
+#~ msgstr "неизвестный параметр сжатия \"%s\""
+
+#~ msgid "could not check file \"%s\""
+#~ msgstr "не удалось проверить файл \"%s\""
+
+#~ msgid "This build does not support compression with %s."
+#~ msgstr "Эта сборка программы не поддерживает сжатие %s."
+
+#~ msgid "no value specified for --compress, switching to default"
+#~ msgstr ""
+#~ "для параметра --compress не задано значение, используется значение по "
+#~ "умолчанию"
+
+#~ msgid "could not find replication slot \"%s\""
+#~ msgstr "не удалось найти слот репликации \"%s\""
+
+#~ msgid "fatal: "
+#~ msgstr "важно: "
+
+#~ msgid ""
+#~ " -Z, --compress=0-9 compress tar output with given compression "
+#~ "level\n"
+#~ msgstr ""
+#~ " -Z, --compress=0-9 установить уровень сжатия выходного архива\n"
+
+#~ msgid "invalid tar block header size: %zu"
+#~ msgstr "неверный размер заголовка блока tar: %zu"
+
+#~ msgid "unrecognized link indicator \"%c\""
+#~ msgstr "нераспознанный индикатор связи \"%c\""
+
+#~ msgid "could not get write-ahead log end position from server: %s"
+#~ msgstr ""
+#~ "не удалось получить от сервера конечную позицию в журнале предзаписи: %s"
+
+#~ msgid "invalid status interval \"%s\""
+#~ msgstr "неверный интервал сообщений о состоянии \"%s\""
+
+#~ msgid ""
+#~ " -Z, --compress=0-9 compress logs with given compression level\n"
+#~ msgstr " -Z, --compress=0-9 установить уровень сжатия журналов\n"
+
+#~ msgid "invalid fsync interval \"%s\""
+#~ msgstr "неверный интервал синхронизации с ФС \"%s\""
+
+#~ msgid "--progress and --no-estimate-size are incompatible options"
+#~ msgstr "параметры --progress и --no-estimate-size несовместимы"
+
+#~ msgid "--no-manifest and --manifest-checksums are incompatible options"
+#~ msgstr "параметры --no-manifest и --manifest-checksums несовместимы"
+
+#~ msgid "--no-manifest and --manifest-force-encode are incompatible options"
+#~ msgstr "параметры --no-manifest и --manifest-force-encode несовместимы"
+
+#~ msgid "could not connect to server: %s"
+#~ msgstr "не удалось подключиться к серверу: %s"
+
+#~ msgid ""
+#~ "\n"
+#~ "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Об ошибках сообщайте по адресу <pgsql-bugs@lists.postgresql.org>.\n"
+
+#~ msgid "%s: out of memory\n"
+#~ msgstr "%s: нехватка памяти\n"
+
+#~ msgid "%s: child process did not exit normally\n"
+#~ msgstr "%s: дочерний процесс завершён ненормально\n"
+
+#~ msgid "%s: child process exited with error %d\n"
+#~ msgstr "%s: дочерний процесс завершился с ошибкой %d\n"
+
+#~ msgid "%s: could not fsync log file \"%s\": %s\n"
+#~ msgstr "%s: не удалось синхронизировать с ФС файл журнала \"%s\": %s\n"
+
+#~ msgid "%s: removing transaction log directory \"%s\"\n"
+#~ msgstr "%s: удаление каталога журнала транзакций \"%s\"\n"
+
+#~ msgid "%s: failed to remove transaction log directory\n"
+#~ msgstr "%s: ошибка при удалении каталога журнала транзакций\n"
+
+#~ msgid "%s: removing contents of transaction log directory \"%s\"\n"
+#~ msgstr "%s: очистка каталога журнала транзакций \"%s\"\n"
+
+#~ msgid "%s: failed to remove contents of transaction log directory\n"
+#~ msgstr "%s: ошибка при очистке каталога журнала транзакций\n"
+
+#~ msgid "%s: transaction log directory \"%s\" not removed at user's request\n"
+#~ msgstr ""
+#~ "%s: каталог журнала транзакций \"%s\" не был удалён по запросу "
+#~ "пользователя\n"
+
+#~ msgid "%s: could not open transaction log file \"%s\": %s\n"
+#~ msgstr "%s: не удалось открыть файл журнала транзакций \"%s\": %s\n"
+
+#~ msgid ""
+#~ " -x, --xlog include required WAL files in backup (fetch "
+#~ "mode)\n"
+#~ msgstr ""
+#~ " -x, --xlog включить в копию требуемые файлы WAL (режим "
+#~ "fetch)\n"
+
+#~ msgid "%s: WAL streaming can only be used in plain mode\n"
+#~ msgstr "%s: потоковая передача WAL поддерживается только в режиме plain\n"
+
+#~ msgid "%s: could not stat transaction log file \"%s\": %s\n"
+#~ msgstr "%s: не удалось проверить файл журнала транзакций \"%s\": %s\n"
+
+#~ msgid "%s: could not pad transaction log file \"%s\": %s\n"
+#~ msgstr "%s: не удалось дополнить файл журнала транзакций \"%s\": %s\n"
+
+#~ msgid "%s: could not rename file \"%s\": %s\n"
+#~ msgstr "%s: не удалось переименовать файл \"%s\": %s\n"
+
+#~ msgid "%s: could not open timeline history file \"%s\": %s\n"
+#~ msgstr "%s: не удалось открыть файл истории линии времени \"%s\": %s\n"
+
+#~ msgid "%s: could not parse file size\n"
+#~ msgstr "%s: не удалось разобрать размер файла\n"
+
+#~ msgid "%s: could not parse file mode\n"
+#~ msgstr "%s: не удалось разобрать режим файла\n"
+
+#~ msgid "%s: socket not open"
+#~ msgstr "%s: сокет не открыт"
+
+#~ msgid "%s: could not remove symbolic link \"%s\": %s\n"
+#~ msgstr "%s: ошибка при удалении символической ссылки \"%s\": %s\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "Replication options:\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Параметры репликации:\n"
+
+#~ msgid "%s: initializing replication slot \"%s\"\n"
+#~ msgstr "%s: инициализируется слот репликации \"%s\"\n"
+
+#~ msgid ""
+#~ "%s: could not init logical replication: got %d rows and %d fields, "
+#~ "expected %d rows and %d fields\n"
+#~ msgstr ""
+#~ "%s: не удалось инициализировать логическую репликацию; получено строк: "
+#~ "%d, полей: %d (ожидалось: %d и %d)\n"
+
+#~ msgid "%s: no start point returned from server\n"
+#~ msgstr "%s: сервер не вернул стартовую точку\n"
+
+#~ msgid ""
+#~ "%s: timeline does not match between base backup and streaming connection\n"
+#~ msgstr ""
+#~ "%s: линия времени базовой резервной копии отличается от линии времени "
+#~ "потоковой передачи\n"
+
+#~ msgid "%s: keepalive message has incorrect size %d\n"
+#~ msgstr "%s: контрольное сообщение имеет некорректный размер: %d\n"
+
+#~ msgid "%s: could not close file %s: %s\n"
+#~ msgstr "%s: не удалось закрыть файл %s: %s\n"
+
+#~ msgid "%s: invalid format of xlog location: %s\n"
+#~ msgstr "%s: неверный формат позиции в xlog: %s\n"
+
+#~ msgid "%s: could not identify system: %s"
+#~ msgstr "%s: не удалось идентифицировать систему: %s"
+
+#~ msgid "%s: could not send base backup command: %s"
+#~ msgstr ""
+#~ "%s: не удалось отправить команду базового резервного копирования: %s"
+
+#~ msgid "%s: could not identify system: %s\n"
+#~ msgstr "%s: не удалось идентифицировать систему: %s\n"
+
+#~ msgid "%s: could not open WAL segment %s: %s\n"
+#~ msgstr "%s: не удалось открыть сегмент WAL %s: %s\n"
+
+#~ msgid "%s: could not stat WAL segment %s: %s\n"
+#~ msgstr "%s: не удалось получить информацию о сегменте WAL %s: %s\n"
+
+#~ msgid "%s: could not pad WAL segment %s: %s\n"
+#~ msgstr "%s: не удалось дополнить сегмент WAL %s: %s\n"
+
+#~ msgid "%s: could not get current position in file %s: %s\n"
+#~ msgstr "%s: не удалось получить текущую позицию в файле %s: %s\n"
diff --git a/src/bin/pg_basebackup/po/sv.po b/src/bin/pg_basebackup/po/sv.po
new file mode 100644
index 0000000..c239ab7
--- /dev/null
+++ b/src/bin/pg_basebackup/po/sv.po
@@ -0,0 +1,1805 @@
+# SWEDISH message translation file for pg_basebackup
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Dennis Björklund <db@zigo.dhs.org>, 2017, 2018, 2019, 2020, 2021, 2022.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PostgreSQL 15\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-09-29 11:48+0000\n"
+"PO-Revision-Date: 2022-09-29 21:41+0200\n"
+"Last-Translator: Dennis Björklund <db@zigo.dhs.org>\n"
+"Language-Team: Swedish <pgsql-translators@postgresql.org>\n"
+"Language: sv\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=n != 1;\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "fel: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "varning: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "detalj: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "tips: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "detta bygge stöder inte komprimering med %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "hittade en tom sträng där en komprimeringsinställning förväntades"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "okänd komprimeringsflagga \"%s\""
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "komprimeringsflaggan \"%s\" kräver ett värde"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "värdet på komprimeringsflaggan \"%s\" måste vara ett heltal"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "komprimeringsalgoritmen \"%s\" stöder inte komprimeringsnivåer"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "komprimeringsalgoritmen \"%s\" förväntar sig en komprimeringsnivå mellan %d och %d (standard är %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "komprimeringsalgoritmen \"%s\" stöder inte inställning av antal arbetarprocesser"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "slut på minne\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "kan inte duplicera null-pekare (internt fel)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "kunde inte göra stat() på fil \"%s\": %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "kunde inte öppna katalog \"%s\": %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "kunde inte läsa katalog \"%s\": %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "kunde inte öppna fil \"%s\": %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "kunde inte fsync:a fil \"%s\": %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2256 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "kunde inte döpa om fil \"%s\" till \"%s\": %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "ogiltigt värde \"%s\" för flaggan \"%s\""
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s måste vara i intervallet %d..%d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1636
+#, c-format
+msgid "out of memory"
+msgstr "slut på minne"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1433 pg_basebackup.c:1727
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "kunde inte skriva till fil \"%s\": %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1497 pg_basebackup.c:1706
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "kunde inte skapa fil \"%s\": %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "kunde inte stänga fil \"%s\": %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "oväntat tillstånd vid uppackning av arkiv"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:686 pg_basebackup.c:730
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "kunde inte skapa katalog \"%s\": %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "kunde inte sätta rättigheter på katalogen \"%s\": %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "kunde inte skapa symbolisk länk från \"%s\" till \"%s\": %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "kunde inte sätta rättigheter på filen \"%s\": %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "kunde inte skapa komprimerad fil \"%s\": %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "kunde inte duplicera stdout: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "kunde inte öppna utdatafilen: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "kunde inte sätta komprimeringsnivå %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "detta bygge stöder inte gzip-komprimering"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "kunde inte skriva till komprimerad fil \"%s\": %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "kunde inte stänga komprimerad fil \"%s\": %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "kunde inte initierar komprimeringsbibliotek"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "kunde inte dekomprimera data: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "oväntat tillstånd vid injicering av återställningsinställningar"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "kunde inte skapa kontext för lz4-komprimering: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "detta bygge stöder inte lz4-komprimering"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "kunde inte skriva lz4-header: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "kunde inte komprimera data: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "kunde inte avsluta lz4-komprimering: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "kunde inte initiera komprimeringsbibliotek: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "tarfilens slutdel överskred 2 block"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "oväntat tillstånd vid parsning av tar-arkiv"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "tar-medlem har tomt namn"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "COPY-ström avslutade innan sista filen var klar"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "kunde inte skapa kontext för zstd-komprimering"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "kunde inte sätta zstd-komprimeringsnivå till %d: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "kunde inte sätta komprimeringsarbetarantalet till %d: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "detta bygge stöder inte zstd-komprimering"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "kunde inte skapa kontext för zstd-dekomprimering"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "tar bort datakatalog \"%s\""
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "misslyckades med att ta bort datakatalog"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "tar bort innehållet i datakatalog \"%s\""
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "misslyckades med att ta bort innehållet i datakatalogen"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "tar bort WAL-katalog \"%s\""
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "misslyckades med att ta bort WAL-katalog"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "tar bort innehållet i WAL-katalog \"%s\""
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "misslyckades med att ta bort innehållet i WAL-katalogen"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "datakatalog \"%s\" är ej borttagen på användares begäran"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "WAL-katalog \"%s\" är ej borttagen på användares begäran"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "ändringar av tablespace-kataloger kan inte backas"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "katalognamn för långt"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "multipla \"=\"-tecken i tablespace-mappning"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "ogiltigt tablespace-mappningsformat \"%s\", måste vara \"OLDDIR=NEWDIR\""
+
+#: pg_basebackup.c:351
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "gammal katalog är inte en absolut sökväg i tablespace-mappning: %s"
+
+#: pg_basebackup.c:355
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "ny katalog är inte en absolut sökväg i tablespace-mappning: %s"
+
+#: pg_basebackup.c:377
+#, c-format
+msgid ""
+"%s takes a base backup of a running PostgreSQL server.\n"
+"\n"
+msgstr ""
+"%s tar en basbackup av en körande PostgreSQL-server.\n"
+"\n"
+
+#: pg_basebackup.c:379 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Användning:\n"
+
+#: pg_basebackup.c:380 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s [FLAGGA]...\n"
+
+#: pg_basebackup.c:381
+#, c-format
+msgid ""
+"\n"
+"Options controlling the output:\n"
+msgstr ""
+"\n"
+"Flaggor som styr utmatning:\n"
+
+#: pg_basebackup.c:382
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, --pgdata=KATALOG ta emot basbackup till katalog\n"
+
+#: pg_basebackup.c:383
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|t utdataformat (plain (standard), tar)\n"
+
+#: pg_basebackup.c:384
+#, c-format
+msgid ""
+" -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr ""
+" -r, --max-rate=RATE maximal överföringshastighet för att överföra datakatalog\n"
+" (i kB/s, eller använd suffix \"k\" resp. \"M\")\n"
+
+#: pg_basebackup.c:386
+#, c-format
+msgid ""
+" -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr ""
+" -R, --write-recovery-conf\n"
+" skriv konfiguration för replikering\n"
+
+#: pg_basebackup.c:388
+#, c-format
+msgid ""
+" -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr ""
+" -t, --target=MÅL[:DETALJ]\n"
+" backupmål (om annat än klienten)\n"
+
+#: pg_basebackup.c:390
+#, c-format
+msgid ""
+" -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr ""
+" -T, --tablespace-mapping=GAMMALKAT=NYKAT\n"
+" flytta tablespace i GAMMALKAT till NYKAT\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr " --waldir=WALKAT plats för write-ahead-logg-katalog\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid ""
+" -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr ""
+" -X, --wal-method=none|fetch|stream\n"
+" inkludera behövda WAL-filer med angiven metod\n"
+
+#: pg_basebackup.c:395
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip komprimera tar-utdata\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid ""
+" -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METOD[:DETALJ]\n"
+" komprimera på klient- eller serversida\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none komprimera inte tar-utdata\n"
+
+#: pg_basebackup.c:399
+#, c-format
+msgid ""
+"\n"
+"General options:\n"
+msgstr ""
+"\n"
+"Allmänna flaggor:\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid ""
+" -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr ""
+" -c, --checkpoint=fast|spread\n"
+" ställ in \"fast\" eller \"spread\" checkpoint-metod\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " --create-slot skapa en replikeringsslot\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=ETIKETT sätt backup-etikett\n"
+
+#: pg_basebackup.c:404
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean städa inte upp efter fel\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " -N, --no-sync vänta inte på att ändringar skall skrivas säkert till disk\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress visa förloppsinformation\n"
+
+#: pg_basebackup.c:407 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=SLOTNAMN replikerings-slot att använda\n"
+
+#: pg_basebackup.c:408 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose mata ut utförliga meddelanden\n"
+
+#: pg_basebackup.c:409 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version visa versionsinformation, avsluta sedan\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr ""
+" --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" använd algoritm för manifestchecksummor\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid ""
+" --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr ""
+" --manifest-force-encode\n"
+" hex-koda alla filnamn i manifestet\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size estimerar inte backupstorlek på serversidan\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest förhindra att backupmanifest genereras\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot förhindra skapande av temporär replikerings-slot\n"
+
+#: pg_basebackup.c:417
+#, c-format
+msgid ""
+" --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr ""
+" --no-verify-checksums\n"
+" verifiera inte checksummor\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help visa den här hjälpen, avsluta sedan\n"
+
+#: pg_basebackup.c:420 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid ""
+"\n"
+"Connection options:\n"
+msgstr ""
+"\n"
+"Flaggor för anslutning:\n"
+
+#: pg_basebackup.c:421 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONNSTR anslutningssträng\n"
+
+#: pg_basebackup.c:422 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=HOSTNAMN databasserverns värdnamn eller socket-katalog\n"
+
+#: pg_basebackup.c:423 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT databasserverns postnummer\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid ""
+" -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr ""
+" -s, --status-interval=INTERVAL\n"
+" tid mellan att statuspaket skickas till servern (i sekunder)\n"
+
+#: pg_basebackup.c:426 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NAMN ansluta som angiven databasanvändare\n"
+
+#: pg_basebackup.c:427 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password fråga aldrig efter lösenord\n"
+
+#: pg_basebackup.c:428 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr " -W, --password tvinga fram lösenordsfråga (skall ske automatiskt)\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Rapportera fel till <%s>.\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "hemsida för %s: <%s>\n"
+
+#: pg_basebackup.c:472
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "kunde inte läsa från rör (pipe) som har data: %m"
+
+#: pg_basebackup.c:475 pg_basebackup.c:622 pg_basebackup.c:2170
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "kunde inte parsa write-ahead-logg-plats \"%s\""
+
+#: pg_basebackup.c:581 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "kunde inte slutföra skrivning av WAL-filer: %m"
+
+#: pg_basebackup.c:631
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "kunde inte skapa rör (pipe) för bakgrundsprocess: %m"
+
+#: pg_basebackup.c:664
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "skapade en temporär replikeringsslot \"%s\""
+
+#: pg_basebackup.c:667
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "skapade en replikeringsslot \"%s\""
+
+#: pg_basebackup.c:701
+#, c-format
+msgid "could not create background process: %m"
+msgstr "kunde inte skapa bakgrundsprocess: %m"
+
+#: pg_basebackup.c:710
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "kunde inte skapa bakgrundstråd: %m"
+
+#: pg_basebackup.c:749
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "katalogen \"%s\" existerar men är inte tom"
+
+#: pg_basebackup.c:755
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "kunde inte komma åt katalog \"%s\": %m"
+
+#: pg_basebackup.c:832
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgstr[1] "%*s/%s kB (100%%), %d/%d tablespace %*s"
+
+#: pg_basebackup.c:844
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+
+#: pg_basebackup.c:860
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d tablespace"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d tablespace"
+
+#: pg_basebackup.c:884
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "överföringshastighet \"%s\" är inte ett giltigt värde"
+
+#: pg_basebackup.c:886
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "ogiltig överföringshastighet \"%s\": %m"
+
+#: pg_basebackup.c:893
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "överföringshastigheten måste vara större än noll"
+
+#: pg_basebackup.c:923
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "ogiltig enhet för --max-rate: \"%s\""
+
+#: pg_basebackup.c:927
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "överföringshastighet \"%s\" överskrider heltalsintervall"
+
+#: pg_basebackup.c:934
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "överföringshastighet \"%s\" är utanför sitt intervall"
+
+#: pg_basebackup.c:1030
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "kunde inte hämta COPY-data-ström: %s"
+
+#: pg_basebackup.c:1047 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "kunde inte läsa COPY-data: %s"
+
+#: pg_basebackup.c:1051
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "en bakgrundsprocess avslutade oväntat"
+
+#: pg_basebackup.c:1122
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "kan inte injicera manifest in i en komprimerad tarfil"
+
+#: pg_basebackup.c:1123
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "använd komprimering på klientsidan, skicka utdatan till en katalog istället för till standard ut eller använd %s."
+
+#: pg_basebackup.c:1139
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "kunde inte parsa arkiv \"%s\""
+
+#: pg_basebackup.c:1140
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Bara tar-arkiv kan parsas."
+
+#: pg_basebackup.c:1142
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Enkelt format kräver pg_basebackup för att parsa arkivet."
+
+#: pg_basebackup.c:1144
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "Att använda - som utkatalog kräver att pg_basebackup parsar arkivet."
+
+#: pg_basebackup.c:1146
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "Flaggan -R kräver att pg_basebackup parsar arkivet."
+
+#: pg_basebackup.c:1357
+#, c-format
+msgid "archives must precede manifest"
+msgstr "arkiv skall komma före manifest"
+
+#: pg_basebackup.c:1372
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "ogiltigt arkivnamn: \"%s\""
+
+#: pg_basebackup.c:1444
+#, c-format
+msgid "unexpected payload data"
+msgstr "oväntat datainnehåll"
+
+#: pg_basebackup.c:1587
+#, c-format
+msgid "empty COPY message"
+msgstr "tomt COPY-meddelande"
+
+#: pg_basebackup.c:1589
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "felaktigt COPY-meddelande av typ %d, längd %zu"
+
+#: pg_basebackup.c:1787
+#, c-format
+msgid "incompatible server version %s"
+msgstr "inkompatibel serverversion %s"
+
+#: pg_basebackup.c:1803
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Använd -X none eller -X fetch för att stänga av logg-strömning"
+
+#: pg_basebackup.c:1871
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "backupmål stöds inte av denna serverversion"
+
+#: pg_basebackup.c:1874
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "återställningskonfiguration kan inte skrivas när backupmål används"
+
+#: pg_basebackup.c:1901
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "servern stöder inte komprimering på serversidan"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "initierar basbackup, väntar på att checkpoint skall gå klart"
+
+#: pg_basebackup.c:1915
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "väntar på checkpoint"
+
+#: pg_basebackup.c:1928 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "kunde inte skicka replikeringskommando \"%s\": %s"
+
+#: pg_basebackup.c:1936
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "kunde inte initiera basbackup: %s"
+
+#: pg_basebackup.c:1939
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "servern retunerade ett oväntat svar på BASE_BACKUP-kommandot; fick %d rader och %d fält, förväntade %d rader och %d fält"
+
+#: pg_basebackup.c:1945
+#, c-format
+msgid "checkpoint completed"
+msgstr "checkpoint klar"
+
+#: pg_basebackup.c:1960
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "write-ahead-loggens startposition: %s på tidslinje %u"
+
+#: pg_basebackup.c:1968
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "kunde inte hämta backup-header: %s"
+
+#: pg_basebackup.c:1971
+#, c-format
+msgid "no data returned from server"
+msgstr "ingen data returnerades från servern"
+
+#: pg_basebackup.c:2006
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "kunde bara skriva en endaste tablespace till stdout, databasen har %d"
+
+#: pg_basebackup.c:2019
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "startar bakgrunds-WAL-mottagare"
+
+#: pg_basebackup.c:2101
+#, c-format
+msgid "backup failed: %s"
+msgstr "backup misslyckades: %s"
+
+#: pg_basebackup.c:2104
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "ingen write-ahead-logg-slutposition returnerad från servern"
+
+#: pg_basebackup.c:2107
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "write-ahead-logg-slutposition: %s"
+
+#: pg_basebackup.c:2118
+#, c-format
+msgid "checksum error occurred"
+msgstr "felaktig kontrollsumma upptäcktes"
+
+#: pg_basebackup.c:2123
+#, c-format
+msgid "final receive failed: %s"
+msgstr "sista mottagning misslyckades: %s"
+
+#: pg_basebackup.c:2147
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "väntat på att bakgrundsprocess skall avsluta strömmande ..."
+
+#: pg_basebackup.c:2151
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "kunde inte skicka kommando till bakgrundsrör (pipe): %m"
+
+#: pg_basebackup.c:2156
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "kunde inte vänta på barnprocess: %m"
+
+#: pg_basebackup.c:2158
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "barn %d dog, förväntade %d"
+
+#: pg_basebackup.c:2160 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2180
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "kunde inte vänta på barntråd: %m"
+
+#: pg_basebackup.c:2185
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "kunde inte hämta barntrådens slutstatus: %m"
+
+#: pg_basebackup.c:2188
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "barntråd avslutade med fel %u"
+
+#: pg_basebackup.c:2217
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "synkar data till disk ..."
+
+#: pg_basebackup.c:2242
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "byter namn på backup_manifest.tmp till backup_manifest"
+
+#: pg_basebackup.c:2262
+#, c-format
+msgid "base backup completed"
+msgstr "basbackup klar"
+
+#: pg_basebackup.c:2351
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "ogiltigt utdataformat \"%s\", måste vara \"plain\" eller \"tar\""
+
+#: pg_basebackup.c:2395
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "ogiltig wal-metod-flagga \"%s\", måste vara \"fetch\", \"stream\" eller \"none\""
+
+#: pg_basebackup.c:2425
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "ogiltigt checkpoint-argument \"%s\", måste vara \"fast\" eller \"spread\""
+
+#: pg_basebackup.c:2476 pg_basebackup.c:2488 pg_basebackup.c:2510
+#: pg_basebackup.c:2522 pg_basebackup.c:2528 pg_basebackup.c:2580
+#: pg_basebackup.c:2591 pg_basebackup.c:2601 pg_basebackup.c:2607
+#: pg_basebackup.c:2614 pg_basebackup.c:2626 pg_basebackup.c:2638
+#: pg_basebackup.c:2646 pg_basebackup.c:2659 pg_basebackup.c:2665
+#: pg_basebackup.c:2674 pg_basebackup.c:2686 pg_basebackup.c:2697
+#: pg_basebackup.c:2705 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Försök med \"%s --help\" för mer information."
+
+#: pg_basebackup.c:2486 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "för många kommandoradsargument (första är \"%s\")"
+
+#: pg_basebackup.c:2509
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "kan inte ange både format och backupmål"
+
+#: pg_basebackup.c:2521
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "måste ange utkatalog eller backupmål"
+
+#: pg_basebackup.c:2527
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "kan inte ange både utdatakatalog och backupmål"
+
+#: pg_basebackup.c:2557 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "okänd komprimeringsalgoritm \"%s\""
+
+#: pg_basebackup.c:2563 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "ogiltig komprimeringsangivelse: %s"
+
+#: pg_basebackup.c:2579
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "komprimering på klientsidan är inte möjlig när backupmål angivits"
+
+#: pg_basebackup.c:2590
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "bara backupper i tar-läge kan komprimeras"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "WAL kan inte strömmas när ett backupmål angivits"
+
+#: pg_basebackup.c:2606
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "kan inte strömma write-ahead-logg i tar-läge till stdout"
+
+#: pg_basebackup.c:2613
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "replikerings-slot kan bara användas med WAL-strömning"
+
+#: pg_basebackup.c:2625
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot kan inte användas tillsammans med slot-namn"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2636 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "%s kräver att en slot anges med --slot"
+
+#: pg_basebackup.c:2644 pg_basebackup.c:2684 pg_basebackup.c:2695
+#: pg_basebackup.c:2703
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "%s och %s är inkompatibla flaggor"
+
+#: pg_basebackup.c:2658
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "WAL-katalogplats kan inte anges tillsammans med backupmål"
+
+#: pg_basebackup.c:2664
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "WAL-katalogplats kan bara anges i läget \"plain\""
+
+#: pg_basebackup.c:2673
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "WAL-katalogen måste vara en absolut sökväg"
+
+#: pg_basebackup.c:2774
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "kan inte skapa symbolisk länk \"%s\": %m"
+
+#: pg_basebackup.c:2776
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "symboliska länkar stöds inte på denna plattform"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid ""
+"%s receives PostgreSQL streaming write-ahead logs.\n"
+"\n"
+msgstr ""
+"%s tar emot PostgreSQL-strömning-write-ahead-logg.\n"
+"\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Flaggor:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=KAT ta emot write-ahead-logg-filer till denna katalog\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN avsluta efter att ha taget emot den angivna LSN\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr " --if-not-exists inget fel om slot:en redan finns när vi skapar slot:en\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop loopa inte om anslutning tappas\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " --no-sync vänta inte på att ändringar skall skrivas säkert till disk\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid ""
+" -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr ""
+" -s, --status-interval=SEKS\n"
+" tid mellan att statuspaket skickas till serverb (standard: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous flush:a write-ahead-logg direkt efter skrivning\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid ""
+" -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr ""
+" -Z, --compress=[{client|server}-]METOD[:DETALJ]\n"
+" komprimera enligt detta\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid ""
+"\n"
+"Optional actions:\n"
+msgstr ""
+"\n"
+"Valfria handlingar:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr " --create-slot skapa en ny replikeringsslot (angående slot:ens namn, se --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr " --drop-slot släng replikeringsslot (angående slot:ens namn, se --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "slutförde segment vid %X/%X (tidslinje %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "stoppade logg-strömning vid %X/%X (tidslinje %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "bytte till tidslinje %u vid %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "mottog avbrottsignal, avslutar"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "kunde inte stänga katalog \"%s\": %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "segmentfil \"%s\" har inkorrekt storlek %lld, hoppar över"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "kunde inte öppna komprimerad fil \"%s\": %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "kunde inte söka i komprimerad fil \"%s\": %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "kunde inte läsa komprimerad fil \"%s\": %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "kunde inte läsa komprimerad fil \"%s\": läste %d av %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "komprimerad segmentfil \"%s\" har inkorrekt okomprimerad storlek %d, hoppar över"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "kunde inte skapa kontext för LZ4-dekomprimering: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "kunde inte läsa fil \"%s\": %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "kunde inte dekomprimera fil \"%s\": %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "kunde inte frigöra kontext för LZ4-dekomprimering: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "komprimerad segmentfil \"%s\" har inkorrekt okomprimerad storlek %zu, hoppar över"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "kan inte kontrollera filen \"%s\": komprimering med %s stöds inte av detta bygge"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "startar logg-strömning vid %X/%X (tidslinje %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "kunde inte parsa slutposition \"%s\""
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "kan inte använda --create-slot tillsammans med --drop-slot"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "kan inte använda --synchronous tillsammans med --no-sync"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "ingen målkatalog angiven"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "komprimering med %s stöds inte än"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "replikeringsanslutning som använder slot \"%s\" är oväntat databasspecifik"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "slänger replikeringsslot \"%s\""
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "skapar replikeringsslot \"%s\""
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "nerkopplad"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "nerkopplad; väntar %d sekunder för att försöka igen"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid ""
+"%s controls PostgreSQL logical decoding streams.\n"
+"\n"
+msgstr ""
+"%s styr PostgreSQL:s logiskt avkodade strömmar.\n"
+"\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid ""
+"\n"
+"Action to be performed:\n"
+msgstr ""
+"\n"
+"Handling att utföra:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr " --start starta strömning i en replikeringsslot (angående slot:ens namn, se --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=FIL ta emot logg till denna fil, - för stdout\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid ""
+" -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr ""
+" -F --fsync-interval=SEK\n"
+" tid mellan fsync av utdatafil (standard: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN var i en existerande slot skall strömningen starta\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid ""
+" -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr ""
+" -o, --option=NAMN[=VÄRDE]\n"
+" skicka vidare flaggan NAMN med ev. värde VÄRDE till\n"
+" utmatnings-plugin:en\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN använd utmatnings-plugin:en PLUGIN (standard: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOTNAMN namn på den logiska replikerings-slotten\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase slå på avkodning av förberedda transaktioner när en slot skapas\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=DBNAMN databas att ansluta till\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "bekräftar skrivning fram till %X/%X, flush till %X/%X (slot %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "kunde inte skicka feedback-paket: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "startar logg-strömning vid %X/%X (slot %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "strömning initierad"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "kunde inte öppna loggfil \"%s\": %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "ogiltigt uttag: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() misslyckades: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "kunde inte ta emot data från WAL-ström: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "strömningsheader för liten: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "okänd strömningsheader: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "kunde inte skriva %d byte till loggfil \"%s\": %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "oväntad terminering av replikeringsström: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "kunde inte parsa startposition \"%s\""
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "ingen slot angiven"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "ingen målfil angiven"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "ingen databas angiven"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "minst en handling måste anges"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "kan inte använda --create-slot eller --start tillsammans med --drop-slot"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "kan inte använda --create-slot eller --drop-slot tillsammans med --startpos"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos får bara anges tillsammans med --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase får bara anges tillsammans med --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "kunde inte upprätta databasspecifik replikeringsanslutning"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "slutposition %X/%X nådd av keepalive"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "slutposition %X/%X nådd av WAL-post vid %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "kunde inte skapa arkiveringsstatusfil \"%s\": %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "kunde inte stänga arkiveringsstatusfil \"%s\": %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "kunde inte hämta storleken på write-ahead-logg-fil \"%s\": %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "kunde inte öppna existerande write-ahead-logg-fil \"%s\": %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "kunde inte fsync:a befintlig write-ahead-logg-fil \"%s\": %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "write-ahead-logg-fil \"%s\" har %zd byte, skall vara 0 eller %d"
+msgstr[1] "write-ahead-logg-fil \"%s\" har %zd byte, skall vara 0 eller %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "kunde inte öppna write-ahead-logg-fil \"%s\": %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "kunde inte fastställa sökposition i fil \"%s\": %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "byter inte namn på \"%s\", segmentet är inte komplett"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "kunde inte stänga fil \"%s\": %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "servern rapporterade oväntat historikfilnamn för tidslinje %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "kunde inte skapa tidslinjehistorikfil \"%s\": %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "kunde inte skriva tidslinjehistorikfil \"%s\": %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "inkompatibel serverversion %s; klienten stöder inte stömning från serverversioner äldre än %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "inkompatibel serverversion %s; klienten stöder inte stömning från serverversioner nyare än %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "systemidentifieraren matchar inte mellan basbackup och strömningsanslutning"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "starttidslinje %u finns inte tillgänglig i servern"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "oväntat svar på TIMELINE_HISTORY-kommando: fick %d rader och %d fält, förväntade %d rader och %d fält"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "servern rapporterade oväntad nästa tidslinje %u, följer på tidslinje %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "servern stoppade strömning av tidslinje %u vid %X/%X men rapporterade nästa tidslinje %u skulle börja vid %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "replikeringsström avslutades innan stoppunkt"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "oväntad resultatmängd efter slut-på-tidslinje: fick %d rader och %d fält, förväntade %d rader och %d fält"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "kunde inte parsa nästa tidslinjens startpunkt \"%s\""
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "kunde inte fsync:a fil \"%s\": %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "tog emot write-ahead-logg-post för offset %u utan att ha någon öppen fil"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "fick WAL-data-offset %08x, förväntade %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "kunde inte skriva %d byte till WAL-fil \"%s\": %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "kunde inte skicka \"copy-end\"-paket: %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Lösenord: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "kunde inte ansluta till server"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "kunde inte nollställa search_path: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "kunde inte lista ut serverns inställning för integer_datetimes"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "kompileringsflaggan integer_datetimes matchar inte servern"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "kunde inte hämta WAL-segmentstorlek: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "WAL-segment-storlek kunde inte parsas"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "WAL-segmentstorlek måste vara en tvåpotens mellan 1MB och 1GB men fjärrservern rapporterade värdet %d byte"
+msgstr[1] "WAL-segmentstorlek måste vara en tvåpotens mellan 1MB och 1GB men fjärrservern rapporterade värdet %d byte"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "kunde inte hämta gruppaccessflagga: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "gruppaccessflagga kunde inte parsas: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "kunde inte identifiera system: fick %d rader och %d fält, förväntade %d rader och %d eller fler fält"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "kunde inte läsa replikeringsslot \"%s\": fick %d rader och %d fält, förväntade %d rader och %d fält"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "replikeringsslot \"%s\" existerar inte"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "förväntade en fysisk replikeringsslot men fick av typen \"%s\" istället"
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "kunde inte parsa restart_lsn \"%s\" för replikeringsslot \"%s\""
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "kunde inte skapa replikeringsslot \"%s\": fick %d rader och %d fält, förväntade %d rader och %d fält"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "kunde inte slänga replikeringsslot \"%s\": fick %d rader och %d fält, förväntade %d rader och %d fält"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "kunde inte komprimera data"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "kunde inte nollställa komprimeringsström"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "implementationsfel: tar-filer kan inte ha mer än en öppen fil"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "kunde inte skapa tar-header"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "kunde inte ändra komprimeringsparametrar"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "unlink stöds inte med komprimering"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "kunde inte stänga komprimeringsström"
diff --git a/src/bin/pg_basebackup/po/uk.po b/src/bin/pg_basebackup/po/uk.po
new file mode 100644
index 0000000..d840949
--- /dev/null
+++ b/src/bin/pg_basebackup/po/uk.po
@@ -0,0 +1,1759 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: postgresql\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2023-01-31 23:18+0000\n"
+"PO-Revision-Date: 2023-04-19 15:06\n"
+"Last-Translator: \n"
+"Language-Team: Ukrainian\n"
+"Language: uk_UA\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
+"X-Crowdin-Project: postgresql\n"
+"X-Crowdin-Project-ID: 324573\n"
+"X-Crowdin-Language: uk\n"
+"X-Crowdin-File: /REL_15_STABLE/pg_basebackup.pot\n"
+"X-Crowdin-File-ID: 910\n"
+
+#: ../../../src/common/logging.c:276
+#, c-format
+msgid "error: "
+msgstr "помилка: "
+
+#: ../../../src/common/logging.c:283
+#, c-format
+msgid "warning: "
+msgstr "попередження: "
+
+#: ../../../src/common/logging.c:294
+#, c-format
+msgid "detail: "
+msgstr "деталі: "
+
+#: ../../../src/common/logging.c:301
+#, c-format
+msgid "hint: "
+msgstr "підказка: "
+
+#: ../../common/compression.c:130 ../../common/compression.c:139
+#: ../../common/compression.c:148
+#, c-format
+msgid "this build does not support compression with %s"
+msgstr "ця збірка не підтримує стиснення з %s"
+
+#: ../../common/compression.c:203
+msgid "found empty string where a compression option was expected"
+msgstr "знайдено порожній рядок, де очікувався параметр стискання"
+
+#: ../../common/compression.c:237
+#, c-format
+msgid "unrecognized compression option: \"%s\""
+msgstr "нерозпізнаний алгоритм стискання: \"%s\""
+
+#: ../../common/compression.c:276
+#, c-format
+msgid "compression option \"%s\" requires a value"
+msgstr "параметр стискання \"%s\" потребує значення"
+
+#: ../../common/compression.c:285
+#, c-format
+msgid "value for compression option \"%s\" must be an integer"
+msgstr "значення параметру стискання \"%s\" має бути цілим числом"
+
+#: ../../common/compression.c:335
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a compression level"
+msgstr "алгоритм стискання \"%s\" не приймає рівень стискання"
+
+#: ../../common/compression.c:342
+#, c-format
+msgid "compression algorithm \"%s\" expects a compression level between %d and %d (default at %d)"
+msgstr "алгоритм стискання \"%s\" очікує рівень стискання між %d і %d (за замовчуванням %d)"
+
+#: ../../common/compression.c:353
+#, c-format
+msgid "compression algorithm \"%s\" does not accept a worker count"
+msgstr "алгоритм стиснення \"%s\" не приймає кількість працівників"
+
+#: ../../common/fe_memutils.c:35 ../../common/fe_memutils.c:75
+#: ../../common/fe_memutils.c:98 ../../common/fe_memutils.c:162
+#, c-format
+msgid "out of memory\n"
+msgstr "недостатньо пам'яті\n"
+
+#: ../../common/fe_memutils.c:92 ../../common/fe_memutils.c:154
+#, c-format
+msgid "cannot duplicate null pointer (internal error)\n"
+msgstr "неможливо дублювати нульовий покажчик (внутрішня помилка)\n"
+
+#: ../../common/file_utils.c:87 ../../common/file_utils.c:451
+#: pg_receivewal.c:380 pg_recvlogical.c:341
+#, c-format
+msgid "could not stat file \"%s\": %m"
+msgstr "не вдалося отримати інформацію від файлу \"%s\": %m"
+
+#: ../../common/file_utils.c:166 pg_receivewal.c:303
+#, c-format
+msgid "could not open directory \"%s\": %m"
+msgstr "не вдалося відкрити каталог \"%s\": %m"
+
+#: ../../common/file_utils.c:200 pg_receivewal.c:532
+#, c-format
+msgid "could not read directory \"%s\": %m"
+msgstr "не вдалося прочитати каталог \"%s\": %m"
+
+#: ../../common/file_utils.c:232 ../../common/file_utils.c:291
+#: ../../common/file_utils.c:365 ../../fe_utils/recovery_gen.c:121
+#: pg_receivewal.c:447
+#, c-format
+msgid "could not open file \"%s\": %m"
+msgstr "не можливо відкрити файл \"%s\": %m"
+
+#: ../../common/file_utils.c:303 ../../common/file_utils.c:373
+#: pg_recvlogical.c:196
+#, c-format
+msgid "could not fsync file \"%s\": %m"
+msgstr "не вдалося fsync файл \"%s\": %m"
+
+#: ../../common/file_utils.c:383 pg_basebackup.c:2266 walmethods.c:459
+#, c-format
+msgid "could not rename file \"%s\" to \"%s\": %m"
+msgstr "не вдалося перейменувати файл \"%s\" на \"%s\": %m"
+
+#: ../../fe_utils/option_utils.c:69
+#, c-format
+msgid "invalid value \"%s\" for option %s"
+msgstr "неприпустиме значення \"%s\" для параметра %s"
+
+#: ../../fe_utils/option_utils.c:76
+#, c-format
+msgid "%s must be in range %d..%d"
+msgstr "%s має бути в діапазоні %d..%d"
+
+#: ../../fe_utils/recovery_gen.c:34 ../../fe_utils/recovery_gen.c:45
+#: ../../fe_utils/recovery_gen.c:70 ../../fe_utils/recovery_gen.c:90
+#: ../../fe_utils/recovery_gen.c:149 pg_basebackup.c:1646
+#, c-format
+msgid "out of memory"
+msgstr "недостатньо пам'яті"
+
+#: ../../fe_utils/recovery_gen.c:124 bbstreamer_file.c:121
+#: bbstreamer_file.c:258 pg_basebackup.c:1443 pg_basebackup.c:1737
+#, c-format
+msgid "could not write to file \"%s\": %m"
+msgstr "неможливо записати до файлу \"%s\": %m"
+
+#: ../../fe_utils/recovery_gen.c:133 bbstreamer_file.c:93 bbstreamer_file.c:339
+#: pg_basebackup.c:1507 pg_basebackup.c:1716
+#, c-format
+msgid "could not create file \"%s\": %m"
+msgstr "неможливо створити файл \"%s\": %m"
+
+#: bbstreamer_file.c:138 pg_recvlogical.c:635
+#, c-format
+msgid "could not close file \"%s\": %m"
+msgstr "неможливо закрити файл \"%s\": %m"
+
+#: bbstreamer_file.c:275
+#, c-format
+msgid "unexpected state while extracting archive"
+msgstr "неочікуваний стан під час розпакування архіву"
+
+#: bbstreamer_file.c:298 pg_basebackup.c:696 pg_basebackup.c:740
+#, c-format
+msgid "could not create directory \"%s\": %m"
+msgstr "не вдалося створити каталог \"%s\": %m"
+
+#: bbstreamer_file.c:304
+#, c-format
+msgid "could not set permissions on directory \"%s\": %m"
+msgstr "не вдалося встановити права для каталогу \"%s\": %m"
+
+#: bbstreamer_file.c:323
+#, c-format
+msgid "could not create symbolic link from \"%s\" to \"%s\": %m"
+msgstr "не вдалося створити символічне послання з \"%s\" на \"%s\": %m"
+
+#: bbstreamer_file.c:343
+#, c-format
+msgid "could not set permissions on file \"%s\": %m"
+msgstr "не вдалося встановити права на файл \"%s\": %m"
+
+#: bbstreamer_gzip.c:95
+#, c-format
+msgid "could not create compressed file \"%s\": %m"
+msgstr "не вдалося створити стиснутий файл \"%s\": %m"
+
+#: bbstreamer_gzip.c:103
+#, c-format
+msgid "could not duplicate stdout: %m"
+msgstr "не вдалося дублювати stdout: %m"
+
+#: bbstreamer_gzip.c:107
+#, c-format
+msgid "could not open output file: %m"
+msgstr "не вдалося відкрити вихідний файл: %m"
+
+#: bbstreamer_gzip.c:111
+#, c-format
+msgid "could not set compression level %d: %s"
+msgstr "не вдалося встановити рівень стискання %d: %s"
+
+#: bbstreamer_gzip.c:116 bbstreamer_gzip.c:249
+#, c-format
+msgid "this build does not support gzip compression"
+msgstr "ця збірка не підтримує стиснення gzip"
+
+#: bbstreamer_gzip.c:143
+#, c-format
+msgid "could not write to compressed file \"%s\": %s"
+msgstr "не вдалося записати до стиснутого файлу \"%s\": %s"
+
+#: bbstreamer_gzip.c:167
+#, c-format
+msgid "could not close compressed file \"%s\": %m"
+msgstr "не вдалося закрити стиснутий файл \"%s\": %m"
+
+#: bbstreamer_gzip.c:245 walmethods.c:869
+#, c-format
+msgid "could not initialize compression library"
+msgstr "не вдалося ініціалізувати бібліотеку стискання"
+
+#: bbstreamer_gzip.c:296 bbstreamer_lz4.c:354 bbstreamer_zstd.c:316
+#, c-format
+msgid "could not decompress data: %s"
+msgstr "не вдалося розпакувати дані: %s"
+
+#: bbstreamer_inject.c:189
+#, c-format
+msgid "unexpected state while injecting recovery settings"
+msgstr "неочікуваний стан під час введення налаштувань відновлення"
+
+#: bbstreamer_lz4.c:95
+#, c-format
+msgid "could not create lz4 compression context: %s"
+msgstr "не вдалося створити контекст стиснення lz4: %s"
+
+#: bbstreamer_lz4.c:100 bbstreamer_lz4.c:298
+#, c-format
+msgid "this build does not support lz4 compression"
+msgstr "ця збірка не підтримує стиснення lz4"
+
+#: bbstreamer_lz4.c:140
+#, c-format
+msgid "could not write lz4 header: %s"
+msgstr "не вдалося записати заголовок lz4: %s"
+
+#: bbstreamer_lz4.c:189 bbstreamer_zstd.c:168 bbstreamer_zstd.c:210
+#, c-format
+msgid "could not compress data: %s"
+msgstr "не вдалося стиснути дані: %s"
+
+#: bbstreamer_lz4.c:241
+#, c-format
+msgid "could not end lz4 compression: %s"
+msgstr "не вдалося закінчити стискання lz4: %s"
+
+#: bbstreamer_lz4.c:293
+#, c-format
+msgid "could not initialize compression library: %s"
+msgstr "не вдалося ініціалізувати бібліотеку стиснення: %s"
+
+#: bbstreamer_tar.c:244
+#, c-format
+msgid "tar file trailer exceeds 2 blocks"
+msgstr "причіп файлу tar перевищує 2 блоки"
+
+#: bbstreamer_tar.c:249
+#, c-format
+msgid "unexpected state while parsing tar archive"
+msgstr "неочікуваний стан під час розбору архіву tar"
+
+#: bbstreamer_tar.c:296
+#, c-format
+msgid "tar member has empty name"
+msgstr "частина tar містить порожню назву"
+
+#: bbstreamer_tar.c:328
+#, c-format
+msgid "COPY stream ended before last file was finished"
+msgstr "потік COPY завершився до завершення останнього файлу"
+
+#: bbstreamer_zstd.c:85
+#, c-format
+msgid "could not create zstd compression context"
+msgstr "не вдалося створити контекст стиснення zstd"
+
+#: bbstreamer_zstd.c:91
+#, c-format
+msgid "could not set zstd compression level to %d: %s"
+msgstr "не вдалося встановити рівень стискання zstd на %d: %s"
+
+#: bbstreamer_zstd.c:105
+#, c-format
+msgid "could not set compression worker count to %d: %s"
+msgstr "не вдалося встановити кількість процесів стискання на %d: %s"
+
+#: bbstreamer_zstd.c:116 bbstreamer_zstd.c:271
+#, c-format
+msgid "this build does not support zstd compression"
+msgstr "ця збірка не підтримує стиснення zstd"
+
+#: bbstreamer_zstd.c:262
+#, c-format
+msgid "could not create zstd decompression context"
+msgstr "не вдалося створити контекст zstd декомпресії"
+
+#: pg_basebackup.c:240
+#, c-format
+msgid "removing data directory \"%s\""
+msgstr "видалення даних з директорії \"%s\""
+
+#: pg_basebackup.c:242
+#, c-format
+msgid "failed to remove data directory"
+msgstr "не вдалося видалити дані директорії"
+
+#: pg_basebackup.c:246
+#, c-format
+msgid "removing contents of data directory \"%s\""
+msgstr "видалення даних з директорії \"%s\""
+
+#: pg_basebackup.c:248
+#, c-format
+msgid "failed to remove contents of data directory"
+msgstr "не вдалося видалити дані директорії"
+
+#: pg_basebackup.c:253
+#, c-format
+msgid "removing WAL directory \"%s\""
+msgstr "видалення WAL директорії \"%s\""
+
+#: pg_basebackup.c:255
+#, c-format
+msgid "failed to remove WAL directory"
+msgstr "не вдалося видалити директорію WAL"
+
+#: pg_basebackup.c:259
+#, c-format
+msgid "removing contents of WAL directory \"%s\""
+msgstr "видалення даних з директорії WAL \"%s\""
+
+#: pg_basebackup.c:261
+#, c-format
+msgid "failed to remove contents of WAL directory"
+msgstr "не вдалося видалити дані директорії WAL"
+
+#: pg_basebackup.c:267
+#, c-format
+msgid "data directory \"%s\" not removed at user's request"
+msgstr "директорія даних \"%s\" не видалена за запитом користувача"
+
+#: pg_basebackup.c:270
+#, c-format
+msgid "WAL directory \"%s\" not removed at user's request"
+msgstr "директорія WAL \"%s\" не видалена за запитом користувача"
+
+#: pg_basebackup.c:274
+#, c-format
+msgid "changes to tablespace directories will not be undone"
+msgstr "зміни в каталогах табличних просторів незворотні"
+
+#: pg_basebackup.c:326
+#, c-format
+msgid "directory name too long"
+msgstr "ім'я директорії задовге"
+
+#: pg_basebackup.c:333
+#, c-format
+msgid "multiple \"=\" signs in tablespace mapping"
+msgstr "кілька знаків \"=\" зіставленні табличних просторів"
+
+#: pg_basebackup.c:342
+#, c-format
+msgid "invalid tablespace mapping format \"%s\", must be \"OLDDIR=NEWDIR\""
+msgstr "неприпустимий табличний простір зіставлення формату \"%s\", має бути \"OLDDIR = NEWDIR\""
+
+#: pg_basebackup.c:361
+#, c-format
+msgid "old directory is not an absolute path in tablespace mapping: %s"
+msgstr "старий каталог не є абсолютним шляхом у зіставлення табличного простору: %s"
+
+#: pg_basebackup.c:365
+#, c-format
+msgid "new directory is not an absolute path in tablespace mapping: %s"
+msgstr "новий каталог не є абсолютним шляхом у зіставлення табличного простору: %s"
+
+#: pg_basebackup.c:387
+#, c-format
+msgid "%s takes a base backup of a running PostgreSQL server.\n\n"
+msgstr "%s робить базову резервну копію працюючого сервера PostgreSQL.\n\n"
+
+#: pg_basebackup.c:389 pg_receivewal.c:81 pg_recvlogical.c:78
+#, c-format
+msgid "Usage:\n"
+msgstr "Використання:\n"
+
+#: pg_basebackup.c:390 pg_receivewal.c:82 pg_recvlogical.c:79
+#, c-format
+msgid " %s [OPTION]...\n"
+msgstr " %s: [OPTION]...\n"
+
+#: pg_basebackup.c:391
+#, c-format
+msgid "\n"
+"Options controlling the output:\n"
+msgstr "\n"
+"Параметри, що контролюють вивід:\n"
+
+#: pg_basebackup.c:392
+#, c-format
+msgid " -D, --pgdata=DIRECTORY receive base backup into directory\n"
+msgstr " -D, -- pgdata=DIRECTORY директорія, в яку зберегти резервну копію бази\n"
+
+#: pg_basebackup.c:393
+#, c-format
+msgid " -F, --format=p|t output format (plain (default), tar)\n"
+msgstr " -F, --format=p|т формат виводу (звичайний за замовчуванням, tar)\n"
+
+#: pg_basebackup.c:394
+#, c-format
+msgid " -r, --max-rate=RATE maximum transfer rate to transfer data directory\n"
+" (in kB/s, or use suffix \"k\" or \"M\")\n"
+msgstr " -r, --max-rate=RATE максимальна швидкість передавання даних до директорії\n"
+" (у кБ/с або з використанням суфіксів \"k\" або \"М\")\n"
+
+#: pg_basebackup.c:396
+#, c-format
+msgid " -R, --write-recovery-conf\n"
+" write configuration for replication\n"
+msgstr " -R, --write-recovery-conf\n"
+" записати конфігурацію для реплікації\n"
+
+#: pg_basebackup.c:398
+#, c-format
+msgid " -t, --target=TARGET[:DETAIL]\n"
+" backup target (if other than client)\n"
+msgstr " -t, --target=TARGET[:DETAIL]\n"
+" ціль резервного копіювання (якщо не клієнт)\n"
+
+#: pg_basebackup.c:400
+#, c-format
+msgid " -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" relocate tablespace in OLDDIR to NEWDIR\n"
+msgstr " -T, --tablespace-mapping=OLDDIR=NEWDIR\n"
+" перенестb табличний простір з OLDDIR до NEWDIR\n"
+
+#: pg_basebackup.c:402
+#, c-format
+msgid " --waldir=WALDIR location for the write-ahead log directory\n"
+msgstr "--waldir=WALDIR розташування журналу попереднього запису\n"
+
+#: pg_basebackup.c:403
+#, c-format
+msgid " -X, --wal-method=none|fetch|stream\n"
+" include required WAL files with specified method\n"
+msgstr " -X, --wal-method=none|fetch|stream\n"
+" додати необхідні WAL файли за допомогою вказаного методу\n"
+
+#: pg_basebackup.c:405
+#, c-format
+msgid " -z, --gzip compress tar output\n"
+msgstr " -z, --gzip стиснути вихідний tar\n"
+
+#: pg_basebackup.c:406
+#, c-format
+msgid " -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" compress on client or server as specified\n"
+msgstr " -Z, --compress=[{client|server}-]METHOD[:DETAIL]\n"
+" стискати на клієнті або сервері, як зазначено\n"
+
+#: pg_basebackup.c:408
+#, c-format
+msgid " -Z, --compress=none do not compress tar output\n"
+msgstr " -Z, --compress=none не стискати вивід tar\n"
+
+#: pg_basebackup.c:409
+#, c-format
+msgid "\n"
+"General options:\n"
+msgstr "\n"
+"Основні налаштування:\n"
+
+#: pg_basebackup.c:410
+#, c-format
+msgid " -c, --checkpoint=fast|spread\n"
+" set fast or spread checkpointing\n"
+msgstr " -c, --checkpoint=fast|spread\n"
+" режим швидких або розділених контрольних точок\n"
+
+#: pg_basebackup.c:412
+#, c-format
+msgid " -C, --create-slot create replication slot\n"
+msgstr " -C, --create-slot створити слот для реплікації\n"
+
+#: pg_basebackup.c:413
+#, c-format
+msgid " -l, --label=LABEL set backup label\n"
+msgstr " -l, --label=LABEL встановити мітку резервної копії\n"
+
+#: pg_basebackup.c:414
+#, c-format
+msgid " -n, --no-clean do not clean up after errors\n"
+msgstr " -n, --no-clean не очищати після помилок\n"
+
+#: pg_basebackup.c:415
+#, c-format
+msgid " -N, --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " -N, --no-sync не чекати завершення збереження даних на диску\n"
+
+#: pg_basebackup.c:416
+#, c-format
+msgid " -P, --progress show progress information\n"
+msgstr " -P, --progress відображати інформацію про прогрес\n"
+
+#: pg_basebackup.c:417 pg_receivewal.c:91
+#, c-format
+msgid " -S, --slot=SLOTNAME replication slot to use\n"
+msgstr " -S, --slot=ИМ'Я_СЛОТА використовувати вказаний слот реплікації\n"
+
+#: pg_basebackup.c:418 pg_receivewal.c:93 pg_recvlogical.c:100
+#, c-format
+msgid " -v, --verbose output verbose messages\n"
+msgstr " -v, --verbose виводити детальні повідомлення\n"
+
+#: pg_basebackup.c:419 pg_receivewal.c:94 pg_recvlogical.c:101
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version вивести інформацію про версію і вийти\n"
+
+#: pg_basebackup.c:420
+#, c-format
+msgid " --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE\n"
+" use algorithm for manifest checksums\n"
+msgstr " --manifest-checksums=SHA{224,256,384,512}|CRC32C|НЕ\n"
+" використовувати алгоритм для контрольних сум маніфесту\n"
+
+#: pg_basebackup.c:422
+#, c-format
+msgid " --manifest-force-encode\n"
+" hex encode all file names in manifest\n"
+msgstr " --manifest-force-encode\n"
+" кодувати у hex всі імена файлів у маніфесті\n"
+
+#: pg_basebackup.c:424
+#, c-format
+msgid " --no-estimate-size do not estimate backup size in server side\n"
+msgstr " --no-estimate-size не оцінювати розмір резервної копії на стороні сервера\n"
+
+#: pg_basebackup.c:425
+#, c-format
+msgid " --no-manifest suppress generation of backup manifest\n"
+msgstr " --no-manifest пропустити створення маніфесту резервного копіювання\n"
+
+#: pg_basebackup.c:426
+#, c-format
+msgid " --no-slot prevent creation of temporary replication slot\n"
+msgstr " --no-slot не створювати тимчасового слоту реплікації\n"
+
+#: pg_basebackup.c:427
+#, c-format
+msgid " --no-verify-checksums\n"
+" do not verify checksums\n"
+msgstr " --no-verify-checksums\n"
+" не перевіряти контрольні суми\n"
+
+#: pg_basebackup.c:429 pg_receivewal.c:97 pg_recvlogical.c:102
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help показати цю довідку потім вийти\n"
+
+#: pg_basebackup.c:430 pg_receivewal.c:98 pg_recvlogical.c:103
+#, c-format
+msgid "\n"
+"Connection options:\n"
+msgstr "\n"
+"Налаштування з'єднання:\n"
+
+#: pg_basebackup.c:431 pg_receivewal.c:99
+#, c-format
+msgid " -d, --dbname=CONNSTR connection string\n"
+msgstr " -d, --dbname=CONNSTR рядок з'єднання\n"
+
+#: pg_basebackup.c:432 pg_receivewal.c:100 pg_recvlogical.c:105
+#, c-format
+msgid " -h, --host=HOSTNAME database server host or socket directory\n"
+msgstr " -h, --host=HOSTNAME хост сервера бази даних або каталог сокетів\n"
+
+#: pg_basebackup.c:433 pg_receivewal.c:101 pg_recvlogical.c:106
+#, c-format
+msgid " -p, --port=PORT database server port number\n"
+msgstr " -p, --port=PORT порт сервера бази даних\n"
+
+#: pg_basebackup.c:434
+#, c-format
+msgid " -s, --status-interval=INTERVAL\n"
+" time between status packets sent to server (in seconds)\n"
+msgstr " -s, --status-interval=INTERVAL часу між пакетами статусу до сервера (у секундах)\n"
+
+#: pg_basebackup.c:436 pg_receivewal.c:102 pg_recvlogical.c:107
+#, c-format
+msgid " -U, --username=NAME connect as specified database user\n"
+msgstr " -U, --username=NAME підключатись як вказаний користувач бази даних\n"
+
+#: pg_basebackup.c:437 pg_receivewal.c:103 pg_recvlogical.c:108
+#, c-format
+msgid " -w, --no-password never prompt for password\n"
+msgstr " -w, --no-password ніколи не питати пароль\n"
+
+#: pg_basebackup.c:438 pg_receivewal.c:104 pg_recvlogical.c:109
+#, c-format
+msgid " -W, --password force password prompt (should happen automatically)\n"
+msgstr " -W, --password обов'язково питати пароль (повинно відбуватися автоматично)\n"
+
+#: pg_basebackup.c:439 pg_receivewal.c:108 pg_recvlogical.c:110
+#, c-format
+msgid "\n"
+"Report bugs to <%s>.\n"
+msgstr "\n"
+"Повідомляти про помилки на <%s>.\n"
+
+#: pg_basebackup.c:440 pg_receivewal.c:109 pg_recvlogical.c:111
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Домашня сторінка %s: <%s>\n"
+
+#: pg_basebackup.c:482
+#, c-format
+msgid "could not read from ready pipe: %m"
+msgstr "не можливо прочитати з готових каналів: %m"
+
+#: pg_basebackup.c:485 pg_basebackup.c:632 pg_basebackup.c:2180
+#: streamutil.c:444
+#, c-format
+msgid "could not parse write-ahead log location \"%s\""
+msgstr "не вдалося проаналізувати наперед журнал локації \"%s\""
+
+#: pg_basebackup.c:591 pg_receivewal.c:663
+#, c-format
+msgid "could not finish writing WAL files: %m"
+msgstr "не можливо закінчити написання файлів WAL: %m"
+
+#: pg_basebackup.c:641
+#, c-format
+msgid "could not create pipe for background process: %m"
+msgstr "не можливо створити канал для фонового процесу: %m"
+
+#: pg_basebackup.c:674
+#, c-format
+msgid "created temporary replication slot \"%s\""
+msgstr "створено слот тимчасових реплікацій \"%s\""
+
+#: pg_basebackup.c:677
+#, c-format
+msgid "created replication slot \"%s\""
+msgstr "створено слот реплікацій \"%s\""
+
+#: pg_basebackup.c:711
+#, c-format
+msgid "could not create background process: %m"
+msgstr "не можливо створити фоновий процес: %m"
+
+#: pg_basebackup.c:720
+#, c-format
+msgid "could not create background thread: %m"
+msgstr "не можливо створити фоновий потік: %m"
+
+#: pg_basebackup.c:759
+#, c-format
+msgid "directory \"%s\" exists but is not empty"
+msgstr "каталог \"%s\" існує, але він не порожній"
+
+#: pg_basebackup.c:765
+#, c-format
+msgid "could not access directory \"%s\": %m"
+msgstr "немає доступу до каталогу \"%s\": %m"
+
+#: pg_basebackup.c:842
+#, c-format
+msgid "%*s/%s kB (100%%), %d/%d tablespace %*s"
+msgid_plural "%*s/%s kB (100%%), %d/%d tablespaces %*s"
+msgstr[0] "%*s/%s kB (100%%), %d/%d табличний простір %*s"
+msgstr[1] "%*s/%s kB (100%%), %d/%d табличних простори %*s"
+msgstr[2] "%*s/%s kB (100%%), %d/%d табличних просторів %*s"
+msgstr[3] "%*s/%s kB (100%%), %d/%d табличних просторів %*s"
+
+#: pg_basebackup.c:854
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace (%s%-*.*s)"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces (%s%-*.*s)"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d табличний простір (%s%-*.*s)"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d табличних простори (%s%-*.*s)"
+msgstr[2] "%*s/%s kB (%d%%), %d/%d табличних просторів (%s%-*.*s)"
+msgstr[3] "%*s/%s kB (%d%%), %d/%d табличних просторів (%s%-*.*s)"
+
+#: pg_basebackup.c:870
+#, c-format
+msgid "%*s/%s kB (%d%%), %d/%d tablespace"
+msgid_plural "%*s/%s kB (%d%%), %d/%d tablespaces"
+msgstr[0] "%*s/%s kB (%d%%), %d/%d табличний простір"
+msgstr[1] "%*s/%s kB (%d%%), %d/%d табличних простори"
+msgstr[2] "%*s/%s kB (%d%%), %d/%d табличних просторів"
+msgstr[3] "%*s/%s kB (%d%%), %d/%d табличних просторів"
+
+#: pg_basebackup.c:894
+#, c-format
+msgid "transfer rate \"%s\" is not a valid value"
+msgstr "частота передач \"%s\" не є припустимим значенням"
+
+#: pg_basebackup.c:896
+#, c-format
+msgid "invalid transfer rate \"%s\": %m"
+msgstr "неприпустима частота передач \"%s\": %m"
+
+#: pg_basebackup.c:903
+#, c-format
+msgid "transfer rate must be greater than zero"
+msgstr "частота передач повинна бути більша за нуль"
+
+#: pg_basebackup.c:933
+#, c-format
+msgid "invalid --max-rate unit: \"%s\""
+msgstr "неприпустима одиниця виміру в --max-rate: \"%s\""
+
+#: pg_basebackup.c:937
+#, c-format
+msgid "transfer rate \"%s\" exceeds integer range"
+msgstr "швидкість передачі \"%s\" перевищує діапазон цілого числа"
+
+#: pg_basebackup.c:944
+#, c-format
+msgid "transfer rate \"%s\" is out of range"
+msgstr "швидкість передавання \"%s\" поза діапазоном"
+
+#: pg_basebackup.c:1040
+#, c-format
+msgid "could not get COPY data stream: %s"
+msgstr "не вдалося отримати потік даних COPY: %s"
+
+#: pg_basebackup.c:1057 pg_recvlogical.c:438 pg_recvlogical.c:610
+#: receivelog.c:981
+#, c-format
+msgid "could not read COPY data: %s"
+msgstr "не вдалося прочитати дані COPY: %s"
+
+#: pg_basebackup.c:1061
+#, c-format
+msgid "background process terminated unexpectedly"
+msgstr "фоновий процес несподівано перервано"
+
+#: pg_basebackup.c:1132
+#, c-format
+msgid "cannot inject manifest into a compressed tar file"
+msgstr "неможливо підставити маніфест в стиснений tar-файл"
+
+#: pg_basebackup.c:1133
+#, c-format
+msgid "Use client-side compression, send the output to a directory rather than standard output, or use %s."
+msgstr "Використайте стиснення на клієнті та відправлення даних в каталог замість стандартного виводу, або використайте %s."
+
+#: pg_basebackup.c:1149
+#, c-format
+msgid "cannot parse archive \"%s\""
+msgstr "неможливо розібрати архів \"%s\""
+
+#: pg_basebackup.c:1150
+#, c-format
+msgid "Only tar archives can be parsed."
+msgstr "Тільки архів tar може бути проаналізований."
+
+#: pg_basebackup.c:1152
+#, c-format
+msgid "Plain format requires pg_basebackup to parse the archive."
+msgstr "Простий формат потребує обробки архіву в pg_basebackup для обробки."
+
+#: pg_basebackup.c:1154
+#, c-format
+msgid "Using - as the output directory requires pg_basebackup to parse the archive."
+msgstr "Використання - в якості вихідного каталогу потребує pg_basebackup для аналізу архіву."
+
+#: pg_basebackup.c:1156
+#, c-format
+msgid "The -R option requires pg_basebackup to parse the archive."
+msgstr "Параметр -R потребує використання pg_basebackup для аналізу архіву."
+
+#: pg_basebackup.c:1367
+#, c-format
+msgid "archives must precede manifest"
+msgstr "архіви повинні передувати маніфесту"
+
+#: pg_basebackup.c:1382
+#, c-format
+msgid "invalid archive name: \"%s\""
+msgstr "неприпустиме ім'я архіву: \"%s\""
+
+#: pg_basebackup.c:1454
+#, c-format
+msgid "unexpected payload data"
+msgstr "неочікувані дані корисного навантаження"
+
+#: pg_basebackup.c:1597
+#, c-format
+msgid "empty COPY message"
+msgstr "порожнє повідомлення COPY"
+
+#: pg_basebackup.c:1599
+#, c-format
+msgid "malformed COPY message of type %d, length %zu"
+msgstr "неправильне повідомлення COPY з типом %d, довжина %zu"
+
+#: pg_basebackup.c:1797
+#, c-format
+msgid "incompatible server version %s"
+msgstr "несумісна версія серверу %s"
+
+#: pg_basebackup.c:1813
+#, c-format
+msgid "Use -X none or -X fetch to disable log streaming."
+msgstr "Використайте -X none або -X fetch, щоб вимкнути потокову передачу журналу."
+
+#: pg_basebackup.c:1881
+#, c-format
+msgid "backup targets are not supported by this server version"
+msgstr "цілі резервного копіювання не підтримуються цією версією сервера"
+
+#: pg_basebackup.c:1884
+#, c-format
+msgid "recovery configuration cannot be written when a backup target is used"
+msgstr "конфігурація відновлення не може бути записана під час використання цілі резервного копіювання"
+
+#: pg_basebackup.c:1911
+#, c-format
+msgid "server does not support server-side compression"
+msgstr "сервер не підтримує стиснення на сервері"
+
+#: pg_basebackup.c:1921
+#, c-format
+msgid "initiating base backup, waiting for checkpoint to complete"
+msgstr "початок базового резервного копіювання, очікується завершення контрольної точки"
+
+#: pg_basebackup.c:1925
+#, c-format
+msgid "waiting for checkpoint"
+msgstr "очікування контрольної точки"
+
+#: pg_basebackup.c:1938 pg_recvlogical.c:262 receivelog.c:549 receivelog.c:588
+#: streamutil.c:291 streamutil.c:364 streamutil.c:416 streamutil.c:504
+#: streamutil.c:656 streamutil.c:701
+#, c-format
+msgid "could not send replication command \"%s\": %s"
+msgstr "не вдалося відправити реплікаційну команду \"%s\": %s"
+
+#: pg_basebackup.c:1946
+#, c-format
+msgid "could not initiate base backup: %s"
+msgstr "не вдалося почати базове резервне копіювання: %s"
+
+#: pg_basebackup.c:1949
+#, c-format
+msgid "server returned unexpected response to BASE_BACKUP command; got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "сервер повернув неочікувану відповідь на команду BASE_BACKUP; отримано %d рядків і %d полів, очікувалось %d рядків і %d полів"
+
+#: pg_basebackup.c:1955
+#, c-format
+msgid "checkpoint completed"
+msgstr "контрольна точка завершена"
+
+#: pg_basebackup.c:1970
+#, c-format
+msgid "write-ahead log start point: %s on timeline %u"
+msgstr "стартова точка у випереджувальному журналюванні: %s на часовій шкалі %u"
+
+#: pg_basebackup.c:1978
+#, c-format
+msgid "could not get backup header: %s"
+msgstr "не вдалося отримати заголовок резервної копії: %s"
+
+#: pg_basebackup.c:1981
+#, c-format
+msgid "no data returned from server"
+msgstr "сервер не повернув дані"
+
+#: pg_basebackup.c:2016
+#, c-format
+msgid "can only write single tablespace to stdout, database has %d"
+msgstr "можна записати лише один табличний простір в stdout, всього їх в базі даних %d"
+
+#: pg_basebackup.c:2029
+#, c-format
+msgid "starting background WAL receiver"
+msgstr "запуск фонового процесу зчитування WAL"
+
+#: pg_basebackup.c:2111
+#, c-format
+msgid "backup failed: %s"
+msgstr "помилка резервного копіювання: %s"
+
+#: pg_basebackup.c:2114
+#, c-format
+msgid "no write-ahead log end position returned from server"
+msgstr "сервер не повернув кінцеву позицію у випереджувальному журналюванні"
+
+#: pg_basebackup.c:2117
+#, c-format
+msgid "write-ahead log end point: %s"
+msgstr "кінцева точка у випереджувальному журналюванні: %s"
+
+#: pg_basebackup.c:2128
+#, c-format
+msgid "checksum error occurred"
+msgstr "сталася помилка контрольної суми"
+
+#: pg_basebackup.c:2133
+#, c-format
+msgid "final receive failed: %s"
+msgstr "помилка в кінці передачі: %s"
+
+#: pg_basebackup.c:2157
+#, c-format
+msgid "waiting for background process to finish streaming ..."
+msgstr "очікування завершення потокового передавання фоновим процесом ..."
+
+#: pg_basebackup.c:2161
+#, c-format
+msgid "could not send command to background pipe: %m"
+msgstr "не вдалося надіслати команду до канала фонового процесу: %m"
+
+#: pg_basebackup.c:2166
+#, c-format
+msgid "could not wait for child process: %m"
+msgstr "збій при очікуванні дочірнього процесу: %m"
+
+#: pg_basebackup.c:2168
+#, c-format
+msgid "child %d died, expected %d"
+msgstr "завершився дочірній процес %d, очікувалося %d"
+
+#: pg_basebackup.c:2170 streamutil.c:91 streamutil.c:197
+#, c-format
+msgid "%s"
+msgstr "%s"
+
+#: pg_basebackup.c:2190
+#, c-format
+msgid "could not wait for child thread: %m"
+msgstr "неможливо дочекатися дочірнього потоку: %m"
+
+#: pg_basebackup.c:2195
+#, c-format
+msgid "could not get child thread exit status: %m"
+msgstr "не можливо отримати статус завершення дочірнього потоку: %m"
+
+#: pg_basebackup.c:2198
+#, c-format
+msgid "child thread exited with error %u"
+msgstr "дочірній потік завершився з помилкою %u"
+
+#: pg_basebackup.c:2227
+#, c-format
+msgid "syncing data to disk ..."
+msgstr "синхронізація даних з диском ..."
+
+#: pg_basebackup.c:2252
+#, c-format
+msgid "renaming backup_manifest.tmp to backup_manifest"
+msgstr "перейменування backup_manifest.tmp в backup_manifest"
+
+#: pg_basebackup.c:2272
+#, c-format
+msgid "base backup completed"
+msgstr "базове резервне копіювання завершено"
+
+#: pg_basebackup.c:2361
+#, c-format
+msgid "invalid output format \"%s\", must be \"plain\" or \"tar\""
+msgstr "неприпустимий формат виводу \"%s\", повинен бути \"plain\" або \"tar\""
+
+#: pg_basebackup.c:2405
+#, c-format
+msgid "invalid wal-method option \"%s\", must be \"fetch\", \"stream\", or \"none\""
+msgstr "неприпустимий параметр wal-method \"%s\", повинен бути \"fetch\", \"stream\" або \"none\""
+
+#: pg_basebackup.c:2435
+#, c-format
+msgid "invalid checkpoint argument \"%s\", must be \"fast\" or \"spread\""
+msgstr "неприпустимий аргумент контрольної точки \"%s\", повинен бути \"fast\" або \"spread\""
+
+#: pg_basebackup.c:2486 pg_basebackup.c:2498 pg_basebackup.c:2520
+#: pg_basebackup.c:2532 pg_basebackup.c:2538 pg_basebackup.c:2590
+#: pg_basebackup.c:2601 pg_basebackup.c:2611 pg_basebackup.c:2617
+#: pg_basebackup.c:2624 pg_basebackup.c:2636 pg_basebackup.c:2648
+#: pg_basebackup.c:2656 pg_basebackup.c:2669 pg_basebackup.c:2675
+#: pg_basebackup.c:2684 pg_basebackup.c:2696 pg_basebackup.c:2707
+#: pg_basebackup.c:2715 pg_receivewal.c:814 pg_receivewal.c:826
+#: pg_receivewal.c:833 pg_receivewal.c:842 pg_receivewal.c:849
+#: pg_receivewal.c:859 pg_recvlogical.c:837 pg_recvlogical.c:849
+#: pg_recvlogical.c:859 pg_recvlogical.c:866 pg_recvlogical.c:873
+#: pg_recvlogical.c:880 pg_recvlogical.c:887 pg_recvlogical.c:894
+#: pg_recvlogical.c:901 pg_recvlogical.c:908
+#, c-format
+msgid "Try \"%s --help\" for more information."
+msgstr "Спробуйте \"%s --help\" для додаткової інформації."
+
+#: pg_basebackup.c:2496 pg_receivewal.c:824 pg_recvlogical.c:847
+#, c-format
+msgid "too many command-line arguments (first is \"%s\")"
+msgstr "забагато аргументів у командному рядку (перший \"%s\")"
+
+#: pg_basebackup.c:2519
+#, c-format
+msgid "cannot specify both format and backup target"
+msgstr "неможливо одночасно вказати формат і ціль резервного копіювання"
+
+#: pg_basebackup.c:2531
+#, c-format
+msgid "must specify output directory or backup target"
+msgstr "потрібно вказати вихідний каталог або ціль резервного копіювання"
+
+#: pg_basebackup.c:2537
+#, c-format
+msgid "cannot specify both output directory and backup target"
+msgstr "неможливо одночасно вказати вихідну директорію і ціль резервного копіювання"
+
+#: pg_basebackup.c:2567 pg_receivewal.c:868
+#, c-format
+msgid "unrecognized compression algorithm: \"%s\""
+msgstr "нерозпізнаний алгоритм стискання: \"%s\""
+
+#: pg_basebackup.c:2573 pg_receivewal.c:875
+#, c-format
+msgid "invalid compression specification: %s"
+msgstr "неприпустима специфікація стискання: %s"
+
+#: pg_basebackup.c:2589
+#, c-format
+msgid "client-side compression is not possible when a backup target is specified"
+msgstr "стиснення на стороні клієнта неможливе, коли вказана ціль резервного копіювання"
+
+#: pg_basebackup.c:2600
+#, c-format
+msgid "only tar mode backups can be compressed"
+msgstr "лише резервні копії в архіві tar можуть стискатись"
+
+#: pg_basebackup.c:2610
+#, c-format
+msgid "WAL cannot be streamed when a backup target is specified"
+msgstr "неможливо передавати WAL, коли вказана ціль резервного копіювання"
+
+#: pg_basebackup.c:2616
+#, c-format
+msgid "cannot stream write-ahead logs in tar mode to stdout"
+msgstr "транслювати випереджувальні журналювання в режимі tar в потік stdout не можна"
+
+#: pg_basebackup.c:2623
+#, c-format
+msgid "replication slots can only be used with WAL streaming"
+msgstr "слоти реплікації можуть використовуватись тільки з потоковим передаванням WAL"
+
+#: pg_basebackup.c:2635
+#, c-format
+msgid "--no-slot cannot be used with slot name"
+msgstr "--no-slot не можна використовувати з іменем слота"
+
+#. translator: second %s is an option name
+#: pg_basebackup.c:2646 pg_receivewal.c:840
+#, c-format
+msgid "%s needs a slot to be specified using --slot"
+msgstr "для %s потрібно вказати слот за допомогою --slot"
+
+#: pg_basebackup.c:2654 pg_basebackup.c:2694 pg_basebackup.c:2705
+#: pg_basebackup.c:2713
+#, c-format
+msgid "%s and %s are incompatible options"
+msgstr "параметри %s і %s несумісні"
+
+#: pg_basebackup.c:2668
+#, c-format
+msgid "WAL directory location cannot be specified along with a backup target"
+msgstr "Не можна вказати розташування директорії WAL разом з ціллю резервного копіювання"
+
+#: pg_basebackup.c:2674
+#, c-format
+msgid "WAL directory location can only be specified in plain mode"
+msgstr "розташування каталога WAL можна вказати лише в режимі plain"
+
+#: pg_basebackup.c:2683
+#, c-format
+msgid "WAL directory location must be an absolute path"
+msgstr "розташування WAL каталогу має бути абсолютним шляхом"
+
+#: pg_basebackup.c:2784
+#, c-format
+msgid "could not create symbolic link \"%s\": %m"
+msgstr "не вдалося створити символічне послання \"%s\": %m"
+
+#: pg_basebackup.c:2786
+#, c-format
+msgid "symlinks are not supported on this platform"
+msgstr "символічні посилання не підтримуються цією платформою"
+
+#: pg_receivewal.c:79
+#, c-format
+msgid "%s receives PostgreSQL streaming write-ahead logs.\n\n"
+msgstr "%s отримує передачу випереджувальних журналів PostgreSQL.\n\n"
+
+#: pg_receivewal.c:83 pg_recvlogical.c:84
+#, c-format
+msgid "\n"
+"Options:\n"
+msgstr "\n"
+"Параметри:\n"
+
+#: pg_receivewal.c:84
+#, c-format
+msgid " -D, --directory=DIR receive write-ahead log files into this directory\n"
+msgstr " -D, --directory=DIR зберігати файли випереджувального журналювання до цього каталогу\n"
+
+#: pg_receivewal.c:85 pg_recvlogical.c:85
+#, c-format
+msgid " -E, --endpos=LSN exit after receiving the specified LSN\n"
+msgstr " -E, --endpos=LSN вийти після отримання вказаного LSN\n"
+
+#: pg_receivewal.c:86 pg_recvlogical.c:89
+#, c-format
+msgid " --if-not-exists do not error if slot already exists when creating a slot\n"
+msgstr " --if-not-exists не видавати помилку, при створенні слота, якщо слот вже існує\n"
+
+#: pg_receivewal.c:87 pg_recvlogical.c:91
+#, c-format
+msgid " -n, --no-loop do not loop on connection lost\n"
+msgstr " -n, --no-loop переривати роботу при втраті підключення\n"
+
+#: pg_receivewal.c:88
+#, c-format
+msgid " --no-sync do not wait for changes to be written safely to disk\n"
+msgstr " --no-sync не чекати безпечного збереження змін на диск\n"
+
+#: pg_receivewal.c:89 pg_recvlogical.c:96
+#, c-format
+msgid " -s, --status-interval=SECS\n"
+" time between status packets sent to server (default: %d)\n"
+msgstr " -s, --status-interval=SECS\n"
+" інтервал між відправкою статусних пакетів серверу (за замовчуванням: %d)\n"
+
+#: pg_receivewal.c:92
+#, c-format
+msgid " --synchronous flush write-ahead log immediately after writing\n"
+msgstr " --synchronous очистити випереджувальне журналювання відразу після запису\n"
+
+#: pg_receivewal.c:95
+#, c-format
+msgid " -Z, --compress=METHOD[:DETAIL]\n"
+" compress as specified\n"
+msgstr " -Z, --compress=METHOD[:DETAIL]\n"
+" стискати як вказано\n"
+
+#: pg_receivewal.c:105
+#, c-format
+msgid "\n"
+"Optional actions:\n"
+msgstr "\n"
+"Додаткові дії:\n"
+
+#: pg_receivewal.c:106 pg_recvlogical.c:81
+#, c-format
+msgid " --create-slot create a new replication slot (for the slot's name see --slot)\n"
+msgstr " --create-slot створити новий слот реплікації (ім'я слота задає параметр --slot)\n"
+
+#: pg_receivewal.c:107 pg_recvlogical.c:82
+#, c-format
+msgid " --drop-slot drop the replication slot (for the slot's name see --slot)\n"
+msgstr " --drop-slot видалити слот реплікації (ім'я слота задає параметр --slot)\n"
+
+#: pg_receivewal.c:252
+#, c-format
+msgid "finished segment at %X/%X (timeline %u)"
+msgstr "завершено сегмент в позиції %X/%X (часова шкала %u)"
+
+#: pg_receivewal.c:259
+#, c-format
+msgid "stopped log streaming at %X/%X (timeline %u)"
+msgstr "зупинено потокове передавання журналу в позиції %X/%X (часова шкала %u)"
+
+#: pg_receivewal.c:275
+#, c-format
+msgid "switched to timeline %u at %X/%X"
+msgstr "переключено на часову шкалу %u в позиції %X/%X"
+
+#: pg_receivewal.c:285
+#, c-format
+msgid "received interrupt signal, exiting"
+msgstr "отримано сигнал переривання, завершення роботи"
+
+#: pg_receivewal.c:317
+#, c-format
+msgid "could not close directory \"%s\": %m"
+msgstr "не вдалося закрити каталог \"%s\": %m"
+
+#: pg_receivewal.c:384
+#, c-format
+msgid "segment file \"%s\" has incorrect size %lld, skipping"
+msgstr "файл сегменту \"%s\" має неправильний розмір %lld, пропускається"
+
+#: pg_receivewal.c:401
+#, c-format
+msgid "could not open compressed file \"%s\": %m"
+msgstr "не вдалося відкрити стиснутий файл \"%s\": %m"
+
+#: pg_receivewal.c:404
+#, c-format
+msgid "could not seek in compressed file \"%s\": %m"
+msgstr "не вдалося знайти в стиснутому файлі \"%s\": %m"
+
+#: pg_receivewal.c:410
+#, c-format
+msgid "could not read compressed file \"%s\": %m"
+msgstr "не вдалося прочитати стиснутий файл \"%s\": %m"
+
+#: pg_receivewal.c:413
+#, c-format
+msgid "could not read compressed file \"%s\": read %d of %zu"
+msgstr "не вдалося прочитати стиснутий файл \"%s\": прочитано %d з %zu"
+
+#: pg_receivewal.c:423
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %d, skipping"
+msgstr "файл стиснутого сегменту \"%s\" має неправильний розмір без стискання %d, пропускається"
+
+#: pg_receivewal.c:451
+#, c-format
+msgid "could not create LZ4 decompression context: %s"
+msgstr "не вдалося створити контекст декомпресії LZ4: %s"
+
+#: pg_receivewal.c:463
+#, c-format
+msgid "could not read file \"%s\": %m"
+msgstr "не вдалося прочитати файл \"%s\": %m"
+
+#: pg_receivewal.c:481
+#, c-format
+msgid "could not decompress file \"%s\": %s"
+msgstr "не вдалося розпакувати файл \"%s\": %s"
+
+#: pg_receivewal.c:504
+#, c-format
+msgid "could not free LZ4 decompression context: %s"
+msgstr "не вдалося звільнити контекст декомпресії LZ4: %s"
+
+#: pg_receivewal.c:509
+#, c-format
+msgid "compressed segment file \"%s\" has incorrect uncompressed size %zu, skipping"
+msgstr "файл стиснутого сегменту \"%s\" має неправильний розмір не стиснутого розміру %zu, пропускається"
+
+#: pg_receivewal.c:514
+#, c-format
+msgid "cannot check file \"%s\": compression with %s not supported by this build"
+msgstr "неможливо перевірити файл \"%s\": стиснення %s не підтримується даною збіркою"
+
+#: pg_receivewal.c:641
+#, c-format
+msgid "starting log streaming at %X/%X (timeline %u)"
+msgstr "початок потокового передавання журналу в позиції %X/%X (часова шкала %u)"
+
+#: pg_receivewal.c:783 pg_recvlogical.c:785
+#, c-format
+msgid "could not parse end position \"%s\""
+msgstr "не вдалося проаналізувати кінцеву позицію \"%s\""
+
+#: pg_receivewal.c:832
+#, c-format
+msgid "cannot use --create-slot together with --drop-slot"
+msgstr "використовувати --create-slot разом з --drop-slot не можна"
+
+#: pg_receivewal.c:848
+#, c-format
+msgid "cannot use --synchronous together with --no-sync"
+msgstr "використовувати --synchronous разом з --no-sync не можна"
+
+#: pg_receivewal.c:858
+#, c-format
+msgid "no target directory specified"
+msgstr "цільовий каталог не вказано"
+
+#: pg_receivewal.c:882
+#, c-format
+msgid "compression with %s is not yet supported"
+msgstr "стиснення з %s ще не підтримується"
+
+#: pg_receivewal.c:924
+#, c-format
+msgid "replication connection using slot \"%s\" is unexpectedly database specific"
+msgstr "підключення для реплікації з використанням слоту \"%s\" неочікувано виявилось прив'язаним до бази даних"
+
+#: pg_receivewal.c:943 pg_recvlogical.c:955
+#, c-format
+msgid "dropping replication slot \"%s\""
+msgstr "видалення слоту реплікації \"%s\""
+
+#: pg_receivewal.c:954 pg_recvlogical.c:965
+#, c-format
+msgid "creating replication slot \"%s\""
+msgstr "створення слоту реплікації \"%s\""
+
+#: pg_receivewal.c:983 pg_recvlogical.c:989
+#, c-format
+msgid "disconnected"
+msgstr "роз’єднано"
+
+#. translator: check source for value for %d
+#: pg_receivewal.c:987 pg_recvlogical.c:993
+#, c-format
+msgid "disconnected; waiting %d seconds to try again"
+msgstr "роз’єднано; через %d секунд буде повторна спроба"
+
+#: pg_recvlogical.c:76
+#, c-format
+msgid "%s controls PostgreSQL logical decoding streams.\n\n"
+msgstr "%s керує потоковими передаваннями логічного декодування PostgreSQL.\n\n"
+
+#: pg_recvlogical.c:80
+#, c-format
+msgid "\n"
+"Action to be performed:\n"
+msgstr "\n"
+"Дія до виконання:\n"
+
+#: pg_recvlogical.c:83
+#, c-format
+msgid " --start start streaming in a replication slot (for the slot's name see --slot)\n"
+msgstr " --start почати потокове передавання в слоті реплікації (ім'я слоту задає параметр --slot)\n"
+
+#: pg_recvlogical.c:86
+#, c-format
+msgid " -f, --file=FILE receive log into this file, - for stdout\n"
+msgstr " -f, --file=FILE зберігати журнал до цього файлу, - позначає stdout\n"
+
+#: pg_recvlogical.c:87
+#, c-format
+msgid " -F --fsync-interval=SECS\n"
+" time between fsyncs to the output file (default: %d)\n"
+msgstr " -F --fsync-interval=SECS\n"
+" час між fsyncs до файлу виводу (за замовчуванням: %d)\n"
+
+#: pg_recvlogical.c:90
+#, c-format
+msgid " -I, --startpos=LSN where in an existing slot should the streaming start\n"
+msgstr " -I, --startpos=LSN де в існуючому слоті слід почати потокове передавання\n"
+
+#: pg_recvlogical.c:92
+#, c-format
+msgid " -o, --option=NAME[=VALUE]\n"
+" pass option NAME with optional value VALUE to the\n"
+" output plugin\n"
+msgstr " -o, --option=NAME[=VALUE]\n"
+" передати параметр NAME з додатковим значенням VALUE до\n"
+" плагіну виводу\n"
+
+#: pg_recvlogical.c:95
+#, c-format
+msgid " -P, --plugin=PLUGIN use output plugin PLUGIN (default: %s)\n"
+msgstr " -P, --plugin=PLUGIN використовувати плагін виводу PLUGIN (за замовчуванням: %s)\n"
+
+#: pg_recvlogical.c:98
+#, c-format
+msgid " -S, --slot=SLOTNAME name of the logical replication slot\n"
+msgstr " -S, --slot=SLOTNAME ім'я слоту логічної реплікації\n"
+
+#: pg_recvlogical.c:99
+#, c-format
+msgid " -t, --two-phase enable decoding of prepared transactions when creating a slot\n"
+msgstr " -t, --two-phase активувати декодування підготовлених транзакцій під час створення слоту\n"
+
+#: pg_recvlogical.c:104
+#, c-format
+msgid " -d, --dbname=DBNAME database to connect to\n"
+msgstr " -d, --dbname=DBNAME бази даних для підключення\n"
+
+#: pg_recvlogical.c:137
+#, c-format
+msgid "confirming write up to %X/%X, flush to %X/%X (slot %s)"
+msgstr "підтвердження запису до %X/%X, очищення до %X/%X (слот %s)"
+
+#: pg_recvlogical.c:161 receivelog.c:366
+#, c-format
+msgid "could not send feedback packet: %s"
+msgstr "не вдалося відправити пакет зворотнього зв'язку: %s"
+
+#: pg_recvlogical.c:229
+#, c-format
+msgid "starting log streaming at %X/%X (slot %s)"
+msgstr "початок потокового передавання журналу в позиції %X/%X (слот %s)"
+
+#: pg_recvlogical.c:271
+#, c-format
+msgid "streaming initiated"
+msgstr "потокове передавання ініційовано"
+
+#: pg_recvlogical.c:335
+#, c-format
+msgid "could not open log file \"%s\": %m"
+msgstr "не вдалося відкрити файл журналу \"%s\": %m"
+
+#: pg_recvlogical.c:364 receivelog.c:889
+#, c-format
+msgid "invalid socket: %s"
+msgstr "неприпустимий сокет: %s"
+
+#: pg_recvlogical.c:417 receivelog.c:917
+#, c-format
+msgid "%s() failed: %m"
+msgstr "%s() помилка: %m"
+
+#: pg_recvlogical.c:424 receivelog.c:967
+#, c-format
+msgid "could not receive data from WAL stream: %s"
+msgstr "не вдалося отримати дані з WAL потоку: %s"
+
+#: pg_recvlogical.c:466 pg_recvlogical.c:517 receivelog.c:1011
+#: receivelog.c:1074
+#, c-format
+msgid "streaming header too small: %d"
+msgstr "заголовок потокового передавання занадто малий: %d"
+
+#: pg_recvlogical.c:501 receivelog.c:849
+#, c-format
+msgid "unrecognized streaming header: \"%c\""
+msgstr "нерозпізнаний заголовок потокового передавання: \"%c\""
+
+#: pg_recvlogical.c:555 pg_recvlogical.c:567
+#, c-format
+msgid "could not write %d bytes to log file \"%s\": %m"
+msgstr "не вдалося записати %d байт до файлу журналу \"%s\": %m"
+
+#: pg_recvlogical.c:621 receivelog.c:648 receivelog.c:685
+#, c-format
+msgid "unexpected termination of replication stream: %s"
+msgstr "неочікуване завершення роботи потоку реплікації: %s"
+
+#: pg_recvlogical.c:780
+#, c-format
+msgid "could not parse start position \"%s\""
+msgstr "не вдалося аналізувати початкову позицію \"%s\""
+
+#: pg_recvlogical.c:858
+#, c-format
+msgid "no slot specified"
+msgstr "слот не вказано"
+
+#: pg_recvlogical.c:865
+#, c-format
+msgid "no target file specified"
+msgstr "цільовий файл не вказано"
+
+#: pg_recvlogical.c:872
+#, c-format
+msgid "no database specified"
+msgstr "база даних не вказана"
+
+#: pg_recvlogical.c:879
+#, c-format
+msgid "at least one action needs to be specified"
+msgstr "необхідно вказати щонайменше одну дію"
+
+#: pg_recvlogical.c:886
+#, c-format
+msgid "cannot use --create-slot or --start together with --drop-slot"
+msgstr "використовувати --create-slot або --start разом з --drop-slot не можна"
+
+#: pg_recvlogical.c:893
+#, c-format
+msgid "cannot use --create-slot or --drop-slot together with --startpos"
+msgstr "використовувати --create-slot або --drop-slot разом з --startpos не можна"
+
+#: pg_recvlogical.c:900
+#, c-format
+msgid "--endpos may only be specified with --start"
+msgstr "--endpos можна вказати лише з --start"
+
+#: pg_recvlogical.c:907
+#, c-format
+msgid "--two-phase may only be specified with --create-slot"
+msgstr "--two-phase може бути вказано тільки з --create-slot"
+
+#: pg_recvlogical.c:939
+#, c-format
+msgid "could not establish database-specific replication connection"
+msgstr "не вдалося встановити підключення для реплікації до вказаної бази даних"
+
+#: pg_recvlogical.c:1033
+#, c-format
+msgid "end position %X/%X reached by keepalive"
+msgstr "кінцева позиція %X/%X досягнута наживо"
+
+#: pg_recvlogical.c:1036
+#, c-format
+msgid "end position %X/%X reached by WAL record at %X/%X"
+msgstr "кінцева позиція %X/%X досягнута WAL записом %X/%X"
+
+#: receivelog.c:68
+#, c-format
+msgid "could not create archive status file \"%s\": %s"
+msgstr "не вдалося створити файл статусу архіву \"%s\": %s"
+
+#: receivelog.c:75
+#, c-format
+msgid "could not close archive status file \"%s\": %s"
+msgstr "не вдалося закрити файл статусу архіву \"%s\": %s"
+
+#: receivelog.c:123
+#, c-format
+msgid "could not get size of write-ahead log file \"%s\": %s"
+msgstr "не вдалося отримати розмір файлу випереджувального журналювання \"%s\": %s"
+
+#: receivelog.c:134
+#, c-format
+msgid "could not open existing write-ahead log file \"%s\": %s"
+msgstr "не вдалося відкрити існуючий файл випереджувального журналювання \"%s\": %s"
+
+#: receivelog.c:143
+#, c-format
+msgid "could not fsync existing write-ahead log file \"%s\": %s"
+msgstr "не вдалося fsync існуючий файл випереджувального журналювання \"%s\": %s"
+
+#: receivelog.c:158
+#, c-format
+msgid "write-ahead log file \"%s\" has %zd byte, should be 0 or %d"
+msgid_plural "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d"
+msgstr[0] "файл випереджувального журналювання \"%s\" має %zd байт, а повинен мати 0 або %d"
+msgstr[1] "файл випереджувального журналювання \"%s\" має %zd байти, а повинен мати 0 або %d"
+msgstr[2] "файл випереджувального журналювання \"%s\" має %zd байтів, а повинен мати 0 або %d"
+msgstr[3] "файл випереджувального журналювання \"%s\" має %zd байтів, а повинен мати 0 або %d"
+
+#: receivelog.c:174
+#, c-format
+msgid "could not open write-ahead log file \"%s\": %s"
+msgstr "не вдалося відкрити файл випереджувального журналювання \"%s\": %s"
+
+#: receivelog.c:208
+#, c-format
+msgid "could not determine seek position in file \"%s\": %s"
+msgstr "не вдалося визначити позицію у файлі \"%s\": %s"
+
+#: receivelog.c:223
+#, c-format
+msgid "not renaming \"%s\", segment is not complete"
+msgstr "не перейменовується \"%s\", сегмент не завершений"
+
+#: receivelog.c:234 receivelog.c:323 receivelog.c:694
+#, c-format
+msgid "could not close file \"%s\": %s"
+msgstr "не вдалося закрити файл \"%s\": %s"
+
+#: receivelog.c:295
+#, c-format
+msgid "server reported unexpected history file name for timeline %u: %s"
+msgstr "сервер повідомив неочікуване ім'я файлу історії часової шкали %u: %s"
+
+#: receivelog.c:303
+#, c-format
+msgid "could not create timeline history file \"%s\": %s"
+msgstr "не вдалося створити файл історії часової шкали \"%s\": %s"
+
+#: receivelog.c:310
+#, c-format
+msgid "could not write timeline history file \"%s\": %s"
+msgstr "не вдалося записати файл історії часової шкали \"%s\": %s"
+
+#: receivelog.c:400
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions older than %s"
+msgstr "несумісна версія серверу %s; клієнт не підтримує потокове передавання з версій серверу старіших, ніж %s"
+
+#: receivelog.c:409
+#, c-format
+msgid "incompatible server version %s; client does not support streaming from server versions newer than %s"
+msgstr "несумісна версія серверу %s; клієнт не підтримує потокове передавання з версій серверу новіших, ніж %s"
+
+#: receivelog.c:514
+#, c-format
+msgid "system identifier does not match between base backup and streaming connection"
+msgstr "системний ідентифікатор базової резервної копії не відповідає ідентифікатору потокового передавання підключення"
+
+#: receivelog.c:522
+#, c-format
+msgid "starting timeline %u is not present in the server"
+msgstr "початкова часова шкала %u не існує на сервері"
+
+#: receivelog.c:561
+#, c-format
+msgid "unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "неочікувана відповідь на команду TIMELINE_HISTORY: отримано %d рядків і %d полів, очікувалось %d рядків і %d полів"
+
+#: receivelog.c:632
+#, c-format
+msgid "server reported unexpected next timeline %u, following timeline %u"
+msgstr "сервер неочікувано повідомив наступну часову шкалу %u після часової шкали %u"
+
+#: receivelog.c:638
+#, c-format
+msgid "server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X"
+msgstr "сервер зупинив потокове передавання часової шкали %u в позиції %X/%X, але повідомив, що наступна часова шкала %u почнеться в позиції %X/%X"
+
+#: receivelog.c:678
+#, c-format
+msgid "replication stream was terminated before stop point"
+msgstr "потік реплікації перервано до точки зупинки"
+
+#: receivelog.c:724
+#, c-format
+msgid "unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "неочікуваний набір результатів після кінця часової шкали: отримано %d рядків і %d полів, очікувалось %d рядків і %d полів"
+
+#: receivelog.c:733
+#, c-format
+msgid "could not parse next timeline's starting point \"%s\""
+msgstr "не вдалося аналізувати початкову точку наступної часової шкали \"%s\""
+
+#: receivelog.c:781 receivelog.c:1030 walmethods.c:1205
+#, c-format
+msgid "could not fsync file \"%s\": %s"
+msgstr "не вдалося fsync файл \"%s\": %s"
+
+#: receivelog.c:1091
+#, c-format
+msgid "received write-ahead log record for offset %u with no file open"
+msgstr "отримано запис випереджувального журналювання для зсуву %u з закритим файлом"
+
+#: receivelog.c:1101
+#, c-format
+msgid "got WAL data offset %08x, expected %08x"
+msgstr "отримано дані зсуву WAL %08x, очікувалось %08x"
+
+#: receivelog.c:1135
+#, c-format
+msgid "could not write %d bytes to WAL file \"%s\": %s"
+msgstr "не вдалося записати %d байт до файлу WAL \"%s\": %s"
+
+#: receivelog.c:1160 receivelog.c:1200 receivelog.c:1230
+#, c-format
+msgid "could not send copy-end packet: %s"
+msgstr "не вдалося відправити пакет кінця копіювання \"copy-end\": %s"
+
+#: streamutil.c:159
+msgid "Password: "
+msgstr "Пароль: "
+
+#: streamutil.c:182
+#, c-format
+msgid "could not connect to server"
+msgstr "не вдалося підключитись до серверу"
+
+#: streamutil.c:225
+#, c-format
+msgid "could not clear search_path: %s"
+msgstr "не вдалося очистити search_path: %s"
+
+#: streamutil.c:241
+#, c-format
+msgid "could not determine server setting for integer_datetimes"
+msgstr "не вдалося визначити настроювання серверу для integer_datetimes"
+
+#: streamutil.c:248
+#, c-format
+msgid "integer_datetimes compile flag does not match server"
+msgstr "параметри компіляції integer_datetimes не відповідають серверу"
+
+#: streamutil.c:299
+#, c-format
+msgid "could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "не вдалося отримати розмір сегменту WAL: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів"
+
+#: streamutil.c:309
+#, c-format
+msgid "WAL segment size could not be parsed"
+msgstr "не вдалося аналізувати розмір сегмента WAL"
+
+#: streamutil.c:327
+#, c-format
+msgid "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte"
+msgid_plural "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes"
+msgstr[0] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байт"
+msgstr[1] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байти"
+msgstr[2] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байтів"
+msgstr[3] "Розмір сегменту WAL повинен бути двійкою, піднесеною до степеня в інтервалі між 1 МБ і 1 ГБ, але віддалений сервер повідомив значення %d байтів"
+
+#: streamutil.c:372
+#, c-format
+msgid "could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "не вдалося вилучити позначку доступа групи: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів"
+
+#: streamutil.c:381
+#, c-format
+msgid "group access flag could not be parsed: %s"
+msgstr "не вдалося аналізувати позначку доступа групи: %s"
+
+#: streamutil.c:424 streamutil.c:461
+#, c-format
+msgid "could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields"
+msgstr "не вдалося ідентифікувати систему: отримано %d рядків і %d полів, очікувалось %d рядків і %d або більше полів"
+
+#: streamutil.c:513
+#, c-format
+msgid "could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "не вдалося прочитати слот реплікації \"%s\": отримано %d рядків і %d полів, очікувалось %d рядків і %d полів"
+
+#: streamutil.c:525
+#, c-format
+msgid "replication slot \"%s\" does not exist"
+msgstr "слот реплікації \"%s\" не існує"
+
+#: streamutil.c:536
+#, c-format
+msgid "expected a physical replication slot, got type \"%s\" instead"
+msgstr "очікувався слот фізичної реплікації, а натомість знайдено \"%s\""
+
+#: streamutil.c:550
+#, c-format
+msgid "could not parse restart_lsn \"%s\" for replication slot \"%s\""
+msgstr "не вдалося аналізувати restart_lsn \"%s\" для слоту реплікації \"%s\""
+
+#: streamutil.c:667
+#, c-format
+msgid "could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "не вдалося створити слот реплікації \"%s\": отримано %d рядків і %d полів, очікувалось %d рядків і %d полів"
+
+#: streamutil.c:711
+#, c-format
+msgid "could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields"
+msgstr "не вдалося видалити слот реплікації \"%s\": отримано %d рядків і %d полів, очікувалось %d рядків і %d полів"
+
+#: walmethods.c:720 walmethods.c:1267
+msgid "could not compress data"
+msgstr "не вдалося стиснути дані"
+
+#: walmethods.c:749
+msgid "could not reset compression stream"
+msgstr "не вдалося скинути потік стискання"
+
+#: walmethods.c:880
+msgid "implementation error: tar files can't have more than one open file"
+msgstr "помилка реалізації: файли tar не можуть мати більше одного відкритого файлу"
+
+#: walmethods.c:894
+msgid "could not create tar header"
+msgstr "не вдалося створити заголовок tar"
+
+#: walmethods.c:910 walmethods.c:951 walmethods.c:1170 walmethods.c:1183
+msgid "could not change compression parameters"
+msgstr "не вдалося змінити параметри стискання"
+
+#: walmethods.c:1055
+msgid "unlink not supported with compression"
+msgstr "unink не підтримується зі стисканням"
+
+#: walmethods.c:1291
+msgid "could not close compression stream"
+msgstr "не вдалося закрити потік стискання"
+
diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c
new file mode 100644
index 0000000..ad866a7
--- /dev/null
+++ b/src/bin/pg_basebackup/receivelog.c
@@ -0,0 +1,1276 @@
+/*-------------------------------------------------------------------------
+ *
+ * receivelog.c - receive WAL files using the streaming
+ * replication protocol.
+ *
+ * Author: Magnus Hagander <magnus@hagander.net>
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/receivelog.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+#include "access/xlog_internal.h"
+#include "common/file_utils.h"
+#include "common/logging.h"
+#include "libpq-fe.h"
+#include "receivelog.h"
+#include "streamutil.h"
+
+/* fd and filename for currently open WAL file */
+static Walfile *walfile = NULL;
+static char current_walfile_name[MAXPGPATH] = "";
+static bool reportFlushPosition = false;
+static XLogRecPtr lastFlushPosition = InvalidXLogRecPtr;
+
+static bool still_sending = true; /* feedback still needs to be sent? */
+
+static PGresult *HandleCopyStream(PGconn *conn, StreamCtl *stream,
+ XLogRecPtr *stoppos);
+static int CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket);
+static int CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket,
+ char **buffer);
+static bool ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf,
+ int len, XLogRecPtr blockpos, TimestampTz *last_status);
+static bool ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
+ XLogRecPtr *blockpos);
+static PGresult *HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf,
+ XLogRecPtr blockpos, XLogRecPtr *stoppos);
+static bool CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos);
+static long CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout,
+ TimestampTz last_status);
+
+static bool ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos,
+ uint32 *timeline);
+
+static bool
+mark_file_as_archived(StreamCtl *stream, const char *fname)
+{
+ Walfile *f;
+ static char tmppath[MAXPGPATH];
+
+ snprintf(tmppath, sizeof(tmppath), "archive_status/%s.done",
+ fname);
+
+ f = stream->walmethod->open_for_write(tmppath, NULL, 0);
+ if (f == NULL)
+ {
+ pg_log_error("could not create archive status file \"%s\": %s",
+ tmppath, stream->walmethod->getlasterror());
+ return false;
+ }
+
+ if (stream->walmethod->close(f, CLOSE_NORMAL) != 0)
+ {
+ pg_log_error("could not close archive status file \"%s\": %s",
+ tmppath, stream->walmethod->getlasterror());
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Open a new WAL file in the specified directory.
+ *
+ * Returns true if OK; on failure, returns false after printing an error msg.
+ * On success, 'walfile' is set to the FD for the file, and the base filename
+ * (without partial_suffix) is stored in 'current_walfile_name'.
+ *
+ * The file will be padded to 16Mb with zeroes.
+ */
+static bool
+open_walfile(StreamCtl *stream, XLogRecPtr startpoint)
+{
+ Walfile *f;
+ char *fn;
+ ssize_t size;
+ XLogSegNo segno;
+
+ XLByteToSeg(startpoint, segno, WalSegSz);
+ XLogFileName(current_walfile_name, stream->timeline, segno, WalSegSz);
+
+ /* Note that this considers the compression used if necessary */
+ fn = stream->walmethod->get_file_name(current_walfile_name,
+ stream->partial_suffix);
+
+ /*
+ * When streaming to files, if an existing file exists we verify that it's
+ * either empty (just created), or a complete WalSegSz segment (in which
+ * case it has been created and padded). Anything else indicates a corrupt
+ * file. Compressed files have no need for padding, so just ignore this
+ * case.
+ *
+ * When streaming to tar, no file with this name will exist before, so we
+ * never have to verify a size.
+ */
+ if (stream->walmethod->compression_algorithm() == PG_COMPRESSION_NONE &&
+ stream->walmethod->existsfile(fn))
+ {
+ size = stream->walmethod->get_file_size(fn);
+ if (size < 0)
+ {
+ pg_log_error("could not get size of write-ahead log file \"%s\": %s",
+ fn, stream->walmethod->getlasterror());
+ pg_free(fn);
+ return false;
+ }
+ if (size == WalSegSz)
+ {
+ /* Already padded file. Open it for use */
+ f = stream->walmethod->open_for_write(current_walfile_name, stream->partial_suffix, 0);
+ if (f == NULL)
+ {
+ pg_log_error("could not open existing write-ahead log file \"%s\": %s",
+ fn, stream->walmethod->getlasterror());
+ pg_free(fn);
+ return false;
+ }
+
+ /* fsync file in case of a previous crash */
+ if (stream->walmethod->sync(f) != 0)
+ {
+ pg_log_error("could not fsync existing write-ahead log file \"%s\": %s",
+ fn, stream->walmethod->getlasterror());
+ stream->walmethod->close(f, CLOSE_UNLINK);
+ exit(1);
+ }
+
+ walfile = f;
+ pg_free(fn);
+ return true;
+ }
+ if (size != 0)
+ {
+ /* if write didn't set errno, assume problem is no disk space */
+ if (errno == 0)
+ errno = ENOSPC;
+ pg_log_error(ngettext("write-ahead log file \"%s\" has %zd byte, should be 0 or %d",
+ "write-ahead log file \"%s\" has %zd bytes, should be 0 or %d",
+ size),
+ fn, size, WalSegSz);
+ pg_free(fn);
+ return false;
+ }
+ /* File existed and was empty, so fall through and open */
+ }
+
+ /* No file existed, so create one */
+
+ f = stream->walmethod->open_for_write(current_walfile_name,
+ stream->partial_suffix, WalSegSz);
+ if (f == NULL)
+ {
+ pg_log_error("could not open write-ahead log file \"%s\": %s",
+ fn, stream->walmethod->getlasterror());
+ pg_free(fn);
+ return false;
+ }
+
+ pg_free(fn);
+ walfile = f;
+ return true;
+}
+
+/*
+ * Close the current WAL file (if open), and rename it to the correct
+ * filename if it's complete. On failure, prints an error message to stderr
+ * and returns false, otherwise returns true.
+ */
+static bool
+close_walfile(StreamCtl *stream, XLogRecPtr pos)
+{
+ char *fn;
+ off_t currpos;
+ int r;
+
+ if (walfile == NULL)
+ return true;
+
+ /* Note that this considers the compression used if necessary */
+ fn = stream->walmethod->get_file_name(current_walfile_name,
+ stream->partial_suffix);
+
+ currpos = stream->walmethod->get_current_pos(walfile);
+
+ if (currpos == -1)
+ {
+ pg_log_error("could not determine seek position in file \"%s\": %s",
+ fn, stream->walmethod->getlasterror());
+ stream->walmethod->close(walfile, CLOSE_UNLINK);
+ walfile = NULL;
+
+ pg_free(fn);
+ return false;
+ }
+
+ if (stream->partial_suffix)
+ {
+ if (currpos == WalSegSz)
+ r = stream->walmethod->close(walfile, CLOSE_NORMAL);
+ else
+ {
+ pg_log_info("not renaming \"%s\", segment is not complete", fn);
+ r = stream->walmethod->close(walfile, CLOSE_NO_RENAME);
+ }
+ }
+ else
+ r = stream->walmethod->close(walfile, CLOSE_NORMAL);
+
+ walfile = NULL;
+
+ if (r != 0)
+ {
+ pg_log_error("could not close file \"%s\": %s",
+ fn, stream->walmethod->getlasterror());
+
+ pg_free(fn);
+ return false;
+ }
+
+ pg_free(fn);
+
+ /*
+ * Mark file as archived if requested by the caller - pg_basebackup needs
+ * to do so as files can otherwise get archived again after promotion of a
+ * new node. This is in line with walreceiver.c always doing a
+ * XLogArchiveForceDone() after a complete segment.
+ */
+ if (currpos == WalSegSz && stream->mark_done)
+ {
+ /* writes error message if failed */
+ if (!mark_file_as_archived(stream, current_walfile_name))
+ return false;
+ }
+
+ lastFlushPosition = pos;
+ return true;
+}
+
+
+/*
+ * Check if a timeline history file exists.
+ */
+static bool
+existsTimeLineHistoryFile(StreamCtl *stream)
+{
+ char histfname[MAXFNAMELEN];
+
+ /*
+ * Timeline 1 never has a history file. We treat that as if it existed,
+ * since we never need to stream it.
+ */
+ if (stream->timeline == 1)
+ return true;
+
+ TLHistoryFileName(histfname, stream->timeline);
+
+ return stream->walmethod->existsfile(histfname);
+}
+
+static bool
+writeTimeLineHistoryFile(StreamCtl *stream, char *filename, char *content)
+{
+ int size = strlen(content);
+ char histfname[MAXFNAMELEN];
+ Walfile *f;
+
+ /*
+ * Check that the server's idea of how timeline history files should be
+ * named matches ours.
+ */
+ TLHistoryFileName(histfname, stream->timeline);
+ if (strcmp(histfname, filename) != 0)
+ {
+ pg_log_error("server reported unexpected history file name for timeline %u: %s",
+ stream->timeline, filename);
+ return false;
+ }
+
+ f = stream->walmethod->open_for_write(histfname, ".tmp", 0);
+ if (f == NULL)
+ {
+ pg_log_error("could not create timeline history file \"%s\": %s",
+ histfname, stream->walmethod->getlasterror());
+ return false;
+ }
+
+ if ((int) stream->walmethod->write(f, content, size) != size)
+ {
+ pg_log_error("could not write timeline history file \"%s\": %s",
+ histfname, stream->walmethod->getlasterror());
+
+ /*
+ * If we fail to make the file, delete it to release disk space
+ */
+ stream->walmethod->close(f, CLOSE_UNLINK);
+
+ return false;
+ }
+
+ if (stream->walmethod->close(f, CLOSE_NORMAL) != 0)
+ {
+ pg_log_error("could not close file \"%s\": %s",
+ histfname, stream->walmethod->getlasterror());
+ return false;
+ }
+
+ /* Maintain archive_status, check close_walfile() for details. */
+ if (stream->mark_done)
+ {
+ /* writes error message if failed */
+ if (!mark_file_as_archived(stream, histfname))
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Send a Standby Status Update message to server.
+ */
+static bool
+sendFeedback(PGconn *conn, XLogRecPtr blockpos, TimestampTz now, bool replyRequested)
+{
+ char replybuf[1 + 8 + 8 + 8 + 8 + 1];
+ int len = 0;
+
+ replybuf[len] = 'r';
+ len += 1;
+ fe_sendint64(blockpos, &replybuf[len]); /* write */
+ len += 8;
+ if (reportFlushPosition)
+ fe_sendint64(lastFlushPosition, &replybuf[len]); /* flush */
+ else
+ fe_sendint64(InvalidXLogRecPtr, &replybuf[len]); /* flush */
+ len += 8;
+ fe_sendint64(InvalidXLogRecPtr, &replybuf[len]); /* apply */
+ len += 8;
+ fe_sendint64(now, &replybuf[len]); /* sendTime */
+ len += 8;
+ replybuf[len] = replyRequested ? 1 : 0; /* replyRequested */
+ len += 1;
+
+ if (PQputCopyData(conn, replybuf, len) <= 0 || PQflush(conn))
+ {
+ pg_log_error("could not send feedback packet: %s",
+ PQerrorMessage(conn));
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * Check that the server version we're connected to is supported by
+ * ReceiveXlogStream().
+ *
+ * If it's not, an error message is printed to stderr, and false is returned.
+ */
+bool
+CheckServerVersionForStreaming(PGconn *conn)
+{
+ int minServerMajor,
+ maxServerMajor;
+ int serverMajor;
+
+ /*
+ * The message format used in streaming replication changed in 9.3, so we
+ * cannot stream from older servers. And we don't support servers newer
+ * than the client; it might work, but we don't know, so err on the safe
+ * side.
+ */
+ minServerMajor = 903;
+ maxServerMajor = PG_VERSION_NUM / 100;
+ serverMajor = PQserverVersion(conn) / 100;
+ if (serverMajor < minServerMajor)
+ {
+ const char *serverver = PQparameterStatus(conn, "server_version");
+
+ pg_log_error("incompatible server version %s; client does not support streaming from server versions older than %s",
+ serverver ? serverver : "'unknown'",
+ "9.3");
+ return false;
+ }
+ else if (serverMajor > maxServerMajor)
+ {
+ const char *serverver = PQparameterStatus(conn, "server_version");
+
+ pg_log_error("incompatible server version %s; client does not support streaming from server versions newer than %s",
+ serverver ? serverver : "'unknown'",
+ PG_VERSION);
+ return false;
+ }
+ return true;
+}
+
+/*
+ * Receive a log stream starting at the specified position.
+ *
+ * Individual parameters are passed through the StreamCtl structure.
+ *
+ * If sysidentifier is specified, validate that both the system
+ * identifier and the timeline matches the specified ones
+ * (by sending an extra IDENTIFY_SYSTEM command)
+ *
+ * All received segments will be written to the directory
+ * specified by basedir. This will also fetch any missing timeline history
+ * files.
+ *
+ * The stream_stop callback will be called every time data
+ * is received, and whenever a segment is completed. If it returns
+ * true, the streaming will stop and the function
+ * return. As long as it returns false, streaming will continue
+ * indefinitely.
+ *
+ * If stream_stop() checks for external input, stop_socket should be set to
+ * the FD it checks. This will allow such input to be detected promptly
+ * rather than after standby_message_timeout (which might be indefinite).
+ * Note that signals will interrupt waits for input as well, but that is
+ * race-y since a signal received while busy won't interrupt the wait.
+ *
+ * standby_message_timeout controls how often we send a message
+ * back to the primary letting it know our progress, in milliseconds.
+ * Zero means no messages are sent.
+ * This message will only contain the write location, and never
+ * flush or replay.
+ *
+ * If 'partial_suffix' is not NULL, files are initially created with the
+ * given suffix, and the suffix is removed once the file is finished. That
+ * allows you to tell the difference between partial and completed files,
+ * so that you can continue later where you left.
+ *
+ * If 'synchronous' is true, the received WAL is flushed as soon as written,
+ * otherwise only when the WAL file is closed.
+ *
+ * Note: The WAL location *must* be at a log segment start!
+ */
+bool
+ReceiveXlogStream(PGconn *conn, StreamCtl *stream)
+{
+ char query[128];
+ char slotcmd[128];
+ PGresult *res;
+ XLogRecPtr stoppos;
+
+ /*
+ * The caller should've checked the server version already, but doesn't do
+ * any harm to check it here too.
+ */
+ if (!CheckServerVersionForStreaming(conn))
+ return false;
+
+ /*
+ * Decide whether we want to report the flush position. If we report the
+ * flush position, the primary will know what WAL we'll possibly
+ * re-request, and it can then remove older WAL safely. We must always do
+ * that when we are using slots.
+ *
+ * Reporting the flush position makes one eligible as a synchronous
+ * replica. People shouldn't include generic names in
+ * synchronous_standby_names, but we've protected them against it so far,
+ * so let's continue to do so unless specifically requested.
+ */
+ if (stream->replication_slot != NULL)
+ {
+ reportFlushPosition = true;
+ sprintf(slotcmd, "SLOT \"%s\" ", stream->replication_slot);
+ }
+ else
+ {
+ if (stream->synchronous)
+ reportFlushPosition = true;
+ else
+ reportFlushPosition = false;
+ slotcmd[0] = 0;
+ }
+
+ if (stream->sysidentifier != NULL)
+ {
+ char *sysidentifier = NULL;
+ TimeLineID servertli;
+
+ /*
+ * Get the server system identifier and timeline, and validate them.
+ */
+ if (!RunIdentifySystem(conn, &sysidentifier, &servertli, NULL, NULL))
+ {
+ pg_free(sysidentifier);
+ return false;
+ }
+
+ if (strcmp(stream->sysidentifier, sysidentifier) != 0)
+ {
+ pg_log_error("system identifier does not match between base backup and streaming connection");
+ pg_free(sysidentifier);
+ return false;
+ }
+ pg_free(sysidentifier);
+
+ if (stream->timeline > servertli)
+ {
+ pg_log_error("starting timeline %u is not present in the server",
+ stream->timeline);
+ return false;
+ }
+ }
+
+ /*
+ * initialize flush position to starting point, it's the caller's
+ * responsibility that that's sane.
+ */
+ lastFlushPosition = stream->startpos;
+
+ while (1)
+ {
+ /*
+ * Fetch the timeline history file for this timeline, if we don't have
+ * it already. When streaming log to tar, this will always return
+ * false, as we are never streaming into an existing file and
+ * therefore there can be no pre-existing timeline history file.
+ */
+ if (!existsTimeLineHistoryFile(stream))
+ {
+ snprintf(query, sizeof(query), "TIMELINE_HISTORY %u", stream->timeline);
+ res = PQexec(conn, query);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ /* FIXME: we might send it ok, but get an error */
+ pg_log_error("could not send replication command \"%s\": %s",
+ "TIMELINE_HISTORY", PQresultErrorMessage(res));
+ PQclear(res);
+ return false;
+ }
+
+ /*
+ * The response to TIMELINE_HISTORY is a single row result set
+ * with two fields: filename and content
+ */
+ if (PQnfields(res) != 2 || PQntuples(res) != 1)
+ {
+ pg_log_warning("unexpected response to TIMELINE_HISTORY command: got %d rows and %d fields, expected %d rows and %d fields",
+ PQntuples(res), PQnfields(res), 1, 2);
+ }
+
+ /* Write the history file to disk */
+ writeTimeLineHistoryFile(stream,
+ PQgetvalue(res, 0, 0),
+ PQgetvalue(res, 0, 1));
+
+ PQclear(res);
+ }
+
+ /*
+ * Before we start streaming from the requested location, check if the
+ * callback tells us to stop here.
+ */
+ if (stream->stream_stop(stream->startpos, stream->timeline, false))
+ return true;
+
+ /* Initiate the replication stream at specified location */
+ snprintf(query, sizeof(query), "START_REPLICATION %s%X/%X TIMELINE %u",
+ slotcmd,
+ LSN_FORMAT_ARGS(stream->startpos),
+ stream->timeline);
+ res = PQexec(conn, query);
+ if (PQresultStatus(res) != PGRES_COPY_BOTH)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ "START_REPLICATION", PQresultErrorMessage(res));
+ PQclear(res);
+ return false;
+ }
+ PQclear(res);
+
+ /* Stream the WAL */
+ res = HandleCopyStream(conn, stream, &stoppos);
+ if (res == NULL)
+ goto error;
+
+ /*
+ * Streaming finished.
+ *
+ * There are two possible reasons for that: a controlled shutdown, or
+ * we reached the end of the current timeline. In case of
+ * end-of-timeline, the server sends a result set after Copy has
+ * finished, containing information about the next timeline. Read
+ * that, and restart streaming from the next timeline. In case of
+ * controlled shutdown, stop here.
+ */
+ if (PQresultStatus(res) == PGRES_TUPLES_OK)
+ {
+ /*
+ * End-of-timeline. Read the next timeline's ID and starting
+ * position. Usually, the starting position will match the end of
+ * the previous timeline, but there are corner cases like if the
+ * server had sent us half of a WAL record, when it was promoted.
+ * The new timeline will begin at the end of the last complete
+ * record in that case, overlapping the partial WAL record on the
+ * old timeline.
+ */
+ uint32 newtimeline;
+ bool parsed;
+
+ parsed = ReadEndOfStreamingResult(res, &stream->startpos, &newtimeline);
+ PQclear(res);
+ if (!parsed)
+ goto error;
+
+ /* Sanity check the values the server gave us */
+ if (newtimeline <= stream->timeline)
+ {
+ pg_log_error("server reported unexpected next timeline %u, following timeline %u",
+ newtimeline, stream->timeline);
+ goto error;
+ }
+ if (stream->startpos > stoppos)
+ {
+ pg_log_error("server stopped streaming timeline %u at %X/%X, but reported next timeline %u to begin at %X/%X",
+ stream->timeline, LSN_FORMAT_ARGS(stoppos),
+ newtimeline, LSN_FORMAT_ARGS(stream->startpos));
+ goto error;
+ }
+
+ /* Read the final result, which should be CommandComplete. */
+ res = PQgetResult(conn);
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ pg_log_error("unexpected termination of replication stream: %s",
+ PQresultErrorMessage(res));
+ PQclear(res);
+ goto error;
+ }
+ PQclear(res);
+
+ /*
+ * Loop back to start streaming from the new timeline. Always
+ * start streaming at the beginning of a segment.
+ */
+ stream->timeline = newtimeline;
+ stream->startpos = stream->startpos -
+ XLogSegmentOffset(stream->startpos, WalSegSz);
+ continue;
+ }
+ else if (PQresultStatus(res) == PGRES_COMMAND_OK)
+ {
+ PQclear(res);
+
+ /*
+ * End of replication (ie. controlled shut down of the server).
+ *
+ * Check if the callback thinks it's OK to stop here. If not,
+ * complain.
+ */
+ if (stream->stream_stop(stoppos, stream->timeline, false))
+ return true;
+ else
+ {
+ pg_log_error("replication stream was terminated before stop point");
+ goto error;
+ }
+ }
+ else
+ {
+ /* Server returned an error. */
+ pg_log_error("unexpected termination of replication stream: %s",
+ PQresultErrorMessage(res));
+ PQclear(res);
+ goto error;
+ }
+ }
+
+error:
+ if (walfile != NULL && stream->walmethod->close(walfile, CLOSE_NO_RENAME) != 0)
+ pg_log_error("could not close file \"%s\": %s",
+ current_walfile_name, stream->walmethod->getlasterror());
+ walfile = NULL;
+ return false;
+}
+
+/*
+ * Helper function to parse the result set returned by server after streaming
+ * has finished. On failure, prints an error to stderr and returns false.
+ */
+static bool
+ReadEndOfStreamingResult(PGresult *res, XLogRecPtr *startpos, uint32 *timeline)
+{
+ uint32 startpos_xlogid,
+ startpos_xrecoff;
+
+ /*----------
+ * The result set consists of one row and two columns, e.g:
+ *
+ * next_tli | next_tli_startpos
+ * ----------+-------------------
+ * 4 | 0/9949AE0
+ *
+ * next_tli is the timeline ID of the next timeline after the one that
+ * just finished streaming. next_tli_startpos is the WAL location where
+ * the server switched to it.
+ *----------
+ */
+ if (PQnfields(res) < 2 || PQntuples(res) != 1)
+ {
+ pg_log_error("unexpected result set after end-of-timeline: got %d rows and %d fields, expected %d rows and %d fields",
+ PQntuples(res), PQnfields(res), 1, 2);
+ return false;
+ }
+
+ *timeline = atoi(PQgetvalue(res, 0, 0));
+ if (sscanf(PQgetvalue(res, 0, 1), "%X/%X", &startpos_xlogid,
+ &startpos_xrecoff) != 2)
+ {
+ pg_log_error("could not parse next timeline's starting point \"%s\"",
+ PQgetvalue(res, 0, 1));
+ return false;
+ }
+ *startpos = ((uint64) startpos_xlogid << 32) | startpos_xrecoff;
+
+ return true;
+}
+
+/*
+ * The main loop of ReceiveXlogStream. Handles the COPY stream after
+ * initiating streaming with the START_REPLICATION command.
+ *
+ * If the COPY ends (not necessarily successfully) due a message from the
+ * server, returns a PGresult and sets *stoppos to the last byte written.
+ * On any other sort of error, returns NULL.
+ */
+static PGresult *
+HandleCopyStream(PGconn *conn, StreamCtl *stream,
+ XLogRecPtr *stoppos)
+{
+ char *copybuf = NULL;
+ TimestampTz last_status = -1;
+ XLogRecPtr blockpos = stream->startpos;
+
+ still_sending = true;
+
+ while (1)
+ {
+ int r;
+ TimestampTz now;
+ long sleeptime;
+
+ /*
+ * Check if we should continue streaming, or abort at this point.
+ */
+ if (!CheckCopyStreamStop(conn, stream, blockpos))
+ goto error;
+
+ now = feGetCurrentTimestamp();
+
+ /*
+ * If synchronous option is true, issue sync command as soon as there
+ * are WAL data which has not been flushed yet.
+ */
+ if (stream->synchronous && lastFlushPosition < blockpos && walfile != NULL)
+ {
+ if (stream->walmethod->sync(walfile) != 0)
+ pg_fatal("could not fsync file \"%s\": %s",
+ current_walfile_name, stream->walmethod->getlasterror());
+ lastFlushPosition = blockpos;
+
+ /*
+ * Send feedback so that the server sees the latest WAL locations
+ * immediately.
+ */
+ if (!sendFeedback(conn, blockpos, now, false))
+ goto error;
+ last_status = now;
+ }
+
+ /*
+ * Potentially send a status message to the primary
+ */
+ if (still_sending && stream->standby_message_timeout > 0 &&
+ feTimestampDifferenceExceeds(last_status, now,
+ stream->standby_message_timeout))
+ {
+ /* Time to send feedback! */
+ if (!sendFeedback(conn, blockpos, now, false))
+ goto error;
+ last_status = now;
+ }
+
+ /*
+ * Calculate how long send/receive loops should sleep
+ */
+ sleeptime = CalculateCopyStreamSleeptime(now, stream->standby_message_timeout,
+ last_status);
+
+ r = CopyStreamReceive(conn, sleeptime, stream->stop_socket, &copybuf);
+ while (r != 0)
+ {
+ if (r == -1)
+ goto error;
+ if (r == -2)
+ {
+ PGresult *res = HandleEndOfCopyStream(conn, stream, copybuf, blockpos, stoppos);
+
+ if (res == NULL)
+ goto error;
+ else
+ return res;
+ }
+
+ /* Check the message type. */
+ if (copybuf[0] == 'k')
+ {
+ if (!ProcessKeepaliveMsg(conn, stream, copybuf, r, blockpos,
+ &last_status))
+ goto error;
+ }
+ else if (copybuf[0] == 'w')
+ {
+ if (!ProcessXLogDataMsg(conn, stream, copybuf, r, &blockpos))
+ goto error;
+
+ /*
+ * Check if we should continue streaming, or abort at this
+ * point.
+ */
+ if (!CheckCopyStreamStop(conn, stream, blockpos))
+ goto error;
+ }
+ else
+ {
+ pg_log_error("unrecognized streaming header: \"%c\"",
+ copybuf[0]);
+ goto error;
+ }
+
+ /*
+ * Process the received data, and any subsequent data we can read
+ * without blocking.
+ */
+ r = CopyStreamReceive(conn, 0, stream->stop_socket, &copybuf);
+ }
+ }
+
+error:
+ if (copybuf != NULL)
+ PQfreemem(copybuf);
+ return NULL;
+}
+
+/*
+ * Wait until we can read a CopyData message,
+ * or timeout, or occurrence of a signal or input on the stop_socket.
+ * (timeout_ms < 0 means wait indefinitely; 0 means don't wait.)
+ *
+ * Returns 1 if data has become available for reading, 0 if timed out
+ * or interrupted by signal or stop_socket input, and -1 on an error.
+ */
+static int
+CopyStreamPoll(PGconn *conn, long timeout_ms, pgsocket stop_socket)
+{
+ int ret;
+ fd_set input_mask;
+ int connsocket;
+ int maxfd;
+ struct timeval timeout;
+ struct timeval *timeoutptr;
+
+ connsocket = PQsocket(conn);
+ if (connsocket < 0)
+ {
+ pg_log_error("invalid socket: %s", PQerrorMessage(conn));
+ return -1;
+ }
+
+ FD_ZERO(&input_mask);
+ FD_SET(connsocket, &input_mask);
+ maxfd = connsocket;
+ if (stop_socket != PGINVALID_SOCKET)
+ {
+ FD_SET(stop_socket, &input_mask);
+ maxfd = Max(maxfd, stop_socket);
+ }
+
+ if (timeout_ms < 0)
+ timeoutptr = NULL;
+ else
+ {
+ timeout.tv_sec = timeout_ms / 1000L;
+ timeout.tv_usec = (timeout_ms % 1000L) * 1000L;
+ timeoutptr = &timeout;
+ }
+
+ ret = select(maxfd + 1, &input_mask, NULL, NULL, timeoutptr);
+
+ if (ret < 0)
+ {
+ if (errno == EINTR)
+ return 0; /* Got a signal, so not an error */
+ pg_log_error("%s() failed: %m", "select");
+ return -1;
+ }
+ if (ret > 0 && FD_ISSET(connsocket, &input_mask))
+ return 1; /* Got input on connection socket */
+
+ return 0; /* Got timeout or input on stop_socket */
+}
+
+/*
+ * Receive CopyData message available from XLOG stream, blocking for
+ * maximum of 'timeout' ms.
+ *
+ * If data was received, returns the length of the data. *buffer is set to
+ * point to a buffer holding the received message. The buffer is only valid
+ * until the next CopyStreamReceive call.
+ *
+ * Returns 0 if no data was available within timeout, or if wait was
+ * interrupted by signal or stop_socket input.
+ * -1 on error. -2 if the server ended the COPY.
+ */
+static int
+CopyStreamReceive(PGconn *conn, long timeout, pgsocket stop_socket,
+ char **buffer)
+{
+ char *copybuf = NULL;
+ int rawlen;
+
+ if (*buffer != NULL)
+ PQfreemem(*buffer);
+ *buffer = NULL;
+
+ /* Try to receive a CopyData message */
+ rawlen = PQgetCopyData(conn, &copybuf, 1);
+ if (rawlen == 0)
+ {
+ int ret;
+
+ /*
+ * No data available. Wait for some to appear, but not longer than
+ * the specified timeout, so that we can ping the server. Also stop
+ * waiting if input appears on stop_socket.
+ */
+ ret = CopyStreamPoll(conn, timeout, stop_socket);
+ if (ret <= 0)
+ return ret;
+
+ /* Now there is actually data on the socket */
+ if (PQconsumeInput(conn) == 0)
+ {
+ pg_log_error("could not receive data from WAL stream: %s",
+ PQerrorMessage(conn));
+ return -1;
+ }
+
+ /* Now that we've consumed some input, try again */
+ rawlen = PQgetCopyData(conn, &copybuf, 1);
+ if (rawlen == 0)
+ return 0;
+ }
+ if (rawlen == -1) /* end-of-streaming or error */
+ return -2;
+ if (rawlen == -2)
+ {
+ pg_log_error("could not read COPY data: %s", PQerrorMessage(conn));
+ return -1;
+ }
+
+ /* Return received messages to caller */
+ *buffer = copybuf;
+ return rawlen;
+}
+
+/*
+ * Process the keepalive message.
+ */
+static bool
+ProcessKeepaliveMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
+ XLogRecPtr blockpos, TimestampTz *last_status)
+{
+ int pos;
+ bool replyRequested;
+ TimestampTz now;
+
+ /*
+ * Parse the keepalive message, enclosed in the CopyData message. We just
+ * check if the server requested a reply, and ignore the rest.
+ */
+ pos = 1; /* skip msgtype 'k' */
+ pos += 8; /* skip walEnd */
+ pos += 8; /* skip sendTime */
+
+ if (len < pos + 1)
+ {
+ pg_log_error("streaming header too small: %d", len);
+ return false;
+ }
+ replyRequested = copybuf[pos];
+
+ /* If the server requested an immediate reply, send one. */
+ if (replyRequested && still_sending)
+ {
+ if (reportFlushPosition && lastFlushPosition < blockpos &&
+ walfile != NULL)
+ {
+ /*
+ * If a valid flush location needs to be reported, flush the
+ * current WAL file so that the latest flush location is sent back
+ * to the server. This is necessary to see whether the last WAL
+ * data has been successfully replicated or not, at the normal
+ * shutdown of the server.
+ */
+ if (stream->walmethod->sync(walfile) != 0)
+ pg_fatal("could not fsync file \"%s\": %s",
+ current_walfile_name, stream->walmethod->getlasterror());
+ lastFlushPosition = blockpos;
+ }
+
+ now = feGetCurrentTimestamp();
+ if (!sendFeedback(conn, blockpos, now, false))
+ return false;
+ *last_status = now;
+ }
+
+ return true;
+}
+
+/*
+ * Process XLogData message.
+ */
+static bool
+ProcessXLogDataMsg(PGconn *conn, StreamCtl *stream, char *copybuf, int len,
+ XLogRecPtr *blockpos)
+{
+ int xlogoff;
+ int bytes_left;
+ int bytes_written;
+ int hdr_len;
+
+ /*
+ * Once we've decided we don't want to receive any more, just ignore any
+ * subsequent XLogData messages.
+ */
+ if (!(still_sending))
+ return true;
+
+ /*
+ * Read the header of the XLogData message, enclosed in the CopyData
+ * message. We only need the WAL location field (dataStart), the rest of
+ * the header is ignored.
+ */
+ hdr_len = 1; /* msgtype 'w' */
+ hdr_len += 8; /* dataStart */
+ hdr_len += 8; /* walEnd */
+ hdr_len += 8; /* sendTime */
+ if (len < hdr_len)
+ {
+ pg_log_error("streaming header too small: %d", len);
+ return false;
+ }
+ *blockpos = fe_recvint64(&copybuf[1]);
+
+ /* Extract WAL location for this block */
+ xlogoff = XLogSegmentOffset(*blockpos, WalSegSz);
+
+ /*
+ * Verify that the initial location in the stream matches where we think
+ * we are.
+ */
+ if (walfile == NULL)
+ {
+ /* No file open yet */
+ if (xlogoff != 0)
+ {
+ pg_log_error("received write-ahead log record for offset %u with no file open",
+ xlogoff);
+ return false;
+ }
+ }
+ else
+ {
+ /* More data in existing segment */
+ if (stream->walmethod->get_current_pos(walfile) != xlogoff)
+ {
+ pg_log_error("got WAL data offset %08x, expected %08x",
+ xlogoff, (int) stream->walmethod->get_current_pos(walfile));
+ return false;
+ }
+ }
+
+ bytes_left = len - hdr_len;
+ bytes_written = 0;
+
+ while (bytes_left)
+ {
+ int bytes_to_write;
+
+ /*
+ * If crossing a WAL boundary, only write up until we reach wal
+ * segment size.
+ */
+ if (xlogoff + bytes_left > WalSegSz)
+ bytes_to_write = WalSegSz - xlogoff;
+ else
+ bytes_to_write = bytes_left;
+
+ if (walfile == NULL)
+ {
+ if (!open_walfile(stream, *blockpos))
+ {
+ /* Error logged by open_walfile */
+ return false;
+ }
+ }
+
+ if (stream->walmethod->write(walfile, copybuf + hdr_len + bytes_written,
+ bytes_to_write) != bytes_to_write)
+ {
+ pg_log_error("could not write %d bytes to WAL file \"%s\": %s",
+ bytes_to_write, current_walfile_name,
+ stream->walmethod->getlasterror());
+ return false;
+ }
+
+ /* Write was successful, advance our position */
+ bytes_written += bytes_to_write;
+ bytes_left -= bytes_to_write;
+ *blockpos += bytes_to_write;
+ xlogoff += bytes_to_write;
+
+ /* Did we reach the end of a WAL segment? */
+ if (XLogSegmentOffset(*blockpos, WalSegSz) == 0)
+ {
+ if (!close_walfile(stream, *blockpos))
+ /* Error message written in close_walfile() */
+ return false;
+
+ xlogoff = 0;
+
+ if (still_sending && stream->stream_stop(*blockpos, stream->timeline, true))
+ {
+ if (PQputCopyEnd(conn, NULL) <= 0 || PQflush(conn))
+ {
+ pg_log_error("could not send copy-end packet: %s",
+ PQerrorMessage(conn));
+ return false;
+ }
+ still_sending = false;
+ return true; /* ignore the rest of this XLogData packet */
+ }
+ }
+ }
+ /* No more data left to write, receive next copy packet */
+
+ return true;
+}
+
+/*
+ * Handle end of the copy stream.
+ */
+static PGresult *
+HandleEndOfCopyStream(PGconn *conn, StreamCtl *stream, char *copybuf,
+ XLogRecPtr blockpos, XLogRecPtr *stoppos)
+{
+ PGresult *res = PQgetResult(conn);
+
+ /*
+ * The server closed its end of the copy stream. If we haven't closed
+ * ours already, we need to do so now, unless the server threw an error,
+ * in which case we don't.
+ */
+ if (still_sending)
+ {
+ if (!close_walfile(stream, blockpos))
+ {
+ /* Error message written in close_walfile() */
+ PQclear(res);
+ return NULL;
+ }
+ if (PQresultStatus(res) == PGRES_COPY_IN)
+ {
+ if (PQputCopyEnd(conn, NULL) <= 0 || PQflush(conn))
+ {
+ pg_log_error("could not send copy-end packet: %s",
+ PQerrorMessage(conn));
+ PQclear(res);
+ return NULL;
+ }
+ res = PQgetResult(conn);
+ }
+ still_sending = false;
+ }
+ if (copybuf != NULL)
+ PQfreemem(copybuf);
+ *stoppos = blockpos;
+ return res;
+}
+
+/*
+ * Check if we should continue streaming, or abort at this point.
+ */
+static bool
+CheckCopyStreamStop(PGconn *conn, StreamCtl *stream, XLogRecPtr blockpos)
+{
+ if (still_sending && stream->stream_stop(blockpos, stream->timeline, false))
+ {
+ if (!close_walfile(stream, blockpos))
+ {
+ /* Potential error message is written by close_walfile */
+ return false;
+ }
+ if (PQputCopyEnd(conn, NULL) <= 0 || PQflush(conn))
+ {
+ pg_log_error("could not send copy-end packet: %s",
+ PQerrorMessage(conn));
+ return false;
+ }
+ still_sending = false;
+ }
+
+ return true;
+}
+
+/*
+ * Calculate how long send/receive loops should sleep
+ */
+static long
+CalculateCopyStreamSleeptime(TimestampTz now, int standby_message_timeout,
+ TimestampTz last_status)
+{
+ TimestampTz status_targettime = 0;
+ long sleeptime;
+
+ if (standby_message_timeout && still_sending)
+ status_targettime = last_status +
+ (standby_message_timeout - 1) * ((int64) 1000);
+
+ if (status_targettime > 0)
+ {
+ long secs;
+ int usecs;
+
+ feTimestampDifference(now,
+ status_targettime,
+ &secs,
+ &usecs);
+ /* Always sleep at least 1 sec */
+ if (secs <= 0)
+ {
+ secs = 1;
+ usecs = 0;
+ }
+
+ sleeptime = secs * 1000 + usecs / 1000;
+ }
+ else
+ sleeptime = -1;
+
+ return sleeptime;
+}
diff --git a/src/bin/pg_basebackup/receivelog.h b/src/bin/pg_basebackup/receivelog.h
new file mode 100644
index 0000000..050d4bc
--- /dev/null
+++ b/src/bin/pg_basebackup/receivelog.h
@@ -0,0 +1,57 @@
+/*-------------------------------------------------------------------------
+ *
+ * receivelog.h
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/receivelog.h
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef RECEIVELOG_H
+#define RECEIVELOG_H
+
+#include "access/xlogdefs.h"
+#include "libpq-fe.h"
+#include "walmethods.h"
+
+/*
+ * Called before trying to read more data or when a segment is
+ * finished. Return true to stop streaming.
+ */
+typedef bool (*stream_stop_callback) (XLogRecPtr segendpos, uint32 timeline, bool segment_finished);
+
+/*
+ * Global parameters when receiving xlog stream. For details about the individual fields,
+ * see the function comment for ReceiveXlogStream().
+ */
+typedef struct StreamCtl
+{
+ XLogRecPtr startpos; /* Start position for streaming */
+ TimeLineID timeline; /* Timeline to stream data from */
+ char *sysidentifier; /* Validate this system identifier and
+ * timeline */
+ int standby_message_timeout; /* Send status messages this often */
+ bool synchronous; /* Flush immediately WAL data on write */
+ bool mark_done; /* Mark segment as done in generated archive */
+ bool do_sync; /* Flush to disk to ensure consistent state of
+ * data */
+
+ stream_stop_callback stream_stop; /* Stop streaming when returns true */
+
+ pgsocket stop_socket; /* if valid, watch for input on this socket
+ * and check stream_stop() when there is any */
+
+ WalWriteMethod *walmethod; /* How to write the WAL */
+ char *partial_suffix; /* Suffix appended to partially received files */
+ char *replication_slot; /* Replication slot to use, or NULL */
+} StreamCtl;
+
+
+
+extern bool CheckServerVersionForStreaming(PGconn *conn);
+extern bool ReceiveXlogStream(PGconn *conn,
+ StreamCtl *stream);
+
+#endif /* RECEIVELOG_H */
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
new file mode 100644
index 0000000..1478aa9
--- /dev/null
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -0,0 +1,864 @@
+/*-------------------------------------------------------------------------
+ *
+ * streamutil.c - utility functions for pg_basebackup, pg_receivewal and
+ * pg_recvlogical
+ *
+ * Author: Magnus Hagander <magnus@hagander.net>
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/streamutil.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <sys/time.h>
+#include <unistd.h>
+
+#include "access/xlog_internal.h"
+#include "common/connect.h"
+#include "common/fe_memutils.h"
+#include "common/file_perm.h"
+#include "common/logging.h"
+#include "common/string.h"
+#include "datatype/timestamp.h"
+#include "port/pg_bswap.h"
+#include "pqexpbuffer.h"
+#include "receivelog.h"
+#include "streamutil.h"
+
+#define ERRCODE_DUPLICATE_OBJECT "42710"
+
+uint32 WalSegSz;
+
+static bool RetrieveDataDirCreatePerm(PGconn *conn);
+
+/* SHOW command for replication connection was introduced in version 10 */
+#define MINIMUM_VERSION_FOR_SHOW_CMD 100000
+
+/*
+ * Group access is supported from version 11.
+ */
+#define MINIMUM_VERSION_FOR_GROUP_ACCESS 110000
+
+const char *progname;
+char *connection_string = NULL;
+char *dbhost = NULL;
+char *dbuser = NULL;
+char *dbport = NULL;
+char *dbname = NULL;
+int dbgetpassword = 0; /* 0=auto, -1=never, 1=always */
+static char *password = NULL;
+PGconn *conn = NULL;
+
+/*
+ * Connect to the server. Returns a valid PGconn pointer if connected,
+ * or NULL on non-permanent error. On permanent error, the function will
+ * call exit(1) directly.
+ */
+PGconn *
+GetConnection(void)
+{
+ PGconn *tmpconn;
+ int argcount = 7; /* dbname, replication, fallback_app_name,
+ * host, user, port, password */
+ int i;
+ const char **keywords;
+ const char **values;
+ const char *tmpparam;
+ bool need_password;
+ PQconninfoOption *conn_opts = NULL;
+ PQconninfoOption *conn_opt;
+ char *err_msg = NULL;
+
+ /* pg_recvlogical uses dbname only; others use connection_string only. */
+ Assert(dbname == NULL || connection_string == NULL);
+
+ /*
+ * Merge the connection info inputs given in form of connection string,
+ * options and default values (dbname=replication, replication=true, etc.)
+ * Explicitly discard any dbname value in the connection string;
+ * otherwise, PQconnectdbParams() would interpret that value as being
+ * itself a connection string.
+ */
+ i = 0;
+ if (connection_string)
+ {
+ conn_opts = PQconninfoParse(connection_string, &err_msg);
+ if (conn_opts == NULL)
+ pg_fatal("%s", err_msg);
+
+ for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
+ {
+ if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
+ strcmp(conn_opt->keyword, "dbname") != 0)
+ argcount++;
+ }
+
+ keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
+ values = pg_malloc0((argcount + 1) * sizeof(*values));
+
+ for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
+ {
+ if (conn_opt->val != NULL && conn_opt->val[0] != '\0' &&
+ strcmp(conn_opt->keyword, "dbname") != 0)
+ {
+ keywords[i] = conn_opt->keyword;
+ values[i] = conn_opt->val;
+ i++;
+ }
+ }
+ }
+ else
+ {
+ keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
+ values = pg_malloc0((argcount + 1) * sizeof(*values));
+ }
+
+ keywords[i] = "dbname";
+ values[i] = dbname == NULL ? "replication" : dbname;
+ i++;
+ keywords[i] = "replication";
+ values[i] = dbname == NULL ? "true" : "database";
+ i++;
+ keywords[i] = "fallback_application_name";
+ values[i] = progname;
+ i++;
+
+ if (dbhost)
+ {
+ keywords[i] = "host";
+ values[i] = dbhost;
+ i++;
+ }
+ if (dbuser)
+ {
+ keywords[i] = "user";
+ values[i] = dbuser;
+ i++;
+ }
+ if (dbport)
+ {
+ keywords[i] = "port";
+ values[i] = dbport;
+ i++;
+ }
+
+ /* If -W was given, force prompt for password, but only the first time */
+ need_password = (dbgetpassword == 1 && !password);
+
+ do
+ {
+ /* Get a new password if appropriate */
+ if (need_password)
+ {
+ if (password)
+ free(password);
+ password = simple_prompt("Password: ", false);
+ need_password = false;
+ }
+
+ /* Use (or reuse, on a subsequent connection) password if we have it */
+ if (password)
+ {
+ keywords[i] = "password";
+ values[i] = password;
+ }
+ else
+ {
+ keywords[i] = NULL;
+ values[i] = NULL;
+ }
+
+ tmpconn = PQconnectdbParams(keywords, values, true);
+
+ /*
+ * If there is too little memory even to allocate the PGconn object
+ * and PQconnectdbParams returns NULL, we call exit(1) directly.
+ */
+ if (!tmpconn)
+ pg_fatal("could not connect to server");
+
+ /* If we need a password and -w wasn't given, loop back and get one */
+ if (PQstatus(tmpconn) == CONNECTION_BAD &&
+ PQconnectionNeedsPassword(tmpconn) &&
+ dbgetpassword != -1)
+ {
+ PQfinish(tmpconn);
+ need_password = true;
+ }
+ }
+ while (need_password);
+
+ if (PQstatus(tmpconn) != CONNECTION_OK)
+ {
+ pg_log_error("%s", PQerrorMessage(tmpconn));
+ PQfinish(tmpconn);
+ free(values);
+ free(keywords);
+ if (conn_opts)
+ PQconninfoFree(conn_opts);
+ return NULL;
+ }
+
+ /* Connection ok! */
+ free(values);
+ free(keywords);
+ if (conn_opts)
+ PQconninfoFree(conn_opts);
+
+ /*
+ * Set always-secure search path, so malicious users can't get control.
+ * The capacity to run normal SQL queries was added in PostgreSQL 10, so
+ * the search path cannot be changed (by us or attackers) on earlier
+ * versions.
+ */
+ if (dbname != NULL && PQserverVersion(tmpconn) >= 100000)
+ {
+ PGresult *res;
+
+ res = PQexec(tmpconn, ALWAYS_SECURE_SEARCH_PATH_SQL);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ pg_log_error("could not clear search_path: %s",
+ PQerrorMessage(tmpconn));
+ PQclear(res);
+ PQfinish(tmpconn);
+ exit(1);
+ }
+ PQclear(res);
+ }
+
+ /*
+ * Ensure we have the same value of integer_datetimes (now always "on") as
+ * the server we are connecting to.
+ */
+ tmpparam = PQparameterStatus(tmpconn, "integer_datetimes");
+ if (!tmpparam)
+ {
+ pg_log_error("could not determine server setting for integer_datetimes");
+ PQfinish(tmpconn);
+ exit(1);
+ }
+
+ if (strcmp(tmpparam, "on") != 0)
+ {
+ pg_log_error("integer_datetimes compile flag does not match server");
+ PQfinish(tmpconn);
+ exit(1);
+ }
+
+ /*
+ * Retrieve the source data directory mode and use it to construct a umask
+ * for creating directories and files.
+ */
+ if (!RetrieveDataDirCreatePerm(tmpconn))
+ {
+ PQfinish(tmpconn);
+ exit(1);
+ }
+
+ return tmpconn;
+}
+
+/*
+ * From version 10, explicitly set wal segment size using SHOW wal_segment_size
+ * since ControlFile is not accessible here.
+ */
+bool
+RetrieveWalSegSize(PGconn *conn)
+{
+ PGresult *res;
+ char xlog_unit[3];
+ int xlog_val,
+ multiplier = 1;
+
+ /* check connection existence */
+ Assert(conn != NULL);
+
+ /* for previous versions set the default xlog seg size */
+ if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_SHOW_CMD)
+ {
+ WalSegSz = DEFAULT_XLOG_SEG_SIZE;
+ return true;
+ }
+
+ res = PQexec(conn, "SHOW wal_segment_size");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ "SHOW wal_segment_size", PQerrorMessage(conn));
+
+ PQclear(res);
+ return false;
+ }
+ if (PQntuples(res) != 1 || PQnfields(res) < 1)
+ {
+ pg_log_error("could not fetch WAL segment size: got %d rows and %d fields, expected %d rows and %d or more fields",
+ PQntuples(res), PQnfields(res), 1, 1);
+
+ PQclear(res);
+ return false;
+ }
+
+ /* fetch xlog value and unit from the result */
+ if (sscanf(PQgetvalue(res, 0, 0), "%d%2s", &xlog_val, xlog_unit) != 2)
+ {
+ pg_log_error("WAL segment size could not be parsed");
+ PQclear(res);
+ return false;
+ }
+
+ PQclear(res);
+
+ /* set the multiplier based on unit to convert xlog_val to bytes */
+ if (strcmp(xlog_unit, "MB") == 0)
+ multiplier = 1024 * 1024;
+ else if (strcmp(xlog_unit, "GB") == 0)
+ multiplier = 1024 * 1024 * 1024;
+
+ /* convert and set WalSegSz */
+ WalSegSz = xlog_val * multiplier;
+
+ if (!IsValidWalSegSize(WalSegSz))
+ {
+ pg_log_error(ngettext("WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d byte",
+ "WAL segment size must be a power of two between 1 MB and 1 GB, but the remote server reported a value of %d bytes",
+ WalSegSz),
+ WalSegSz);
+ return false;
+ }
+
+ return true;
+}
+
+/*
+ * RetrieveDataDirCreatePerm
+ *
+ * This function is used to determine the privileges on the server's PG data
+ * directory and, based on that, set what the permissions will be for
+ * directories and files we create.
+ *
+ * PG11 added support for (optionally) group read/execute rights to be set on
+ * the data directory. Prior to PG11, only the owner was allowed to have rights
+ * on the data directory.
+ */
+static bool
+RetrieveDataDirCreatePerm(PGconn *conn)
+{
+ PGresult *res;
+ int data_directory_mode;
+
+ /* check connection existence */
+ Assert(conn != NULL);
+
+ /* for previous versions leave the default group access */
+ if (PQserverVersion(conn) < MINIMUM_VERSION_FOR_GROUP_ACCESS)
+ return true;
+
+ res = PQexec(conn, "SHOW data_directory_mode");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ "SHOW data_directory_mode", PQerrorMessage(conn));
+
+ PQclear(res);
+ return false;
+ }
+ if (PQntuples(res) != 1 || PQnfields(res) < 1)
+ {
+ pg_log_error("could not fetch group access flag: got %d rows and %d fields, expected %d rows and %d or more fields",
+ PQntuples(res), PQnfields(res), 1, 1);
+
+ PQclear(res);
+ return false;
+ }
+
+ if (sscanf(PQgetvalue(res, 0, 0), "%o", &data_directory_mode) != 1)
+ {
+ pg_log_error("group access flag could not be parsed: %s",
+ PQgetvalue(res, 0, 0));
+
+ PQclear(res);
+ return false;
+ }
+
+ SetDataDirectoryCreatePerm(data_directory_mode);
+
+ PQclear(res);
+ return true;
+}
+
+/*
+ * Run IDENTIFY_SYSTEM through a given connection and give back to caller
+ * some result information if requested:
+ * - System identifier
+ * - Current timeline ID
+ * - Start LSN position
+ * - Database name (NULL in servers prior to 9.4)
+ */
+bool
+RunIdentifySystem(PGconn *conn, char **sysid, TimeLineID *starttli,
+ XLogRecPtr *startpos, char **db_name)
+{
+ PGresult *res;
+ uint32 hi,
+ lo;
+
+ /* Check connection existence */
+ Assert(conn != NULL);
+
+ res = PQexec(conn, "IDENTIFY_SYSTEM");
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ "IDENTIFY_SYSTEM", PQerrorMessage(conn));
+
+ PQclear(res);
+ return false;
+ }
+ if (PQntuples(res) != 1 || PQnfields(res) < 3)
+ {
+ pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields",
+ PQntuples(res), PQnfields(res), 1, 3);
+
+ PQclear(res);
+ return false;
+ }
+
+ /* Get system identifier */
+ if (sysid != NULL)
+ *sysid = pg_strdup(PQgetvalue(res, 0, 0));
+
+ /* Get timeline ID to start streaming from */
+ if (starttli != NULL)
+ *starttli = atoi(PQgetvalue(res, 0, 1));
+
+ /* Get LSN start position if necessary */
+ if (startpos != NULL)
+ {
+ if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &hi, &lo) != 2)
+ {
+ pg_log_error("could not parse write-ahead log location \"%s\"",
+ PQgetvalue(res, 0, 2));
+
+ PQclear(res);
+ return false;
+ }
+ *startpos = ((uint64) hi) << 32 | lo;
+ }
+
+ /* Get database name, only available in 9.4 and newer versions */
+ if (db_name != NULL)
+ {
+ *db_name = NULL;
+ if (PQserverVersion(conn) >= 90400)
+ {
+ if (PQnfields(res) < 4)
+ {
+ pg_log_error("could not identify system: got %d rows and %d fields, expected %d rows and %d or more fields",
+ PQntuples(res), PQnfields(res), 1, 4);
+
+ PQclear(res);
+ return false;
+ }
+ if (!PQgetisnull(res, 0, 3))
+ *db_name = pg_strdup(PQgetvalue(res, 0, 3));
+ }
+ }
+
+ PQclear(res);
+ return true;
+}
+
+/*
+ * Run READ_REPLICATION_SLOT through a given connection and give back to
+ * caller some result information if requested for this slot:
+ * - Start LSN position, InvalidXLogRecPtr if unknown.
+ * - Current timeline ID, 0 if unknown.
+ * Returns false on failure, and true otherwise.
+ */
+bool
+GetSlotInformation(PGconn *conn, const char *slot_name,
+ XLogRecPtr *restart_lsn, TimeLineID *restart_tli)
+{
+ PGresult *res;
+ PQExpBuffer query;
+ XLogRecPtr lsn_loc = InvalidXLogRecPtr;
+ TimeLineID tli_loc = 0;
+
+ if (restart_lsn)
+ *restart_lsn = lsn_loc;
+ if (restart_tli)
+ *restart_tli = tli_loc;
+
+ query = createPQExpBuffer();
+ appendPQExpBuffer(query, "READ_REPLICATION_SLOT %s", slot_name);
+ res = PQexec(conn, query->data);
+ destroyPQExpBuffer(query);
+
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ "READ_REPLICATION_SLOT", PQerrorMessage(conn));
+ PQclear(res);
+ return false;
+ }
+
+ /* The command should always return precisely one tuple and three fields */
+ if (PQntuples(res) != 1 || PQnfields(res) != 3)
+ {
+ pg_log_error("could not read replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
+ slot_name, PQntuples(res), PQnfields(res), 1, 3);
+ PQclear(res);
+ return false;
+ }
+
+ /*
+ * When the slot doesn't exist, the command returns a tuple with NULL
+ * values. This checks only the slot type field.
+ */
+ if (PQgetisnull(res, 0, 0))
+ {
+ pg_log_error("replication slot \"%s\" does not exist", slot_name);
+ PQclear(res);
+ return false;
+ }
+
+ /*
+ * Note that this cannot happen as READ_REPLICATION_SLOT supports only
+ * physical slots, but play it safe.
+ */
+ if (strcmp(PQgetvalue(res, 0, 0), "physical") != 0)
+ {
+ pg_log_error("expected a physical replication slot, got type \"%s\" instead",
+ PQgetvalue(res, 0, 0));
+ PQclear(res);
+ return false;
+ }
+
+ /* restart LSN */
+ if (!PQgetisnull(res, 0, 1))
+ {
+ uint32 hi,
+ lo;
+
+ if (sscanf(PQgetvalue(res, 0, 1), "%X/%X", &hi, &lo) != 2)
+ {
+ pg_log_error("could not parse restart_lsn \"%s\" for replication slot \"%s\"",
+ PQgetvalue(res, 0, 1), slot_name);
+ PQclear(res);
+ return false;
+ }
+ lsn_loc = ((uint64) hi) << 32 | lo;
+ }
+
+ /* current TLI */
+ if (!PQgetisnull(res, 0, 2))
+ tli_loc = (TimeLineID) atol(PQgetvalue(res, 0, 2));
+
+ PQclear(res);
+
+ /* Assign results if requested */
+ if (restart_lsn)
+ *restart_lsn = lsn_loc;
+ if (restart_tli)
+ *restart_tli = tli_loc;
+
+ return true;
+}
+
+/*
+ * Create a replication slot for the given connection. This function
+ * returns true in case of success.
+ */
+bool
+CreateReplicationSlot(PGconn *conn, const char *slot_name, const char *plugin,
+ bool is_temporary, bool is_physical, bool reserve_wal,
+ bool slot_exists_ok, bool two_phase)
+{
+ PQExpBuffer query;
+ PGresult *res;
+ bool use_new_option_syntax = (PQserverVersion(conn) >= 150000);
+
+ query = createPQExpBuffer();
+
+ Assert((is_physical && plugin == NULL) ||
+ (!is_physical && plugin != NULL));
+ Assert(!(two_phase && is_physical));
+ Assert(slot_name != NULL);
+
+ /* Build base portion of query */
+ appendPQExpBuffer(query, "CREATE_REPLICATION_SLOT \"%s\"", slot_name);
+ if (is_temporary)
+ appendPQExpBufferStr(query, " TEMPORARY");
+ if (is_physical)
+ appendPQExpBufferStr(query, " PHYSICAL");
+ else
+ appendPQExpBuffer(query, " LOGICAL \"%s\"", plugin);
+
+ /* Add any requested options */
+ if (use_new_option_syntax)
+ appendPQExpBufferStr(query, " (");
+ if (is_physical)
+ {
+ if (reserve_wal)
+ AppendPlainCommandOption(query, use_new_option_syntax,
+ "RESERVE_WAL");
+ }
+ else
+ {
+ if (two_phase && PQserverVersion(conn) >= 150000)
+ AppendPlainCommandOption(query, use_new_option_syntax,
+ "TWO_PHASE");
+
+ if (PQserverVersion(conn) >= 100000)
+ {
+ /* pg_recvlogical doesn't use an exported snapshot, so suppress */
+ if (use_new_option_syntax)
+ AppendStringCommandOption(query, use_new_option_syntax,
+ "SNAPSHOT", "nothing");
+ else
+ AppendPlainCommandOption(query, use_new_option_syntax,
+ "NOEXPORT_SNAPSHOT");
+ }
+ }
+ if (use_new_option_syntax)
+ {
+ /* Suppress option list if it would be empty, otherwise terminate */
+ if (query->data[query->len - 1] == '(')
+ {
+ query->len -= 2;
+ query->data[query->len] = '\0';
+ }
+ else
+ appendPQExpBufferChar(query, ')');
+ }
+
+ /* Now run the query */
+ res = PQexec(conn, query->data);
+ if (PQresultStatus(res) != PGRES_TUPLES_OK)
+ {
+ const char *sqlstate = PQresultErrorField(res, PG_DIAG_SQLSTATE);
+
+ if (slot_exists_ok &&
+ sqlstate &&
+ strcmp(sqlstate, ERRCODE_DUPLICATE_OBJECT) == 0)
+ {
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return true;
+ }
+ else
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ query->data, PQerrorMessage(conn));
+
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return false;
+ }
+ }
+
+ if (PQntuples(res) != 1 || PQnfields(res) != 4)
+ {
+ pg_log_error("could not create replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
+ slot_name,
+ PQntuples(res), PQnfields(res), 1, 4);
+
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return false;
+ }
+
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return true;
+}
+
+/*
+ * Drop a replication slot for the given connection. This function
+ * returns true in case of success.
+ */
+bool
+DropReplicationSlot(PGconn *conn, const char *slot_name)
+{
+ PQExpBuffer query;
+ PGresult *res;
+
+ Assert(slot_name != NULL);
+
+ query = createPQExpBuffer();
+
+ /* Build query */
+ appendPQExpBuffer(query, "DROP_REPLICATION_SLOT \"%s\"",
+ slot_name);
+ res = PQexec(conn, query->data);
+ if (PQresultStatus(res) != PGRES_COMMAND_OK)
+ {
+ pg_log_error("could not send replication command \"%s\": %s",
+ query->data, PQerrorMessage(conn));
+
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return false;
+ }
+
+ if (PQntuples(res) != 0 || PQnfields(res) != 0)
+ {
+ pg_log_error("could not drop replication slot \"%s\": got %d rows and %d fields, expected %d rows and %d fields",
+ slot_name,
+ PQntuples(res), PQnfields(res), 0, 0);
+
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return false;
+ }
+
+ destroyPQExpBuffer(query);
+ PQclear(res);
+ return true;
+}
+
+/*
+ * Append a "plain" option - one with no value - to a server command that
+ * is being constructed.
+ *
+ * In the old syntax, all options were parser keywords, so you could just
+ * write things like SOME_COMMAND OPTION1 OPTION2 'opt2value' OPTION3 42. The
+ * new syntax uses a comma-separated list surrounded by parentheses, so the
+ * equivalent is SOME_COMMAND (OPTION1, OPTION2 'optvalue', OPTION3 42).
+ */
+void
+AppendPlainCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
+ char *option_name)
+{
+ if (buf->len > 0 && buf->data[buf->len - 1] != '(')
+ {
+ if (use_new_option_syntax)
+ appendPQExpBufferStr(buf, ", ");
+ else
+ appendPQExpBufferChar(buf, ' ');
+ }
+
+ appendPQExpBuffer(buf, " %s", option_name);
+}
+
+/*
+ * Append an option with an associated string value to a server command that
+ * is being constructed.
+ *
+ * See comments for AppendPlainCommandOption, above.
+ */
+void
+AppendStringCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
+ char *option_name, char *option_value)
+{
+ AppendPlainCommandOption(buf, use_new_option_syntax, option_name);
+
+ if (option_value != NULL)
+ {
+ size_t length = strlen(option_value);
+ char *escaped_value = palloc(1 + 2 * length);
+
+ PQescapeStringConn(conn, escaped_value, option_value, length, NULL);
+ appendPQExpBuffer(buf, " '%s'", escaped_value);
+ pfree(escaped_value);
+ }
+}
+
+/*
+ * Append an option with an associated integer value to a server command
+ * is being constructed.
+ *
+ * See comments for AppendPlainCommandOption, above.
+ */
+void
+AppendIntegerCommandOption(PQExpBuffer buf, bool use_new_option_syntax,
+ char *option_name, int32 option_value)
+{
+ AppendPlainCommandOption(buf, use_new_option_syntax, option_name);
+
+ appendPQExpBuffer(buf, " %d", option_value);
+}
+
+/*
+ * Frontend version of GetCurrentTimestamp(), since we are not linked with
+ * backend code.
+ */
+TimestampTz
+feGetCurrentTimestamp(void)
+{
+ TimestampTz result;
+ struct timeval tp;
+
+ gettimeofday(&tp, NULL);
+
+ result = (TimestampTz) tp.tv_sec -
+ ((POSTGRES_EPOCH_JDATE - UNIX_EPOCH_JDATE) * SECS_PER_DAY);
+ result = (result * USECS_PER_SEC) + tp.tv_usec;
+
+ return result;
+}
+
+/*
+ * Frontend version of TimestampDifference(), since we are not linked with
+ * backend code.
+ */
+void
+feTimestampDifference(TimestampTz start_time, TimestampTz stop_time,
+ long *secs, int *microsecs)
+{
+ TimestampTz diff = stop_time - start_time;
+
+ if (diff <= 0)
+ {
+ *secs = 0;
+ *microsecs = 0;
+ }
+ else
+ {
+ *secs = (long) (diff / USECS_PER_SEC);
+ *microsecs = (int) (diff % USECS_PER_SEC);
+ }
+}
+
+/*
+ * Frontend version of TimestampDifferenceExceeds(), since we are not
+ * linked with backend code.
+ */
+bool
+feTimestampDifferenceExceeds(TimestampTz start_time,
+ TimestampTz stop_time,
+ int msec)
+{
+ TimestampTz diff = stop_time - start_time;
+
+ return (diff >= msec * INT64CONST(1000));
+}
+
+/*
+ * Converts an int64 to network byte order.
+ */
+void
+fe_sendint64(int64 i, char *buf)
+{
+ uint64 n64 = pg_hton64(i);
+
+ memcpy(buf, &n64, sizeof(n64));
+}
+
+/*
+ * Converts an int64 from network byte order to native format.
+ */
+int64
+fe_recvint64(char *buf)
+{
+ uint64 n64;
+
+ memcpy(&n64, buf, sizeof(n64));
+
+ return pg_ntoh64(n64);
+}
diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h
new file mode 100644
index 0000000..8638f81
--- /dev/null
+++ b/src/bin/pg_basebackup/streamutil.h
@@ -0,0 +1,68 @@
+/*-------------------------------------------------------------------------
+ *
+ * streamutil.h
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/streamutil.h
+ *-------------------------------------------------------------------------
+ */
+
+#ifndef STREAMUTIL_H
+#define STREAMUTIL_H
+
+#include "access/xlogdefs.h"
+#include "datatype/timestamp.h"
+#include "libpq-fe.h"
+#include "pqexpbuffer.h"
+
+extern const char *progname;
+extern char *connection_string;
+extern char *dbhost;
+extern char *dbuser;
+extern char *dbport;
+extern char *dbname;
+extern int dbgetpassword;
+extern uint32 WalSegSz;
+
+/* Connection kept global so we can disconnect easily */
+extern PGconn *conn;
+
+extern PGconn *GetConnection(void);
+
+/* Replication commands */
+extern bool CreateReplicationSlot(PGconn *conn, const char *slot_name,
+ const char *plugin, bool is_temporary,
+ bool is_physical, bool reserve_wal,
+ bool slot_exists_ok, bool two_phase);
+extern bool DropReplicationSlot(PGconn *conn, const char *slot_name);
+extern bool RunIdentifySystem(PGconn *conn, char **sysid,
+ TimeLineID *starttli,
+ XLogRecPtr *startpos,
+ char **db_name);
+
+extern void AppendPlainCommandOption(PQExpBuffer buf,
+ bool use_new_option_syntax,
+ char *option_value);
+extern void AppendStringCommandOption(PQExpBuffer buf,
+ bool use_new_option_syntax,
+ char *option_name, char *option_value);
+extern void AppendIntegerCommandOption(PQExpBuffer buf,
+ bool use_new_option_syntax,
+ char *option_name, int32 option_value);
+
+extern bool GetSlotInformation(PGconn *conn, const char *slot_name,
+ XLogRecPtr *restart_lsn,
+ TimeLineID *restart_tli);
+extern bool RetrieveWalSegSize(PGconn *conn);
+extern TimestampTz feGetCurrentTimestamp(void);
+extern void feTimestampDifference(TimestampTz start_time, TimestampTz stop_time,
+ long *secs, int *microsecs);
+
+extern bool feTimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time,
+ int msec);
+extern void fe_sendint64(int64 i, char *buf);
+extern int64 fe_recvint64(char *buf);
+
+#endif /* STREAMUTIL_H */
diff --git a/src/bin/pg_basebackup/t/010_pg_basebackup.pl b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
new file mode 100644
index 0000000..ec72282
--- /dev/null
+++ b/src/bin/pg_basebackup/t/010_pg_basebackup.pl
@@ -0,0 +1,945 @@
+
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use File::Basename qw(basename dirname);
+use File::Path qw(rmtree);
+use PostgreSQL::Test::Cluster;
+use PostgreSQL::Test::Utils;
+use Test::More;
+
+program_help_ok('pg_basebackup');
+program_version_ok('pg_basebackup');
+program_options_handling_ok('pg_basebackup');
+
+my $tempdir = PostgreSQL::Test::Utils::tempdir;
+
+my $node = PostgreSQL::Test::Cluster->new('main');
+
+# For nearly all pg_basebackup invocations some options should be specified,
+# to keep test times reasonable. Using @pg_basebackup_defs as the first
+# element of the array passed to IPC::Run interpolate the array (as it is
+# not a reference to an array)...
+my @pg_basebackup_defs = ('pg_basebackup', '--no-sync', '-cfast');
+
+
+# Set umask so test directories and files are created with default permissions
+umask(0077);
+
+# Initialize node without replication settings
+$node->init(
+ extra => ['--data-checksums'],
+ auth_extra => [ '--create-role', 'backupuser' ]);
+$node->start;
+my $pgdata = $node->data_dir;
+
+$node->command_fails(['pg_basebackup'],
+ 'pg_basebackup needs target directory specified');
+
+# Sanity checks for options
+$node->command_fails_like(
+ [ 'pg_basebackup', '-D', "$tempdir/backup", '--compress', 'none:1' ],
+ qr/\Qcompression algorithm "none" does not accept a compression level/,
+ 'failure if method "none" specified with compression level');
+$node->command_fails_like(
+ [ 'pg_basebackup', '-D', "$tempdir/backup", '--compress', 'none+' ],
+ qr/\Qunrecognized compression algorithm: "none+"/,
+ 'failure on incorrect separator to define compression level');
+
+# Some Windows ANSI code pages may reject this filename, in which case we
+# quietly proceed without this bit of test coverage.
+if (open my $badchars, '>>', "$tempdir/pgdata/FOO\xe0\xe0\xe0BAR")
+{
+ print $badchars "test backup of file with non-UTF8 name\n";
+ close $badchars;
+}
+
+$node->set_replication_conf();
+$node->reload;
+
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup" ],
+ 'pg_basebackup fails because of WAL configuration');
+
+ok(!-d "$tempdir/backup", 'backup directory was cleaned up');
+
+# Create a backup directory that is not empty so the next command will fail
+# but leave the data directory behind
+mkdir("$tempdir/backup")
+ or BAIL_OUT("unable to create $tempdir/backup");
+append_to_file("$tempdir/backup/dir-not-empty.txt", "Some data");
+
+$node->command_fails([ @pg_basebackup_defs, '-D', "$tempdir/backup", '-n' ],
+ 'failing run with no-clean option');
+
+ok(-d "$tempdir/backup", 'backup directory was created and left behind');
+rmtree("$tempdir/backup");
+
+open my $conf, '>>', "$pgdata/postgresql.conf";
+print $conf "max_replication_slots = 10\n";
+print $conf "max_wal_senders = 10\n";
+print $conf "wal_level = replica\n";
+close $conf;
+$node->restart;
+
+# Now that we have a server that supports replication commands, test whether
+# certain invalid compression commands fail on the client side with client-side
+# compression and on the server side with server-side compression.
+SKIP:
+{
+ skip "postgres was not built with ZLIB support", 6
+ if (!check_pg_config("#define HAVE_LIBZ 1"));
+
+ my $client_fails = 'pg_basebackup: error: ';
+ my $server_fails =
+ 'pg_basebackup: error: could not initiate base backup: ERROR: ';
+ my @compression_failure_tests = (
+ [
+ 'extrasquishy',
+ 'unrecognized compression algorithm: "extrasquishy"',
+ 'failure on invalid compression algorithm'
+ ],
+ [
+ 'gzip:',
+ 'invalid compression specification: found empty string where a compression option was expected',
+ 'failure on empty compression options list'
+ ],
+ [
+ 'gzip:thunk',
+ 'invalid compression specification: unrecognized compression option: "thunk"',
+ 'failure on unknown compression option'
+ ],
+ [
+ 'gzip:level',
+ 'invalid compression specification: compression option "level" requires a value',
+ 'failure on missing compression level'
+ ],
+ [
+ 'gzip:level=',
+ 'invalid compression specification: value for compression option "level" must be an integer',
+ 'failure on empty compression level'
+ ],
+ [
+ 'gzip:level=high',
+ 'invalid compression specification: value for compression option "level" must be an integer',
+ 'failure on non-numeric compression level'
+ ],
+ [
+ 'gzip:level=236',
+ 'invalid compression specification: compression algorithm "gzip" expects a compression level between 1 and 9',
+ 'failure on out-of-range compression level'
+ ],
+ [
+ 'gzip:level=9,',
+ 'invalid compression specification: found empty string where a compression option was expected',
+ 'failure on extra, empty compression option'
+ ],
+ [
+ 'gzip:workers=3',
+ 'invalid compression specification: compression algorithm "gzip" does not accept a worker count',
+ 'failure on worker count for gzip'
+ ],);
+ for my $cft (@compression_failure_tests)
+ {
+ my $cfail = quotemeta($client_fails . $cft->[1]);
+ my $sfail = quotemeta($server_fails . $cft->[1]);
+ $node->command_fails_like(
+ [
+ 'pg_basebackup', '-D',
+ "$tempdir/backup", '--compress',
+ $cft->[0]
+ ],
+ qr/$cfail/,
+ 'client ' . $cft->[2]);
+ $node->command_fails_like(
+ [
+ 'pg_basebackup', '-D',
+ "$tempdir/backup", '--compress',
+ 'server-' . $cft->[0]
+ ],
+ qr/$sfail/,
+ 'server ' . $cft->[2]);
+ }
+}
+
+# Write some files to test that they are not copied.
+foreach my $filename (
+ qw(backup_label tablespace_map postgresql.auto.conf.tmp
+ current_logfiles.tmp global/pg_internal.init.123))
+{
+ open my $file, '>>', "$pgdata/$filename";
+ print $file "DONOTCOPY";
+ close $file;
+}
+
+# Connect to a database to create global/pg_internal.init. If this is removed
+# the test to ensure global/pg_internal.init is not copied will return a false
+# positive.
+$node->safe_psql('postgres', 'SELECT 1;');
+
+# Create an unlogged table to test that forks other than init are not copied.
+$node->safe_psql('postgres', 'CREATE UNLOGGED TABLE base_unlogged (id int)');
+
+my $baseUnloggedPath = $node->safe_psql('postgres',
+ q{select pg_relation_filepath('base_unlogged')});
+
+# Make sure main and init forks exist
+ok(-f "$pgdata/${baseUnloggedPath}_init", 'unlogged init fork in base');
+ok(-f "$pgdata/$baseUnloggedPath", 'unlogged main fork in base');
+
+# Create files that look like temporary relations to ensure they are ignored.
+my $postgresOid = $node->safe_psql('postgres',
+ q{select oid from pg_database where datname = 'postgres'});
+
+my @tempRelationFiles =
+ qw(t999_999 t9999_999.1 t999_9999_vm t99999_99999_vm.1);
+
+foreach my $filename (@tempRelationFiles)
+{
+ append_to_file("$pgdata/base/$postgresOid/$filename", 'TEMP_RELATION');
+}
+
+# Run base backup.
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup", '-X', 'none' ],
+ 'pg_basebackup runs');
+ok(-f "$tempdir/backup/PG_VERSION", 'backup was created');
+ok(-f "$tempdir/backup/backup_manifest", 'backup manifest included');
+
+# Permissions on backup should be default
+SKIP:
+{
+ skip "unix-style permissions not supported on Windows", 1
+ if ($windows_os);
+
+ ok(check_mode_recursive("$tempdir/backup", 0700, 0600),
+ "check backup dir permissions");
+}
+
+# Only archive_status directory should be copied in pg_wal/.
+is_deeply(
+ [ sort(slurp_dir("$tempdir/backup/pg_wal/")) ],
+ [ sort qw(. .. archive_status) ],
+ 'no WAL files copied');
+
+# Contents of these directories should not be copied.
+foreach my $dirname (
+ qw(pg_dynshmem pg_notify pg_replslot pg_serial pg_snapshots pg_stat_tmp pg_subtrans)
+ )
+{
+ is_deeply(
+ [ sort(slurp_dir("$tempdir/backup/$dirname/")) ],
+ [ sort qw(. ..) ],
+ "contents of $dirname/ not copied");
+}
+
+# These files should not be copied.
+foreach my $filename (
+ qw(postgresql.auto.conf.tmp postmaster.opts postmaster.pid tablespace_map current_logfiles.tmp
+ global/pg_internal.init global/pg_internal.init.123))
+{
+ ok(!-f "$tempdir/backup/$filename", "$filename not copied");
+}
+
+# Unlogged relation forks other than init should not be copied
+ok(-f "$tempdir/backup/${baseUnloggedPath}_init",
+ 'unlogged init fork in backup');
+ok( !-f "$tempdir/backup/$baseUnloggedPath",
+ 'unlogged main fork not in backup');
+
+# Temp relations should not be copied.
+foreach my $filename (@tempRelationFiles)
+{
+ ok( !-f "$tempdir/backup/base/$postgresOid/$filename",
+ "base/$postgresOid/$filename not copied");
+}
+
+# Make sure existing backup_label was ignored.
+isnt(slurp_file("$tempdir/backup/backup_label"),
+ 'DONOTCOPY', 'existing backup_label not copied');
+rmtree("$tempdir/backup");
+
+# Now delete the bogus backup_label file since it will interfere with startup
+unlink("$pgdata/backup_label")
+ or BAIL_OUT("unable to unlink $pgdata/backup_label");
+
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup2", '--no-manifest',
+ '--waldir', "$tempdir/xlog2"
+ ],
+ 'separate xlog directory');
+ok(-f "$tempdir/backup2/PG_VERSION", 'backup was created');
+ok(!-f "$tempdir/backup2/backup_manifest", 'manifest was suppressed');
+ok(-d "$tempdir/xlog2/", 'xlog directory was created');
+rmtree("$tempdir/backup2");
+rmtree("$tempdir/xlog2");
+
+$node->command_ok([ @pg_basebackup_defs, '-D', "$tempdir/tarbackup", '-Ft' ],
+ 'tar format');
+ok(-f "$tempdir/tarbackup/base.tar", 'backup tar was created');
+rmtree("$tempdir/tarbackup");
+
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_foo", '-Fp', "-T=/foo" ],
+ '-T with empty old directory fails');
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=" ],
+ '-T with empty new directory fails');
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D', "$tempdir/backup_foo", '-Fp',
+ "-T/foo=/bar=/baz"
+ ],
+ '-T with multiple = fails');
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo=/bar" ],
+ '-T with old directory not absolute fails');
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_foo", '-Fp', "-T/foo=bar" ],
+ '-T with new directory not absolute fails');
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_foo", '-Fp', "-Tfoo" ],
+ '-T with invalid format fails');
+
+my $superlongname = "superlongname_" . ("x" x 100);
+# Tar format doesn't support filenames longer than 100 bytes.
+SKIP:
+{
+ my $superlongpath = "$pgdata/$superlongname";
+
+ skip "File path too long", 1
+ if $windows_os && length($superlongpath) > 255;
+
+ open my $file, '>', "$superlongpath"
+ or die "unable to create file $superlongpath";
+ close $file;
+ $node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/tarbackup_l1", '-Ft' ],
+ 'pg_basebackup tar with long name fails');
+ unlink "$superlongpath";
+}
+
+# The following tests are for symlinks.
+
+# Move pg_replslot out of $pgdata and create a symlink to it.
+$node->stop;
+
+# Set umask so test directories and files are created with group permissions
+umask(0027);
+
+# Enable group permissions on PGDATA
+chmod_recursive("$pgdata", 0750, 0640);
+
+# Create a temporary directory in the system location.
+my $sys_tempdir = PostgreSQL::Test::Utils::tempdir_short;
+
+# On Windows use the short location to avoid path length issues.
+# Elsewhere use $tempdir to avoid file system boundary issues with moving.
+my $tmploc = $windows_os ? $sys_tempdir : $tempdir;
+
+rename("$pgdata/pg_replslot", "$tmploc/pg_replslot")
+ or BAIL_OUT "could not move $pgdata/pg_replslot";
+dir_symlink("$tmploc/pg_replslot", "$pgdata/pg_replslot")
+ or BAIL_OUT "could not symlink to $pgdata/pg_replslot";
+
+$node->start;
+
+# Test backup of a tablespace using tar format.
+# Symlink the system located tempdir to our physical temp location.
+# That way we can use shorter names for the tablespace directories,
+# which hopefully won't run afoul of the 99 character length limit.
+my $real_sys_tempdir = "$sys_tempdir/tempdir";
+dir_symlink "$tempdir", $real_sys_tempdir;
+
+mkdir "$tempdir/tblspc1";
+my $realTsDir = "$real_sys_tempdir/tblspc1";
+$node->safe_psql('postgres',
+ "CREATE TABLESPACE tblspc1 LOCATION '$realTsDir';");
+$node->safe_psql('postgres',
+ "CREATE TABLE test1 (a int) TABLESPACE tblspc1;"
+ . "INSERT INTO test1 VALUES (1234);");
+$node->backup('tarbackup2', backup_options => ['-Ft']);
+# empty test1, just so that it's different from the to-be-restored data
+$node->safe_psql('postgres', "TRUNCATE TABLE test1;");
+
+# basic checks on the output
+my $backupdir = $node->backup_dir . '/tarbackup2';
+ok(-f "$backupdir/base.tar", 'backup tar was created');
+ok(-f "$backupdir/pg_wal.tar", 'WAL tar was created');
+my @tblspc_tars = glob "$backupdir/[0-9]*.tar";
+is(scalar(@tblspc_tars), 1, 'one tablespace tar was created');
+
+# Try to verify the tar-format backup by restoring it.
+# For this, we use the tar program identified by configure.
+SKIP:
+{
+ my $tar = $ENV{TAR};
+ # don't check for a working tar here, to accommodate various odd
+ # cases such as AIX. If tar doesn't work the init_from_backup below
+ # will fail.
+ skip "no tar program available", 1
+ if (!defined $tar || $tar eq '');
+
+ my $node2 = PostgreSQL::Test::Cluster->new('replica');
+
+ # Recover main data directory
+ $node2->init_from_backup($node, 'tarbackup2', tar_program => $tar);
+
+ # Recover tablespace into a new directory (not where it was!)
+ my $repTsDir = "$tempdir/tblspc1replica";
+ my $realRepTsDir = "$real_sys_tempdir/tblspc1replica";
+ mkdir $repTsDir;
+ PostgreSQL::Test::Utils::system_or_bail($tar, 'xf', $tblspc_tars[0],
+ '-C', $repTsDir);
+
+ # Update tablespace map to point to new directory.
+ # XXX Ideally pg_basebackup would handle this.
+ $tblspc_tars[0] =~ m|/([0-9]*)\.tar$|;
+ my $tblspcoid = $1;
+ my $escapedRepTsDir = $realRepTsDir;
+ $escapedRepTsDir =~ s/\\/\\\\/g;
+ open my $mapfile, '>', $node2->data_dir . '/tablespace_map';
+ print $mapfile "$tblspcoid $escapedRepTsDir\n";
+ close $mapfile;
+
+ $node2->start;
+ my $result = $node2->safe_psql('postgres', 'SELECT * FROM test1');
+ is($result, '1234', "tablespace data restored from tar-format backup");
+ $node2->stop;
+}
+
+# Create an unlogged table to test that forks other than init are not copied.
+$node->safe_psql('postgres',
+ 'CREATE UNLOGGED TABLE tblspc1_unlogged (id int) TABLESPACE tblspc1;');
+
+my $tblspc1UnloggedPath = $node->safe_psql('postgres',
+ q{select pg_relation_filepath('tblspc1_unlogged')});
+
+# Make sure main and init forks exist
+ok( -f "$pgdata/${tblspc1UnloggedPath}_init",
+ 'unlogged init fork in tablespace');
+ok(-f "$pgdata/$tblspc1UnloggedPath", 'unlogged main fork in tablespace');
+
+# Create files that look like temporary relations to ensure they are ignored
+# in a tablespace.
+@tempRelationFiles = qw(t888_888 t888888_888888_vm.1);
+my $tblSpc1Id = basename(
+ dirname(
+ dirname(
+ $node->safe_psql(
+ 'postgres', q{select pg_relation_filepath('test1')}))));
+
+foreach my $filename (@tempRelationFiles)
+{
+ append_to_file(
+ "$real_sys_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename",
+ 'TEMP_RELATION');
+}
+
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup1", '-Fp' ],
+ 'plain format with tablespaces fails without tablespace mapping');
+
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup1", '-Fp',
+ "-T$realTsDir=$tempdir/tbackup/tblspc1",
+ ],
+ 'plain format with tablespaces succeeds with tablespace mapping');
+ok(-d "$tempdir/tbackup/tblspc1", 'tablespace was relocated');
+
+# This symlink check is not supported on Windows as -l
+# doesn't work with junctions
+SKIP:
+{
+ skip "symlink check not implemented on Windows", 1
+ if ($windows_os);
+ opendir(my $dh, "$pgdata/pg_tblspc") or die;
+ ok( ( grep {
+ -l "$tempdir/backup1/pg_tblspc/$_"
+ and readlink "$tempdir/backup1/pg_tblspc/$_" eq
+ "$tempdir/tbackup/tblspc1"
+ } readdir($dh)),
+ "tablespace symlink was updated");
+ closedir $dh;
+}
+
+# Group access should be enabled on all backup files
+SKIP:
+{
+ skip "unix-style permissions not supported on Windows", 1
+ if ($windows_os);
+
+ ok(check_mode_recursive("$tempdir/backup1", 0750, 0640),
+ "check backup dir permissions");
+}
+
+# Unlogged relation forks other than init should not be copied
+my ($tblspc1UnloggedBackupPath) =
+ $tblspc1UnloggedPath =~ /[^\/]*\/[^\/]*\/[^\/]*$/g;
+
+ok(-f "$tempdir/tbackup/tblspc1/${tblspc1UnloggedBackupPath}_init",
+ 'unlogged init fork in tablespace backup');
+ok(!-f "$tempdir/tbackup/tblspc1/$tblspc1UnloggedBackupPath",
+ 'unlogged main fork not in tablespace backup');
+
+# Temp relations should not be copied.
+foreach my $filename (@tempRelationFiles)
+{
+ ok(!-f "$tempdir/tbackup/tblspc1/$tblSpc1Id/$postgresOid/$filename",
+ "[tblspc1]/$postgresOid/$filename not copied");
+
+ # Also remove temp relation files or tablespace drop will fail.
+ my $filepath =
+ "$real_sys_tempdir/tblspc1/$tblSpc1Id/$postgresOid/$filename";
+
+ unlink($filepath)
+ or BAIL_OUT("unable to unlink $filepath");
+}
+
+ok( -d "$tempdir/backup1/pg_replslot",
+ 'pg_replslot symlink copied as directory');
+rmtree("$tempdir/backup1");
+
+mkdir "$tempdir/tbl=spc2";
+$realTsDir = "$real_sys_tempdir/tbl=spc2";
+$node->safe_psql('postgres', "DROP TABLE test1;");
+$node->safe_psql('postgres', "DROP TABLE tblspc1_unlogged;");
+$node->safe_psql('postgres', "DROP TABLESPACE tblspc1;");
+$node->safe_psql('postgres',
+ "CREATE TABLESPACE tblspc2 LOCATION '$realTsDir';");
+$realTsDir =~ s/=/\\=/;
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup3", '-Fp',
+ "-T$realTsDir=$tempdir/tbackup/tbl\\=spc2",
+ ],
+ 'mapping tablespace with = sign in path');
+ok(-d "$tempdir/tbackup/tbl=spc2", 'tablespace with = sign was relocated');
+$node->safe_psql('postgres', "DROP TABLESPACE tblspc2;");
+rmtree("$tempdir/backup3");
+
+mkdir "$tempdir/$superlongname";
+$realTsDir = "$real_sys_tempdir/$superlongname";
+$node->safe_psql('postgres',
+ "CREATE TABLESPACE tblspc3 LOCATION '$realTsDir';");
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/tarbackup_l3", '-Ft' ],
+ 'pg_basebackup tar with long symlink target');
+$node->safe_psql('postgres', "DROP TABLESPACE tblspc3;");
+rmtree("$tempdir/tarbackup_l3");
+
+$node->command_ok([ @pg_basebackup_defs, '-D', "$tempdir/backupR", '-R' ],
+ 'pg_basebackup -R runs');
+ok(-f "$tempdir/backupR/postgresql.auto.conf", 'postgresql.auto.conf exists');
+ok(-f "$tempdir/backupR/standby.signal", 'standby.signal was created');
+my $recovery_conf = slurp_file "$tempdir/backupR/postgresql.auto.conf";
+rmtree("$tempdir/backupR");
+
+my $port = $node->port;
+like(
+ $recovery_conf,
+ qr/^primary_conninfo = '.*port=$port.*'\n/m,
+ 'postgresql.auto.conf sets primary_conninfo');
+
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backupxd" ],
+ 'pg_basebackup runs in default xlog mode');
+ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxd/pg_wal")),
+ 'WAL files copied');
+rmtree("$tempdir/backupxd");
+
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backupxf", '-X', 'fetch' ],
+ 'pg_basebackup -X fetch runs');
+ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxf/pg_wal")),
+ 'WAL files copied');
+rmtree("$tempdir/backupxf");
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backupxs", '-X', 'stream' ],
+ 'pg_basebackup -X stream runs');
+ok(grep(/^[0-9A-F]{24}$/, slurp_dir("$tempdir/backupxs/pg_wal")),
+ 'WAL files copied');
+rmtree("$tempdir/backupxs");
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D', "$tempdir/backupxst", '-X', 'stream',
+ '-Ft'
+ ],
+ 'pg_basebackup -X stream runs in tar mode');
+ok(-f "$tempdir/backupxst/pg_wal.tar", "tar file was created");
+rmtree("$tempdir/backupxst");
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupnoslot", '-X',
+ 'stream', '--no-slot'
+ ],
+ 'pg_basebackup -X stream runs with --no-slot');
+rmtree("$tempdir/backupnoslot");
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backupxf", '-X', 'fetch' ],
+ 'pg_basebackup -X fetch runs');
+
+$node->command_fails_like(
+ [ @pg_basebackup_defs, '--target', 'blackhole' ],
+ qr/WAL cannot be streamed when a backup target is specified/,
+ 'backup target requires -X');
+$node->command_fails_like(
+ [ @pg_basebackup_defs, '--target', 'blackhole', '-X', 'stream' ],
+ qr/WAL cannot be streamed when a backup target is specified/,
+ 'backup target requires -X other than -X stream');
+$node->command_fails_like(
+ [ @pg_basebackup_defs, '--target', 'bogus', '-X', 'none' ],
+ qr/unrecognized target/,
+ 'backup target unrecognized');
+$node->command_fails_like(
+ [
+ @pg_basebackup_defs, '--target', 'blackhole', '-X',
+ 'none', '-D', "$tempdir/blackhole"
+ ],
+ qr/cannot specify both output directory and backup target/,
+ 'backup target and output directory');
+$node->command_fails_like(
+ [ @pg_basebackup_defs, '--target', 'blackhole', '-X', 'none', '-Ft' ],
+ qr/cannot specify both format and backup target/,
+ 'backup target and output directory');
+$node->command_ok(
+ [ @pg_basebackup_defs, '--target', 'blackhole', '-X', 'none' ],
+ 'backup target blackhole');
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '--target',
+ "server:$tempdir/backuponserver", '-X',
+ 'none'
+ ],
+ 'backup target server');
+ok(-f "$tempdir/backuponserver/base.tar", 'backup tar was created');
+rmtree("$tempdir/backuponserver");
+
+$node->command_ok(
+ [qw(createuser --replication --role=pg_write_server_files backupuser)],
+ 'create backup user');
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-U', 'backupuser', '--target',
+ "server:$tempdir/backuponserver",
+ '-X', 'none'
+ ],
+ 'backup target server');
+ok( -f "$tempdir/backuponserver/base.tar",
+ 'backup tar was created as non-superuser');
+rmtree("$tempdir/backuponserver");
+
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupxs_sl_fail", '-X',
+ 'stream', '-S',
+ 'slot0'
+ ],
+ 'pg_basebackup fails with nonexistent replication slot');
+
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot", '-C' ],
+ 'pg_basebackup -C fails without slot name');
+
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupxs_slot", '-C',
+ '-S', 'slot0',
+ '--no-slot'
+ ],
+ 'pg_basebackup fails with -C -S --no-slot');
+$node->command_fails_like(
+ [
+ @pg_basebackup_defs, '--target', 'blackhole', '-D',
+ "$tempdir/blackhole"
+ ],
+ qr/cannot specify both output directory and backup target/,
+ 'backup target and output directory');
+
+$node->command_ok(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backuptr/co", '-X', 'none' ],
+ 'pg_basebackup -X fetch runs');
+
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupxs_sl_fail", '-X',
+ 'stream', '-S',
+ 'slot0'
+ ],
+ 'pg_basebackup fails with nonexistent replication slot');
+
+$node->command_fails(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backupxs_slot", '-C' ],
+ 'pg_basebackup -C fails without slot name');
+
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupxs_slot", '-C',
+ '-S', 'slot0',
+ '--no-slot'
+ ],
+ 'pg_basebackup fails with -C -S --no-slot');
+
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupxs_slot", '-C',
+ '-S', 'slot0'
+ ],
+ 'pg_basebackup -C runs');
+rmtree("$tempdir/backupxs_slot");
+
+is( $node->safe_psql(
+ 'postgres',
+ q{SELECT slot_name FROM pg_replication_slots WHERE slot_name = 'slot0'}
+ ),
+ 'slot0',
+ 'replication slot was created');
+isnt(
+ $node->safe_psql(
+ 'postgres',
+ q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot0'}
+ ),
+ '',
+ 'restart LSN of new slot is not null');
+
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backupxs_slot1", '-C',
+ '-S', 'slot0'
+ ],
+ 'pg_basebackup fails with -C -S and a previously existing slot');
+
+$node->safe_psql('postgres',
+ q{SELECT * FROM pg_create_physical_replication_slot('slot1')});
+my $lsn = $node->safe_psql('postgres',
+ q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}
+);
+is($lsn, '', 'restart LSN of new slot is null');
+$node->command_fails(
+ [
+ @pg_basebackup_defs, '-D', "$tempdir/fail", '-S',
+ 'slot1', '-X', 'none'
+ ],
+ 'pg_basebackup with replication slot fails without WAL streaming');
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D', "$tempdir/backupxs_sl", '-X',
+ 'stream', '-S', 'slot1'
+ ],
+ 'pg_basebackup -X stream with replication slot runs');
+$lsn = $node->safe_psql('postgres',
+ q{SELECT restart_lsn FROM pg_replication_slots WHERE slot_name = 'slot1'}
+);
+like($lsn, qr!^0/[0-9A-Z]{7,8}$!, 'restart LSN of slot has advanced');
+rmtree("$tempdir/backupxs_sl");
+
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D', "$tempdir/backupxs_sl_R", '-X',
+ 'stream', '-S', 'slot1', '-R',
+ ],
+ 'pg_basebackup with replication slot and -R runs');
+like(
+ slurp_file("$tempdir/backupxs_sl_R/postgresql.auto.conf"),
+ qr/^primary_slot_name = 'slot1'\n/m,
+ 'recovery conf file sets primary_slot_name');
+
+my $checksum = $node->safe_psql('postgres', 'SHOW data_checksums;');
+is($checksum, 'on', 'checksums are enabled');
+rmtree("$tempdir/backupxs_sl_R");
+
+# create tables to corrupt and get their relfilenodes
+my $file_corrupt1 = $node->safe_psql('postgres',
+ q{CREATE TABLE corrupt1 AS SELECT a FROM generate_series(1,10000) AS a; ALTER TABLE corrupt1 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt1')}
+);
+my $file_corrupt2 = $node->safe_psql('postgres',
+ q{CREATE TABLE corrupt2 AS SELECT b FROM generate_series(1,2) AS b; ALTER TABLE corrupt2 SET (autovacuum_enabled=false); SELECT pg_relation_filepath('corrupt2')}
+);
+
+# get block size for corruption steps
+my $block_size = $node->safe_psql('postgres', 'SHOW block_size;');
+
+# induce corruption
+$node->stop;
+$node->corrupt_page_checksum($file_corrupt1, 0);
+$node->start;
+
+$node->command_checks_all(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt" ],
+ 1,
+ [qr{^$}],
+ [qr/^WARNING.*checksum verification failed/s],
+ 'pg_basebackup reports checksum mismatch');
+rmtree("$tempdir/backup_corrupt");
+
+# induce further corruption in 5 more blocks
+$node->stop;
+for my $i (1 .. 5)
+{
+ $node->corrupt_page_checksum($file_corrupt1, $i * $block_size);
+}
+$node->start;
+
+$node->command_checks_all(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt2" ],
+ 1,
+ [qr{^$}],
+ [qr/^WARNING.*further.*failures.*will.not.be.reported/s],
+ 'pg_basebackup does not report more than 5 checksum mismatches');
+rmtree("$tempdir/backup_corrupt2");
+
+# induce corruption in a second file
+$node->stop;
+$node->corrupt_page_checksum($file_corrupt2, 0);
+$node->start;
+
+$node->command_checks_all(
+ [ @pg_basebackup_defs, '-D', "$tempdir/backup_corrupt3" ],
+ 1,
+ [qr{^$}],
+ [qr/^WARNING.*7 total checksum verification failures/s],
+ 'pg_basebackup correctly report the total number of checksum mismatches');
+rmtree("$tempdir/backup_corrupt3");
+
+# do not verify checksums, should return ok
+$node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup_corrupt4", '--no-verify-checksums',
+ ],
+ 'pg_basebackup with -k does not report checksum mismatch');
+rmtree("$tempdir/backup_corrupt4");
+
+$node->safe_psql('postgres', "DROP TABLE corrupt1;");
+$node->safe_psql('postgres', "DROP TABLE corrupt2;");
+
+note "Testing pg_basebackup with compression methods";
+
+# Check ZLIB compression if available.
+SKIP:
+{
+ skip "postgres was not built with ZLIB support", 7
+ if (!check_pg_config("#define HAVE_LIBZ 1"));
+
+ $node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup_gzip", '--compress',
+ '1', '--format',
+ 't'
+ ],
+ 'pg_basebackup with --compress');
+ $node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup_gzip2", '--gzip',
+ '--format', 't'
+ ],
+ 'pg_basebackup with --gzip');
+ $node->command_ok(
+ [
+ @pg_basebackup_defs, '-D',
+ "$tempdir/backup_gzip3", '--compress',
+ 'gzip:1', '--format',
+ 't'
+ ],
+ 'pg_basebackup with --compress=gzip:1');
+
+ # Verify that the stored files are generated with their expected
+ # names.
+ my @zlib_files = glob "$tempdir/backup_gzip/*.tar.gz";
+ is(scalar(@zlib_files), 2,
+ "two files created with --compress=NUM (base.tar.gz and pg_wal.tar.gz)"
+ );
+ my @zlib_files2 = glob "$tempdir/backup_gzip2/*.tar.gz";
+ is(scalar(@zlib_files2), 2,
+ "two files created with --gzip (base.tar.gz and pg_wal.tar.gz)");
+ my @zlib_files3 = glob "$tempdir/backup_gzip3/*.tar.gz";
+ is(scalar(@zlib_files3), 2,
+ "two files created with --compress=gzip:NUM (base.tar.gz and pg_wal.tar.gz)"
+ );
+
+ # Check the integrity of the files generated.
+ my $gzip = $ENV{GZIP_PROGRAM};
+ skip "program gzip is not found in your system", 1
+ if (!defined $gzip
+ || $gzip eq '');
+
+ my $gzip_is_valid =
+ system_log($gzip, '--test', @zlib_files, @zlib_files2, @zlib_files3);
+ is($gzip_is_valid, 0, "gzip verified the integrity of compressed data");
+ rmtree("$tempdir/backup_gzip");
+ rmtree("$tempdir/backup_gzip2");
+ rmtree("$tempdir/backup_gzip3");
+}
+
+# Test background stream process terminating before the basebackup has
+# finished, the main process should exit gracefully with an error message on
+# stderr. To reduce the risk of timing related issues we invoke the base
+# backup with rate throttling enabled.
+$node->safe_psql('postgres',
+ q{CREATE TABLE t AS SELECT a FROM generate_series(1,10000) AS a;});
+
+my $sigchld_bb_timeout =
+ IPC::Run::timer($PostgreSQL::Test::Utils::timeout_default);
+my ($sigchld_bb_stdin, $sigchld_bb_stdout, $sigchld_bb_stderr) = ('', '', '');
+my $sigchld_bb = IPC::Run::start(
+ [
+ @pg_basebackup_defs, '--wal-method=stream',
+ '-D', "$tempdir/sigchld",
+ '--max-rate=32', '-d',
+ $node->connstr('postgres')
+ ],
+ '<',
+ \$sigchld_bb_stdin,
+ '>',
+ \$sigchld_bb_stdout,
+ '2>',
+ \$sigchld_bb_stderr,
+ $sigchld_bb_timeout);
+
+is( $node->poll_query_until(
+ 'postgres',
+ "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE "
+ . "application_name = '010_pg_basebackup.pl' AND wait_event = 'WalSenderMain' "
+ . "AND backend_type = 'walsender' AND query ~ 'START_REPLICATION'"),
+ "1",
+ "Walsender killed");
+
+ok( pump_until(
+ $sigchld_bb, $sigchld_bb_timeout,
+ \$sigchld_bb_stderr, qr/background process terminated unexpectedly/),
+ 'background process exit message');
+$sigchld_bb->finish();
+
+# Test that we can back up an in-place tablespace
+$node->safe_psql('postgres',
+ "SET allow_in_place_tablespaces = on; CREATE TABLESPACE tblspc2 LOCATION '';");
+$node->safe_psql('postgres',
+ "CREATE TABLE test2 (a int) TABLESPACE tblspc2;"
+ . "INSERT INTO test2 VALUES (1234);");
+my $tblspc_oid = $node->safe_psql('postgres',
+ "SELECT oid FROM pg_tablespace WHERE spcname = 'tblspc2';");
+$node->backup('backup3');
+$node->safe_psql('postgres', "DROP TABLE test2;");
+$node->safe_psql('postgres', "DROP TABLESPACE tblspc2;");
+
+# check that the in-place tablespace exists in the backup
+$backupdir = $node->backup_dir . '/backup3';
+my @dst_tblspc = glob "$backupdir/pg_tblspc/$tblspc_oid/PG_*";
+is(@dst_tblspc, 1, 'tblspc directory copied');
+
+done_testing();
diff --git a/src/bin/pg_basebackup/t/020_pg_receivewal.pl b/src/bin/pg_basebackup/t/020_pg_receivewal.pl
new file mode 100644
index 0000000..985e68e
--- /dev/null
+++ b/src/bin/pg_basebackup/t/020_pg_receivewal.pl
@@ -0,0 +1,326 @@
+
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Utils;
+use PostgreSQL::Test::Cluster;
+use Test::More;
+
+program_help_ok('pg_receivewal');
+program_version_ok('pg_receivewal');
+program_options_handling_ok('pg_receivewal');
+
+# Set umask so test directories and files are created with default permissions
+umask(0077);
+
+my $primary = PostgreSQL::Test::Cluster->new('primary');
+$primary->init(allows_streaming => 1, extra => ['--wal-segsize=1']);
+$primary->start;
+
+my $stream_dir = $primary->basedir . '/archive_wal';
+mkdir($stream_dir);
+
+# Sanity checks for command line options.
+$primary->command_fails(['pg_receivewal'],
+ 'pg_receivewal needs target directory specified');
+$primary->command_fails(
+ [ 'pg_receivewal', '-D', $stream_dir, '--create-slot', '--drop-slot' ],
+ 'failure if both --create-slot and --drop-slot specified');
+$primary->command_fails(
+ [ 'pg_receivewal', '-D', $stream_dir, '--create-slot' ],
+ 'failure if --create-slot specified without --slot');
+$primary->command_fails(
+ [ 'pg_receivewal', '-D', $stream_dir, '--synchronous', '--no-sync' ],
+ 'failure if --synchronous specified with --no-sync');
+$primary->command_fails_like(
+ [ 'pg_receivewal', '-D', $stream_dir, '--compress', 'none:1', ],
+ qr/\Qpg_receivewal: error: invalid compression specification: compression algorithm "none" does not accept a compression level/,
+ 'failure if --compress none:N (where N > 0)');
+
+# Slot creation and drop
+my $slot_name = 'test';
+$primary->command_ok(
+ [ 'pg_receivewal', '--slot', $slot_name, '--create-slot' ],
+ 'creating a replication slot');
+my $slot = $primary->slot($slot_name);
+is($slot->{'slot_type'}, 'physical', 'physical replication slot was created');
+is($slot->{'restart_lsn'}, '', 'restart LSN of new slot is null');
+$primary->command_ok([ 'pg_receivewal', '--slot', $slot_name, '--drop-slot' ],
+ 'dropping a replication slot');
+is($primary->slot($slot_name)->{'slot_type'},
+ '', 'replication slot was removed');
+
+# Generate some WAL. Use --synchronous at the same time to add more
+# code coverage. Switch to the next segment first so that subsequent
+# restarts of pg_receivewal will see this segment as full..
+$primary->psql('postgres', 'CREATE TABLE test_table(x integer PRIMARY KEY);');
+$primary->psql('postgres', 'SELECT pg_switch_wal();');
+my $nextlsn =
+ $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();');
+chomp($nextlsn);
+$primary->psql('postgres', 'INSERT INTO test_table VALUES (1);');
+
+# Stream up to the given position. This is necessary to have a fixed
+# started point for the next commands done in this test, with or without
+# compression involved.
+$primary->command_ok(
+ [
+ 'pg_receivewal', '-D', $stream_dir, '--verbose',
+ '--endpos', $nextlsn, '--synchronous', '--no-loop'
+ ],
+ 'streaming some WAL with --synchronous');
+
+# Verify that one partial file was generated and keep track of it
+my @partial_wals = glob "$stream_dir/*\.partial";
+is(scalar(@partial_wals), 1, "one partial WAL segment was created");
+
+note "Testing pg_receivewal with compression methods";
+
+# Check ZLIB compression if available.
+SKIP:
+{
+ skip "postgres was not built with ZLIB support", 5
+ if (!check_pg_config("#define HAVE_LIBZ 1"));
+
+ # Generate more WAL worth one completed, compressed, segment.
+ $primary->psql('postgres', 'SELECT pg_switch_wal();');
+ $nextlsn =
+ $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();');
+ chomp($nextlsn);
+ $primary->psql('postgres', 'INSERT INTO test_table VALUES (2);');
+
+ $primary->command_ok(
+ [
+ 'pg_receivewal', '-D', $stream_dir, '--verbose',
+ '--endpos', $nextlsn, '--compress', 'gzip:1',
+ '--no-loop'
+ ],
+ "streaming some WAL using ZLIB compression");
+
+ # Verify that the stored files are generated with their expected
+ # names.
+ my @zlib_wals = glob "$stream_dir/*.gz";
+ is(scalar(@zlib_wals), 1,
+ "one WAL segment compressed with ZLIB was created");
+ my @zlib_partial_wals = glob "$stream_dir/*.gz.partial";
+ is(scalar(@zlib_partial_wals),
+ 1, "one partial WAL segment compressed with ZLIB was created");
+
+ # Verify that the start streaming position is computed correctly by
+ # comparing it with the partial file generated previously. The name
+ # of the previous partial, now-completed WAL segment is updated, keeping
+ # its base number.
+ $partial_wals[0] =~ s/\.partial$/.gz/;
+ is($zlib_wals[0] eq $partial_wals[0],
+ 1, "one partial WAL segment is now completed");
+ # Update the list of partial wals with the current one.
+ @partial_wals = @zlib_partial_wals;
+
+ # Check the integrity of the completed segment, if gzip is a command
+ # available.
+ my $gzip = $ENV{GZIP_PROGRAM};
+ skip "program gzip is not found in your system", 1
+ if (!defined $gzip
+ || $gzip eq '');
+
+ my $gzip_is_valid = system_log($gzip, '--test', @zlib_wals);
+ is($gzip_is_valid, 0,
+ "gzip verified the integrity of compressed WAL segments");
+}
+
+# Check LZ4 compression if available
+SKIP:
+{
+ skip "postgres was not built with LZ4 support", 5
+ if (!check_pg_config("#define USE_LZ4 1"));
+
+ # Generate more WAL including one completed, compressed segment.
+ $primary->psql('postgres', 'SELECT pg_switch_wal();');
+ $nextlsn =
+ $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();');
+ chomp($nextlsn);
+ $primary->psql('postgres', 'INSERT INTO test_table VALUES (3);');
+
+ # Stream up to the given position.
+ $primary->command_ok(
+ [
+ 'pg_receivewal', '-D', $stream_dir, '--verbose',
+ '--endpos', $nextlsn, '--no-loop', '--compress',
+ 'lz4'
+ ],
+ 'streaming some WAL using --compress=lz4');
+
+ # Verify that the stored files are generated with their expected
+ # names.
+ my @lz4_wals = glob "$stream_dir/*.lz4";
+ is(scalar(@lz4_wals), 1,
+ "one WAL segment compressed with LZ4 was created");
+ my @lz4_partial_wals = glob "$stream_dir/*.lz4.partial";
+ is(scalar(@lz4_partial_wals),
+ 1, "one partial WAL segment compressed with LZ4 was created");
+
+ # Verify that the start streaming position is computed correctly by
+ # comparing it with the partial file generated previously. The name
+ # of the previous partial, now-completed WAL segment is updated, keeping
+ # its base number.
+ $partial_wals[0] =~ s/(\.gz)?\.partial$/.lz4/;
+ is($lz4_wals[0] eq $partial_wals[0],
+ 1, "one partial WAL segment is now completed");
+ # Update the list of partial wals with the current one.
+ @partial_wals = @lz4_partial_wals;
+
+ # Check the integrity of the completed segment, if LZ4 is an available
+ # command.
+ my $lz4 = $ENV{LZ4};
+ skip "program lz4 is not found in your system", 1
+ if (!defined $lz4
+ || $lz4 eq '');
+
+ my $lz4_is_valid = system_log($lz4, '-t', @lz4_wals);
+ is($lz4_is_valid, 0,
+ "lz4 verified the integrity of compressed WAL segments");
+}
+
+# Verify that the start streaming position is computed and that the value is
+# correct regardless of whether any compression is available.
+$primary->psql('postgres', 'SELECT pg_switch_wal();');
+$nextlsn =
+ $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();');
+chomp($nextlsn);
+$primary->psql('postgres', 'INSERT INTO test_table VALUES (4);');
+$primary->command_ok(
+ [
+ 'pg_receivewal', '-D', $stream_dir, '--verbose',
+ '--endpos', $nextlsn, '--no-loop'
+ ],
+ "streaming some WAL");
+
+$partial_wals[0] =~ s/(\.gz|\.lz4)?.partial//;
+ok(-e $partial_wals[0], "check that previously partial WAL is now complete");
+
+# Permissions on WAL files should be default
+SKIP:
+{
+ skip "unix-style permissions not supported on Windows", 1
+ if ($windows_os);
+
+ ok(check_mode_recursive($stream_dir, 0700, 0600),
+ "check stream dir permissions");
+}
+
+note "Testing pg_receivewal with slot as starting streaming point";
+
+# When using a replication slot, archiving should be resumed from the slot's
+# restart LSN. Use a new archive location and new slot for this test.
+my $slot_dir = $primary->basedir . '/slot_wal';
+mkdir($slot_dir);
+$slot_name = 'archive_slot';
+
+# Setup the slot, reserving WAL at creation (corresponding to the
+# last redo LSN here, actually, so use a checkpoint to reduce the
+# number of segments archived).
+$primary->psql('postgres', 'checkpoint;');
+$primary->psql('postgres',
+ "SELECT pg_create_physical_replication_slot('$slot_name', true);");
+
+# Get the segment name associated with the slot's restart LSN, that should
+# be archived.
+my $walfile_streamed = $primary->safe_psql(
+ 'postgres',
+ "SELECT pg_walfile_name(restart_lsn)
+ FROM pg_replication_slots
+ WHERE slot_name = '$slot_name';");
+
+# Switch to a new segment, to make sure that the segment retained by the
+# slot is still streamed. This may not be necessary, but play it safe.
+$primary->psql('postgres', 'INSERT INTO test_table VALUES (5);');
+$primary->psql('postgres', 'SELECT pg_switch_wal();');
+$nextlsn =
+ $primary->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();');
+chomp($nextlsn);
+
+# Add a bit more data to accelerate the end of the next pg_receivewal
+# commands.
+$primary->psql('postgres', 'INSERT INTO test_table VALUES (6);');
+
+# Check case where the slot does not exist.
+$primary->command_fails_like(
+ [
+ 'pg_receivewal', '-D', $slot_dir, '--slot',
+ 'nonexistentslot', '-n', '--no-sync', '--verbose',
+ '--endpos', $nextlsn
+ ],
+ qr/pg_receivewal: error: replication slot "nonexistentslot" does not exist/,
+ 'pg_receivewal fails with non-existing slot');
+$primary->command_ok(
+ [
+ 'pg_receivewal', '-D', $slot_dir, '--slot',
+ $slot_name, '-n', '--no-sync', '--verbose',
+ '--endpos', $nextlsn
+ ],
+ "WAL streamed from the slot's restart_lsn");
+ok(-e "$slot_dir/$walfile_streamed",
+ "WAL from the slot's restart_lsn has been archived");
+
+# Test timeline switch using a replication slot, requiring a promoted
+# standby.
+my $backup_name = "basebackup";
+$primary->backup($backup_name);
+my $standby = PostgreSQL::Test::Cluster->new("standby");
+$standby->init_from_backup($primary, $backup_name, has_streaming => 1);
+$standby->start;
+
+# Create a replication slot on this new standby
+my $archive_slot = "archive_slot";
+$standby->psql(
+ '',
+ "CREATE_REPLICATION_SLOT $archive_slot PHYSICAL (RESERVE_WAL)",
+ replication => 1);
+# Wait for standby catchup
+$primary->wait_for_catchup($standby);
+# Get a walfilename from before the promotion to make sure it is archived
+# after promotion
+my $standby_slot = $standby->slot($archive_slot);
+my $replication_slot_lsn = $standby_slot->{'restart_lsn'};
+
+# pg_walfile_name() is not supported while in recovery, so use the primary
+# to build the segment name. Both nodes are on the same timeline, so this
+# produces a segment name with the timeline we are switching from.
+my $walfile_before_promotion =
+ $primary->safe_psql('postgres',
+ "SELECT pg_walfile_name('$replication_slot_lsn');");
+# Everything is setup, promote the standby to trigger a timeline switch.
+$standby->promote;
+
+# Force a segment switch to make sure at least one full WAL is archived
+# on the new timeline.
+my $walfile_after_promotion = $standby->safe_psql('postgres',
+ "SELECT pg_walfile_name(pg_current_wal_insert_lsn());");
+$standby->psql('postgres', 'INSERT INTO test_table VALUES (7);');
+$standby->psql('postgres', 'SELECT pg_switch_wal();');
+$nextlsn =
+ $standby->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn();');
+chomp($nextlsn);
+# This speeds up the operation.
+$standby->psql('postgres', 'INSERT INTO test_table VALUES (8);');
+
+# Now try to resume from the slot after the promotion.
+my $timeline_dir = $primary->basedir . '/timeline_wal';
+mkdir($timeline_dir);
+
+$standby->command_ok(
+ [
+ 'pg_receivewal', '-D', $timeline_dir, '--verbose',
+ '--endpos', $nextlsn, '--slot', $archive_slot,
+ '--no-sync', '-n'
+ ],
+ "Stream some wal after promoting, resuming from the slot's position");
+ok(-e "$timeline_dir/$walfile_before_promotion",
+ "WAL segment $walfile_before_promotion archived after timeline jump");
+ok(-e "$timeline_dir/$walfile_after_promotion",
+ "WAL segment $walfile_after_promotion archived after timeline jump");
+ok(-e "$timeline_dir/00000002.history",
+ "timeline history file archived after timeline jump");
+
+done_testing();
diff --git a/src/bin/pg_basebackup/t/030_pg_recvlogical.pl b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
new file mode 100644
index 0000000..38576c2
--- /dev/null
+++ b/src/bin/pg_basebackup/t/030_pg_recvlogical.pl
@@ -0,0 +1,113 @@
+
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use PostgreSQL::Test::Utils;
+use PostgreSQL::Test::Cluster;
+use Test::More;
+
+program_help_ok('pg_recvlogical');
+program_version_ok('pg_recvlogical');
+program_options_handling_ok('pg_recvlogical');
+
+my $node = PostgreSQL::Test::Cluster->new('main');
+
+# Initialize node without replication settings
+$node->init(allows_streaming => 1, has_archiving => 1);
+$node->append_conf(
+ 'postgresql.conf', q{
+wal_level = 'logical'
+max_replication_slots = 4
+max_wal_senders = 4
+log_min_messages = 'debug1'
+log_error_verbosity = verbose
+max_prepared_transactions = 10
+});
+$node->dump_info;
+$node->start;
+
+$node->command_fails(['pg_recvlogical'], 'pg_recvlogical needs a slot name');
+$node->command_fails([ 'pg_recvlogical', '-S', 'test' ],
+ 'pg_recvlogical needs a database');
+$node->command_fails([ 'pg_recvlogical', '-S', 'test', '-d', 'postgres' ],
+ 'pg_recvlogical needs an action');
+$node->command_fails(
+ [
+ 'pg_recvlogical', '-S',
+ 'test', '-d',
+ $node->connstr('postgres'), '--start'
+ ],
+ 'no destination file');
+
+$node->command_ok(
+ [
+ 'pg_recvlogical', '-S',
+ 'test', '-d',
+ $node->connstr('postgres'), '--create-slot'
+ ],
+ 'slot created');
+
+my $slot = $node->slot('test');
+isnt($slot->{'restart_lsn'}, '', 'restart lsn is defined for new slot');
+
+$node->psql('postgres', 'CREATE TABLE test_table(x integer)');
+$node->psql('postgres',
+ 'INSERT INTO test_table(x) SELECT y FROM generate_series(1, 10) a(y);');
+my $nextlsn =
+ $node->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn()');
+chomp($nextlsn);
+
+$node->command_ok(
+ [
+ 'pg_recvlogical', '-S', 'test', '-d', $node->connstr('postgres'),
+ '--start', '--endpos', "$nextlsn", '--no-loop', '-f', '-'
+ ],
+ 'replayed a transaction');
+
+$node->command_ok(
+ [
+ 'pg_recvlogical', '-S',
+ 'test', '-d',
+ $node->connstr('postgres'), '--drop-slot'
+ ],
+ 'slot dropped');
+
+#test with two-phase option enabled
+$node->command_ok(
+ [
+ 'pg_recvlogical', '-S',
+ 'test', '-d',
+ $node->connstr('postgres'), '--create-slot',
+ '--two-phase'
+ ],
+ 'slot with two-phase created');
+
+$slot = $node->slot('test');
+isnt($slot->{'restart_lsn'}, '', 'restart lsn is defined for new slot');
+
+$node->safe_psql('postgres',
+ "BEGIN; INSERT INTO test_table values (11); PREPARE TRANSACTION 'test'");
+$node->safe_psql('postgres', "COMMIT PREPARED 'test'");
+$nextlsn = $node->safe_psql('postgres', 'SELECT pg_current_wal_insert_lsn()');
+chomp($nextlsn);
+
+$node->command_fails(
+ [
+ 'pg_recvlogical', '-S',
+ 'test', '-d',
+ $node->connstr('postgres'), '--start',
+ '--endpos', "$nextlsn",
+ '--two-phase', '--no-loop',
+ '-f', '-'
+ ],
+ 'incorrect usage');
+
+$node->command_ok(
+ [
+ 'pg_recvlogical', '-S', 'test', '-d', $node->connstr('postgres'),
+ '--start', '--endpos', "$nextlsn", '--no-loop', '-f', '-'
+ ],
+ 'replayed a two-phase transaction');
+
+done_testing();
diff --git a/src/bin/pg_basebackup/walmethods.c b/src/bin/pg_basebackup/walmethods.c
new file mode 100644
index 0000000..602727f
--- /dev/null
+++ b/src/bin/pg_basebackup/walmethods.c
@@ -0,0 +1,1386 @@
+/*-------------------------------------------------------------------------
+ *
+ * walmethods.c - implementations of different ways to write received wal
+ *
+ * NOTE! The caller must ensure that only one method is instantiated in
+ * any given program, and that it's only instantiated once!
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/walmethods.c
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres_fe.h"
+
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifdef USE_LZ4
+#include <lz4frame.h>
+#endif
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
+#include "common/file_perm.h"
+#include "common/file_utils.h"
+#include "common/logging.h"
+#include "pgtar.h"
+#include "receivelog.h"
+#include "streamutil.h"
+
+/* Size of zlib buffer for .tar.gz */
+#define ZLIB_OUT_SIZE 4096
+
+/* Size of LZ4 input chunk for .lz4 */
+#define LZ4_IN_SIZE 4096
+
+/*-------------------------------------------------------------------------
+ * WalDirectoryMethod - write wal to a directory looking like pg_wal
+ *-------------------------------------------------------------------------
+ */
+
+/*
+ * Global static data for this method
+ */
+typedef struct DirectoryMethodData
+{
+ char *basedir;
+ pg_compress_algorithm compression_algorithm;
+ int compression_level;
+ bool sync;
+ const char *lasterrstring; /* if set, takes precedence over lasterrno */
+ int lasterrno;
+} DirectoryMethodData;
+static DirectoryMethodData *dir_data = NULL;
+
+/*
+ * Local file handle
+ */
+typedef struct DirectoryMethodFile
+{
+ int fd;
+ off_t currpos;
+ char *pathname;
+ char *fullpath;
+ char *temp_suffix;
+#ifdef HAVE_LIBZ
+ gzFile gzfp;
+#endif
+#ifdef USE_LZ4
+ LZ4F_compressionContext_t ctx;
+ size_t lz4bufsize;
+ void *lz4buf;
+#endif
+} DirectoryMethodFile;
+
+#define dir_clear_error() \
+ (dir_data->lasterrstring = NULL, dir_data->lasterrno = 0)
+#define dir_set_error(msg) \
+ (dir_data->lasterrstring = _(msg))
+
+static const char *
+dir_getlasterror(void)
+{
+ if (dir_data->lasterrstring)
+ return dir_data->lasterrstring;
+ return strerror(dir_data->lasterrno);
+}
+
+static char *
+dir_get_file_name(const char *pathname, const char *temp_suffix)
+{
+ char *filename = pg_malloc0(MAXPGPATH * sizeof(char));
+
+ snprintf(filename, MAXPGPATH, "%s%s%s",
+ pathname,
+ dir_data->compression_algorithm == PG_COMPRESSION_GZIP ? ".gz" :
+ dir_data->compression_algorithm == PG_COMPRESSION_LZ4 ? ".lz4" : "",
+ temp_suffix ? temp_suffix : "");
+
+ return filename;
+}
+
+static Walfile
+dir_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_size)
+{
+ char tmppath[MAXPGPATH];
+ char *filename;
+ int fd;
+ DirectoryMethodFile *f;
+#ifdef HAVE_LIBZ
+ gzFile gzfp = NULL;
+#endif
+#ifdef USE_LZ4
+ LZ4F_compressionContext_t ctx = NULL;
+ size_t lz4bufsize = 0;
+ void *lz4buf = NULL;
+#endif
+
+ dir_clear_error();
+
+ filename = dir_get_file_name(pathname, temp_suffix);
+ snprintf(tmppath, sizeof(tmppath), "%s/%s",
+ dir_data->basedir, filename);
+ pg_free(filename);
+
+ /*
+ * Open a file for non-compressed as well as compressed files. Tracking
+ * the file descriptor is important for dir_sync() method as gzflush()
+ * does not do any system calls to fsync() to make changes permanent on
+ * disk.
+ */
+ fd = open(tmppath, O_WRONLY | O_CREAT | PG_BINARY, pg_file_create_mode);
+ if (fd < 0)
+ {
+ dir_data->lasterrno = errno;
+ return NULL;
+ }
+
+#ifdef HAVE_LIBZ
+ if (dir_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ gzfp = gzdopen(fd, "wb");
+ if (gzfp == NULL)
+ {
+ dir_data->lasterrno = errno;
+ close(fd);
+ return NULL;
+ }
+
+ if (gzsetparams(gzfp, dir_data->compression_level,
+ Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ dir_data->lasterrno = errno;
+ gzclose(gzfp);
+ return NULL;
+ }
+ }
+#endif
+#ifdef USE_LZ4
+ if (dir_data->compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+ size_t ctx_out;
+ size_t header_size;
+ LZ4F_preferences_t prefs;
+
+ ctx_out = LZ4F_createCompressionContext(&ctx, LZ4F_VERSION);
+ if (LZ4F_isError(ctx_out))
+ {
+ dir_data->lasterrstring = LZ4F_getErrorName(ctx_out);
+ close(fd);
+ return NULL;
+ }
+
+ lz4bufsize = LZ4F_compressBound(LZ4_IN_SIZE, NULL);
+ lz4buf = pg_malloc0(lz4bufsize);
+
+ /* assign the compression level, default is 0 */
+ memset(&prefs, 0, sizeof(prefs));
+ prefs.compressionLevel = dir_data->compression_level;
+
+ /* add the header */
+ header_size = LZ4F_compressBegin(ctx, lz4buf, lz4bufsize, &prefs);
+ if (LZ4F_isError(header_size))
+ {
+ dir_data->lasterrstring = LZ4F_getErrorName(header_size);
+ (void) LZ4F_freeCompressionContext(ctx);
+ pg_free(lz4buf);
+ close(fd);
+ return NULL;
+ }
+
+ errno = 0;
+ if (write(fd, lz4buf, header_size) != header_size)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ (void) LZ4F_freeCompressionContext(ctx);
+ pg_free(lz4buf);
+ close(fd);
+ return NULL;
+ }
+ }
+#endif
+
+ /* Do pre-padding on non-compressed files */
+ if (pad_to_size && dir_data->compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ PGAlignedXLogBlock zerobuf;
+ int bytes;
+
+ memset(zerobuf.data, 0, XLOG_BLCKSZ);
+ for (bytes = 0; bytes < pad_to_size; bytes += XLOG_BLCKSZ)
+ {
+ errno = 0;
+ if (write(fd, zerobuf.data, XLOG_BLCKSZ) != XLOG_BLCKSZ)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ close(fd);
+ return NULL;
+ }
+ }
+
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ {
+ dir_data->lasterrno = errno;
+ close(fd);
+ return NULL;
+ }
+ }
+
+ /*
+ * fsync WAL file and containing directory, to ensure the file is
+ * persistently created and zeroed (if padded). That's particularly
+ * important when using synchronous mode, where the file is modified and
+ * fsynced in-place, without a directory fsync.
+ */
+ if (dir_data->sync)
+ {
+ if (fsync_fname(tmppath, false) != 0 ||
+ fsync_parent_path(tmppath) != 0)
+ {
+ dir_data->lasterrno = errno;
+#ifdef HAVE_LIBZ
+ if (dir_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ gzclose(gzfp);
+ else
+#endif
+#ifdef USE_LZ4
+ if (dir_data->compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+ (void) LZ4F_compressEnd(ctx, lz4buf, lz4bufsize, NULL);
+ (void) LZ4F_freeCompressionContext(ctx);
+ pg_free(lz4buf);
+ close(fd);
+ }
+ else
+#endif
+ close(fd);
+ return NULL;
+ }
+ }
+
+ f = pg_malloc0(sizeof(DirectoryMethodFile));
+#ifdef HAVE_LIBZ
+ if (dir_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ f->gzfp = gzfp;
+#endif
+#ifdef USE_LZ4
+ if (dir_data->compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+ f->ctx = ctx;
+ f->lz4buf = lz4buf;
+ f->lz4bufsize = lz4bufsize;
+ }
+#endif
+
+ f->fd = fd;
+ f->currpos = 0;
+ f->pathname = pg_strdup(pathname);
+ f->fullpath = pg_strdup(tmppath);
+ if (temp_suffix)
+ f->temp_suffix = pg_strdup(temp_suffix);
+
+ return f;
+}
+
+static ssize_t
+dir_write(Walfile f, const void *buf, size_t count)
+{
+ ssize_t r;
+ DirectoryMethodFile *df = (DirectoryMethodFile *) f;
+
+ Assert(f != NULL);
+ dir_clear_error();
+
+#ifdef HAVE_LIBZ
+ if (dir_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ errno = 0;
+ r = (ssize_t) gzwrite(df->gzfp, buf, count);
+ if (r != count)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ }
+ }
+ else
+#endif
+#ifdef USE_LZ4
+ if (dir_data->compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+ size_t chunk;
+ size_t remaining;
+ const void *inbuf = buf;
+
+ remaining = count;
+ while (remaining > 0)
+ {
+ size_t compressed;
+
+ if (remaining > LZ4_IN_SIZE)
+ chunk = LZ4_IN_SIZE;
+ else
+ chunk = remaining;
+
+ remaining -= chunk;
+ compressed = LZ4F_compressUpdate(df->ctx,
+ df->lz4buf, df->lz4bufsize,
+ inbuf, chunk,
+ NULL);
+
+ if (LZ4F_isError(compressed))
+ {
+ dir_data->lasterrstring = LZ4F_getErrorName(compressed);
+ return -1;
+ }
+
+ errno = 0;
+ if (write(df->fd, df->lz4buf, compressed) != compressed)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ return -1;
+ }
+
+ inbuf = ((char *) inbuf) + chunk;
+ }
+
+ /* Our caller keeps track of the uncompressed size. */
+ r = (ssize_t) count;
+ }
+ else
+#endif
+ {
+ errno = 0;
+ r = write(df->fd, buf, count);
+ if (r != count)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ }
+ }
+ if (r > 0)
+ df->currpos += r;
+ return r;
+}
+
+static off_t
+dir_get_current_pos(Walfile f)
+{
+ Assert(f != NULL);
+ dir_clear_error();
+
+ /* Use a cached value to prevent lots of reseeks */
+ return ((DirectoryMethodFile *) f)->currpos;
+}
+
+static int
+dir_close(Walfile f, WalCloseMethod method)
+{
+ int r;
+ DirectoryMethodFile *df = (DirectoryMethodFile *) f;
+ char tmppath[MAXPGPATH];
+ char tmppath2[MAXPGPATH];
+
+ Assert(f != NULL);
+ dir_clear_error();
+
+#ifdef HAVE_LIBZ
+ if (dir_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ errno = 0; /* in case gzclose() doesn't set it */
+ r = gzclose(df->gzfp);
+ }
+ else
+#endif
+#ifdef USE_LZ4
+ if (dir_data->compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+ size_t compressed;
+
+ compressed = LZ4F_compressEnd(df->ctx,
+ df->lz4buf, df->lz4bufsize,
+ NULL);
+
+ if (LZ4F_isError(compressed))
+ {
+ dir_data->lasterrstring = LZ4F_getErrorName(compressed);
+ return -1;
+ }
+
+ errno = 0;
+ if (write(df->fd, df->lz4buf, compressed) != compressed)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ return -1;
+ }
+
+ r = close(df->fd);
+ }
+ else
+#endif
+ r = close(df->fd);
+
+ if (r == 0)
+ {
+ /* Build path to the current version of the file */
+ if (method == CLOSE_NORMAL && df->temp_suffix)
+ {
+ char *filename;
+ char *filename2;
+
+ /*
+ * If we have a temp prefix, normal operation is to rename the
+ * file.
+ */
+ filename = dir_get_file_name(df->pathname, df->temp_suffix);
+ snprintf(tmppath, sizeof(tmppath), "%s/%s",
+ dir_data->basedir, filename);
+ pg_free(filename);
+
+ /* permanent name, so no need for the prefix */
+ filename2 = dir_get_file_name(df->pathname, NULL);
+ snprintf(tmppath2, sizeof(tmppath2), "%s/%s",
+ dir_data->basedir, filename2);
+ pg_free(filename2);
+ if (dir_data->sync)
+ r = durable_rename(tmppath, tmppath2);
+ else
+ {
+ if (rename(tmppath, tmppath2) != 0)
+ {
+ pg_log_error("could not rename file \"%s\" to \"%s\": %m",
+ tmppath, tmppath2);
+ r = -1;
+ }
+ }
+ }
+ else if (method == CLOSE_UNLINK)
+ {
+ char *filename;
+
+ /* Unlink the file once it's closed */
+ filename = dir_get_file_name(df->pathname, df->temp_suffix);
+ snprintf(tmppath, sizeof(tmppath), "%s/%s",
+ dir_data->basedir, filename);
+ pg_free(filename);
+ r = unlink(tmppath);
+ }
+ else
+ {
+ /*
+ * Else either CLOSE_NORMAL and no temp suffix, or
+ * CLOSE_NO_RENAME. In this case, fsync the file and containing
+ * directory if sync mode is requested.
+ */
+ if (dir_data->sync)
+ {
+ r = fsync_fname(df->fullpath, false);
+ if (r == 0)
+ r = fsync_parent_path(df->fullpath);
+ }
+ }
+ }
+
+ if (r != 0)
+ dir_data->lasterrno = errno;
+
+#ifdef USE_LZ4
+ pg_free(df->lz4buf);
+ /* supports free on NULL */
+ LZ4F_freeCompressionContext(df->ctx);
+#endif
+
+ pg_free(df->pathname);
+ pg_free(df->fullpath);
+ if (df->temp_suffix)
+ pg_free(df->temp_suffix);
+ pg_free(df);
+
+ return r;
+}
+
+static int
+dir_sync(Walfile f)
+{
+ int r;
+
+ Assert(f != NULL);
+ dir_clear_error();
+
+ if (!dir_data->sync)
+ return 0;
+
+#ifdef HAVE_LIBZ
+ if (dir_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ if (gzflush(((DirectoryMethodFile *) f)->gzfp, Z_SYNC_FLUSH) != Z_OK)
+ {
+ dir_data->lasterrno = errno;
+ return -1;
+ }
+ }
+#endif
+#ifdef USE_LZ4
+ if (dir_data->compression_algorithm == PG_COMPRESSION_LZ4)
+ {
+ DirectoryMethodFile *df = (DirectoryMethodFile *) f;
+ size_t compressed;
+
+ /* Flush any internal buffers */
+ compressed = LZ4F_flush(df->ctx, df->lz4buf, df->lz4bufsize, NULL);
+ if (LZ4F_isError(compressed))
+ {
+ dir_data->lasterrstring = LZ4F_getErrorName(compressed);
+ return -1;
+ }
+
+ errno = 0;
+ if (write(df->fd, df->lz4buf, compressed) != compressed)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ dir_data->lasterrno = errno ? errno : ENOSPC;
+ return -1;
+ }
+ }
+#endif
+
+ r = fsync(((DirectoryMethodFile *) f)->fd);
+ if (r < 0)
+ dir_data->lasterrno = errno;
+ return r;
+}
+
+static ssize_t
+dir_get_file_size(const char *pathname)
+{
+ struct stat statbuf;
+ char tmppath[MAXPGPATH];
+
+ snprintf(tmppath, sizeof(tmppath), "%s/%s",
+ dir_data->basedir, pathname);
+
+ if (stat(tmppath, &statbuf) != 0)
+ {
+ dir_data->lasterrno = errno;
+ return -1;
+ }
+
+ return statbuf.st_size;
+}
+
+static pg_compress_algorithm
+dir_compression_algorithm(void)
+{
+ return dir_data->compression_algorithm;
+}
+
+static bool
+dir_existsfile(const char *pathname)
+{
+ char tmppath[MAXPGPATH];
+ int fd;
+
+ dir_clear_error();
+
+ snprintf(tmppath, sizeof(tmppath), "%s/%s",
+ dir_data->basedir, pathname);
+
+ fd = open(tmppath, O_RDONLY | PG_BINARY, 0);
+ if (fd < 0)
+ return false;
+ close(fd);
+ return true;
+}
+
+static bool
+dir_finish(void)
+{
+ dir_clear_error();
+
+ if (dir_data->sync)
+ {
+ /*
+ * Files are fsynced when they are closed, but we need to fsync the
+ * directory entry here as well.
+ */
+ if (fsync_fname(dir_data->basedir, true) != 0)
+ {
+ dir_data->lasterrno = errno;
+ return false;
+ }
+ }
+ return true;
+}
+
+
+WalWriteMethod *
+CreateWalDirectoryMethod(const char *basedir,
+ pg_compress_algorithm compression_algorithm,
+ int compression_level, bool sync)
+{
+ WalWriteMethod *method;
+
+ method = pg_malloc0(sizeof(WalWriteMethod));
+ method->open_for_write = dir_open_for_write;
+ method->write = dir_write;
+ method->get_current_pos = dir_get_current_pos;
+ method->get_file_size = dir_get_file_size;
+ method->get_file_name = dir_get_file_name;
+ method->compression_algorithm = dir_compression_algorithm;
+ method->close = dir_close;
+ method->sync = dir_sync;
+ method->existsfile = dir_existsfile;
+ method->finish = dir_finish;
+ method->getlasterror = dir_getlasterror;
+
+ dir_data = pg_malloc0(sizeof(DirectoryMethodData));
+ dir_data->compression_algorithm = compression_algorithm;
+ dir_data->compression_level = compression_level;
+ dir_data->basedir = pg_strdup(basedir);
+ dir_data->sync = sync;
+
+ return method;
+}
+
+void
+FreeWalDirectoryMethod(void)
+{
+ pg_free(dir_data->basedir);
+ pg_free(dir_data);
+ dir_data = NULL;
+}
+
+
+/*-------------------------------------------------------------------------
+ * WalTarMethod - write wal to a tar file containing pg_wal contents
+ *-------------------------------------------------------------------------
+ */
+
+typedef struct TarMethodFile
+{
+ off_t ofs_start; /* Where does the *header* for this file start */
+ off_t currpos;
+ char header[TAR_BLOCK_SIZE];
+ char *pathname;
+ size_t pad_to_size;
+} TarMethodFile;
+
+typedef struct TarMethodData
+{
+ char *tarfilename;
+ int fd;
+ pg_compress_algorithm compression_algorithm;
+ int compression_level;
+ bool sync;
+ TarMethodFile *currentfile;
+ const char *lasterrstring; /* if set, takes precedence over lasterrno */
+ int lasterrno;
+#ifdef HAVE_LIBZ
+ z_streamp zp;
+ void *zlibOut;
+#endif
+} TarMethodData;
+static TarMethodData *tar_data = NULL;
+
+#define tar_clear_error() \
+ (tar_data->lasterrstring = NULL, tar_data->lasterrno = 0)
+#define tar_set_error(msg) \
+ (tar_data->lasterrstring = _(msg))
+
+static const char *
+tar_getlasterror(void)
+{
+ if (tar_data->lasterrstring)
+ return tar_data->lasterrstring;
+ return strerror(tar_data->lasterrno);
+}
+
+#ifdef HAVE_LIBZ
+static bool
+tar_write_compressed_data(void *buf, size_t count, bool flush)
+{
+ tar_data->zp->next_in = buf;
+ tar_data->zp->avail_in = count;
+
+ while (tar_data->zp->avail_in || flush)
+ {
+ int r;
+
+ r = deflate(tar_data->zp, flush ? Z_FINISH : Z_NO_FLUSH);
+ if (r == Z_STREAM_ERROR)
+ {
+ tar_set_error("could not compress data");
+ return false;
+ }
+
+ if (tar_data->zp->avail_out < ZLIB_OUT_SIZE)
+ {
+ size_t len = ZLIB_OUT_SIZE - tar_data->zp->avail_out;
+
+ errno = 0;
+ if (write(tar_data->fd, tar_data->zlibOut, len) != len)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ tar_data->lasterrno = errno ? errno : ENOSPC;
+ return false;
+ }
+
+ tar_data->zp->next_out = tar_data->zlibOut;
+ tar_data->zp->avail_out = ZLIB_OUT_SIZE;
+ }
+
+ if (r == Z_STREAM_END)
+ break;
+ }
+
+ if (flush)
+ {
+ /* Reset the stream for writing */
+ if (deflateReset(tar_data->zp) != Z_OK)
+ {
+ tar_set_error("could not reset compression stream");
+ return false;
+ }
+ }
+
+ return true;
+}
+#endif
+
+static ssize_t
+tar_write(Walfile f, const void *buf, size_t count)
+{
+ ssize_t r;
+
+ Assert(f != NULL);
+ tar_clear_error();
+
+ /* Tarfile will always be positioned at the end */
+ if (tar_data->compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ errno = 0;
+ r = write(tar_data->fd, buf, count);
+ if (r != count)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ tar_data->lasterrno = errno ? errno : ENOSPC;
+ return -1;
+ }
+ ((TarMethodFile *) f)->currpos += r;
+ return r;
+ }
+#ifdef HAVE_LIBZ
+ else if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ if (!tar_write_compressed_data(unconstify(void *, buf), count, false))
+ return -1;
+ ((TarMethodFile *) f)->currpos += count;
+ return count;
+ }
+#endif
+ else
+ {
+ /* Can't happen - compression enabled with no method set */
+ tar_data->lasterrno = ENOSYS;
+ return -1;
+ }
+}
+
+static bool
+tar_write_padding_data(TarMethodFile *f, size_t bytes)
+{
+ PGAlignedXLogBlock zerobuf;
+ size_t bytesleft = bytes;
+
+ memset(zerobuf.data, 0, XLOG_BLCKSZ);
+ while (bytesleft)
+ {
+ size_t bytestowrite = Min(bytesleft, XLOG_BLCKSZ);
+ ssize_t r = tar_write(f, zerobuf.data, bytestowrite);
+
+ if (r < 0)
+ return false;
+ bytesleft -= r;
+ }
+
+ return true;
+}
+
+static char *
+tar_get_file_name(const char *pathname, const char *temp_suffix)
+{
+ char *filename = pg_malloc0(MAXPGPATH * sizeof(char));
+
+ snprintf(filename, MAXPGPATH, "%s%s",
+ pathname, temp_suffix ? temp_suffix : "");
+
+ return filename;
+}
+
+static Walfile
+tar_open_for_write(const char *pathname, const char *temp_suffix, size_t pad_to_size)
+{
+ char *tmppath;
+
+ tar_clear_error();
+
+ if (tar_data->fd < 0)
+ {
+ /*
+ * We open the tar file only when we first try to write to it.
+ */
+ tar_data->fd = open(tar_data->tarfilename,
+ O_WRONLY | O_CREAT | PG_BINARY,
+ pg_file_create_mode);
+ if (tar_data->fd < 0)
+ {
+ tar_data->lasterrno = errno;
+ return NULL;
+ }
+
+#ifdef HAVE_LIBZ
+ if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ tar_data->zp = (z_streamp) pg_malloc(sizeof(z_stream));
+ tar_data->zp->zalloc = Z_NULL;
+ tar_data->zp->zfree = Z_NULL;
+ tar_data->zp->opaque = Z_NULL;
+ tar_data->zp->next_out = tar_data->zlibOut;
+ tar_data->zp->avail_out = ZLIB_OUT_SIZE;
+
+ /*
+ * Initialize deflation library. Adding the magic value 16 to the
+ * default 15 for the windowBits parameter makes the output be
+ * gzip instead of zlib.
+ */
+ if (deflateInit2(tar_data->zp, tar_data->compression_level,
+ Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ pg_free(tar_data->zp);
+ tar_data->zp = NULL;
+ tar_set_error("could not initialize compression library");
+ return NULL;
+ }
+ }
+#endif
+
+ /* There's no tar header itself, the file starts with regular files */
+ }
+
+ if (tar_data->currentfile != NULL)
+ {
+ tar_set_error("implementation error: tar files can't have more than one open file");
+ return NULL;
+ }
+
+ tar_data->currentfile = pg_malloc0(sizeof(TarMethodFile));
+
+ tmppath = tar_get_file_name(pathname, temp_suffix);
+
+ /* Create a header with size set to 0 - we will fill out the size on close */
+ if (tarCreateHeader(tar_data->currentfile->header, tmppath, NULL, 0, S_IRUSR | S_IWUSR, 0, 0, time(NULL)) != TAR_OK)
+ {
+ pg_free(tar_data->currentfile);
+ pg_free(tmppath);
+ tar_data->currentfile = NULL;
+ tar_set_error("could not create tar header");
+ return NULL;
+ }
+
+ pg_free(tmppath);
+
+#ifdef HAVE_LIBZ
+ if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ /* Flush existing data */
+ if (!tar_write_compressed_data(NULL, 0, true))
+ return NULL;
+
+ /* Turn off compression for header */
+ if (deflateParams(tar_data->zp, 0, Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ tar_set_error("could not change compression parameters");
+ return NULL;
+ }
+ }
+#endif
+
+ tar_data->currentfile->ofs_start = lseek(tar_data->fd, 0, SEEK_CUR);
+ if (tar_data->currentfile->ofs_start == -1)
+ {
+ tar_data->lasterrno = errno;
+ pg_free(tar_data->currentfile);
+ tar_data->currentfile = NULL;
+ return NULL;
+ }
+ tar_data->currentfile->currpos = 0;
+
+ if (tar_data->compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ errno = 0;
+ if (write(tar_data->fd, tar_data->currentfile->header,
+ TAR_BLOCK_SIZE) != TAR_BLOCK_SIZE)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ tar_data->lasterrno = errno ? errno : ENOSPC;
+ pg_free(tar_data->currentfile);
+ tar_data->currentfile = NULL;
+ return NULL;
+ }
+ }
+#ifdef HAVE_LIBZ
+ else if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ /* Write header through the zlib APIs but with no compression */
+ if (!tar_write_compressed_data(tar_data->currentfile->header,
+ TAR_BLOCK_SIZE, true))
+ return NULL;
+
+ /* Re-enable compression for the rest of the file */
+ if (deflateParams(tar_data->zp, tar_data->compression_level,
+ Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ tar_set_error("could not change compression parameters");
+ return NULL;
+ }
+ }
+#endif
+ else
+ {
+ /* not reachable */
+ Assert(false);
+ }
+
+ tar_data->currentfile->pathname = pg_strdup(pathname);
+
+ /*
+ * Uncompressed files are padded on creation, but for compression we can't
+ * do that
+ */
+ if (pad_to_size)
+ {
+ tar_data->currentfile->pad_to_size = pad_to_size;
+ if (tar_data->compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ /* Uncompressed, so pad now */
+ if (!tar_write_padding_data(tar_data->currentfile, pad_to_size))
+ return NULL;
+ /* Seek back to start */
+ if (lseek(tar_data->fd,
+ tar_data->currentfile->ofs_start + TAR_BLOCK_SIZE,
+ SEEK_SET) != tar_data->currentfile->ofs_start + TAR_BLOCK_SIZE)
+ {
+ tar_data->lasterrno = errno;
+ return NULL;
+ }
+
+ tar_data->currentfile->currpos = 0;
+ }
+ }
+
+ return tar_data->currentfile;
+}
+
+static ssize_t
+tar_get_file_size(const char *pathname)
+{
+ tar_clear_error();
+
+ /* Currently not used, so not supported */
+ tar_data->lasterrno = ENOSYS;
+ return -1;
+}
+
+static pg_compress_algorithm
+tar_compression_algorithm(void)
+{
+ return tar_data->compression_algorithm;
+}
+
+static off_t
+tar_get_current_pos(Walfile f)
+{
+ Assert(f != NULL);
+ tar_clear_error();
+
+ return ((TarMethodFile *) f)->currpos;
+}
+
+static int
+tar_sync(Walfile f)
+{
+ int r;
+
+ Assert(f != NULL);
+ tar_clear_error();
+
+ if (!tar_data->sync)
+ return 0;
+
+ /*
+ * Always sync the whole tarfile, because that's all we can do. This makes
+ * no sense on compressed files, so just ignore those.
+ */
+ if (tar_data->compression_algorithm != PG_COMPRESSION_NONE)
+ return 0;
+
+ r = fsync(tar_data->fd);
+ if (r < 0)
+ tar_data->lasterrno = errno;
+ return r;
+}
+
+static int
+tar_close(Walfile f, WalCloseMethod method)
+{
+ ssize_t filesize;
+ int padding;
+ TarMethodFile *tf = (TarMethodFile *) f;
+
+ Assert(f != NULL);
+ tar_clear_error();
+
+ if (method == CLOSE_UNLINK)
+ {
+ if (tar_data->compression_algorithm != PG_COMPRESSION_NONE)
+ {
+ tar_set_error("unlink not supported with compression");
+ return -1;
+ }
+
+ /*
+ * Unlink the file that we just wrote to the tar. We do this by
+ * truncating it to the start of the header. This is safe as we only
+ * allow writing of the very last file.
+ */
+ if (ftruncate(tar_data->fd, tf->ofs_start) != 0)
+ {
+ tar_data->lasterrno = errno;
+ return -1;
+ }
+
+ pg_free(tf->pathname);
+ pg_free(tf);
+ tar_data->currentfile = NULL;
+
+ return 0;
+ }
+
+ /*
+ * Pad the file itself with zeroes if necessary. Note that this is
+ * different from the tar format padding -- this is the padding we asked
+ * for when the file was opened.
+ */
+ if (tf->pad_to_size)
+ {
+ if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ /*
+ * A compressed tarfile is padded on close since we cannot know
+ * the size of the compressed output until the end.
+ */
+ size_t sizeleft = tf->pad_to_size - tf->currpos;
+
+ if (sizeleft)
+ {
+ if (!tar_write_padding_data(tf, sizeleft))
+ return -1;
+ }
+ }
+ else
+ {
+ /*
+ * An uncompressed tarfile was padded on creation, so just adjust
+ * the current position as if we seeked to the end.
+ */
+ tf->currpos = tf->pad_to_size;
+ }
+ }
+
+ /*
+ * Get the size of the file, and pad out to a multiple of the tar block
+ * size.
+ */
+ filesize = tar_get_current_pos(f);
+ padding = tarPaddingBytesRequired(filesize);
+ if (padding)
+ {
+ char zerobuf[TAR_BLOCK_SIZE];
+
+ MemSet(zerobuf, 0, padding);
+ if (tar_write(f, zerobuf, padding) != padding)
+ return -1;
+ }
+
+
+#ifdef HAVE_LIBZ
+ if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ /* Flush the current buffer */
+ if (!tar_write_compressed_data(NULL, 0, true))
+ return -1;
+ }
+#endif
+
+ /*
+ * Now go back and update the header with the correct filesize and
+ * possibly also renaming the file. We overwrite the entire current header
+ * when done, including the checksum.
+ */
+ print_tar_number(&(tf->header[124]), 12, filesize);
+
+ if (method == CLOSE_NORMAL)
+
+ /*
+ * We overwrite it with what it was before if we have no tempname,
+ * since we're going to write the buffer anyway.
+ */
+ strlcpy(&(tf->header[0]), tf->pathname, 100);
+
+ print_tar_number(&(tf->header[148]), 8, tarChecksum(((TarMethodFile *) f)->header));
+ if (lseek(tar_data->fd, tf->ofs_start, SEEK_SET) != ((TarMethodFile *) f)->ofs_start)
+ {
+ tar_data->lasterrno = errno;
+ return -1;
+ }
+ if (tar_data->compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ errno = 0;
+ if (write(tar_data->fd, tf->header, TAR_BLOCK_SIZE) != TAR_BLOCK_SIZE)
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ tar_data->lasterrno = errno ? errno : ENOSPC;
+ return -1;
+ }
+ }
+#ifdef HAVE_LIBZ
+ else if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ /* Turn off compression */
+ if (deflateParams(tar_data->zp, 0, Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ tar_set_error("could not change compression parameters");
+ return -1;
+ }
+
+ /* Overwrite the header, assuming the size will be the same */
+ if (!tar_write_compressed_data(tar_data->currentfile->header,
+ TAR_BLOCK_SIZE, true))
+ return -1;
+
+ /* Turn compression back on */
+ if (deflateParams(tar_data->zp, tar_data->compression_level,
+ Z_DEFAULT_STRATEGY) != Z_OK)
+ {
+ tar_set_error("could not change compression parameters");
+ return -1;
+ }
+ }
+#endif
+ else
+ {
+ /* not reachable */
+ Assert(false);
+ }
+
+ /* Move file pointer back down to end, so we can write the next file */
+ if (lseek(tar_data->fd, 0, SEEK_END) < 0)
+ {
+ tar_data->lasterrno = errno;
+ return -1;
+ }
+
+ /* Always fsync on close, so the padding gets fsynced */
+ if (tar_sync(f) < 0)
+ {
+ /* XXX this seems pretty bogus; why is only this case fatal? */
+ pg_fatal("could not fsync file \"%s\": %s",
+ tf->pathname, tar_getlasterror());
+ }
+
+ /* Clean up and done */
+ pg_free(tf->pathname);
+ pg_free(tf);
+ tar_data->currentfile = NULL;
+
+ return 0;
+}
+
+static bool
+tar_existsfile(const char *pathname)
+{
+ tar_clear_error();
+ /* We only deal with new tarfiles, so nothing externally created exists */
+ return false;
+}
+
+static bool
+tar_finish(void)
+{
+ char zerobuf[1024];
+
+ tar_clear_error();
+
+ if (tar_data->currentfile)
+ {
+ if (tar_close(tar_data->currentfile, CLOSE_NORMAL) != 0)
+ return false;
+ }
+
+ /* A tarfile always ends with two empty blocks */
+ MemSet(zerobuf, 0, sizeof(zerobuf));
+ if (tar_data->compression_algorithm == PG_COMPRESSION_NONE)
+ {
+ errno = 0;
+ if (write(tar_data->fd, zerobuf, sizeof(zerobuf)) != sizeof(zerobuf))
+ {
+ /* If write didn't set errno, assume problem is no disk space */
+ tar_data->lasterrno = errno ? errno : ENOSPC;
+ return false;
+ }
+ }
+#ifdef HAVE_LIBZ
+ else if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ {
+ if (!tar_write_compressed_data(zerobuf, sizeof(zerobuf), false))
+ return false;
+
+ /* Also flush all data to make sure the gzip stream is finished */
+ tar_data->zp->next_in = NULL;
+ tar_data->zp->avail_in = 0;
+ while (true)
+ {
+ int r;
+
+ r = deflate(tar_data->zp, Z_FINISH);
+
+ if (r == Z_STREAM_ERROR)
+ {
+ tar_set_error("could not compress data");
+ return false;
+ }
+ if (tar_data->zp->avail_out < ZLIB_OUT_SIZE)
+ {
+ size_t len = ZLIB_OUT_SIZE - tar_data->zp->avail_out;
+
+ errno = 0;
+ if (write(tar_data->fd, tar_data->zlibOut, len) != len)
+ {
+ /*
+ * If write didn't set errno, assume problem is no disk
+ * space.
+ */
+ tar_data->lasterrno = errno ? errno : ENOSPC;
+ return false;
+ }
+ }
+ if (r == Z_STREAM_END)
+ break;
+ }
+
+ if (deflateEnd(tar_data->zp) != Z_OK)
+ {
+ tar_set_error("could not close compression stream");
+ return false;
+ }
+ }
+#endif
+ else
+ {
+ /* not reachable */
+ Assert(false);
+ }
+
+ /* sync the empty blocks as well, since they're after the last file */
+ if (tar_data->sync)
+ {
+ if (fsync(tar_data->fd) != 0)
+ {
+ tar_data->lasterrno = errno;
+ return false;
+ }
+ }
+
+ if (close(tar_data->fd) != 0)
+ {
+ tar_data->lasterrno = errno;
+ return false;
+ }
+
+ tar_data->fd = -1;
+
+ if (tar_data->sync)
+ {
+ if (fsync_fname(tar_data->tarfilename, false) != 0 ||
+ fsync_parent_path(tar_data->tarfilename) != 0)
+ {
+ tar_data->lasterrno = errno;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/*
+ * The argument compression_algorithm is currently ignored. It is in place for
+ * symmetry with CreateWalDirectoryMethod which uses it for distinguishing
+ * between the different compression methods. CreateWalTarMethod and its family
+ * of functions handle only zlib compression.
+ */
+WalWriteMethod *
+CreateWalTarMethod(const char *tarbase,
+ pg_compress_algorithm compression_algorithm,
+ int compression_level, bool sync)
+{
+ WalWriteMethod *method;
+ const char *suffix = (compression_algorithm == PG_COMPRESSION_GZIP) ?
+ ".tar.gz" : ".tar";
+
+ method = pg_malloc0(sizeof(WalWriteMethod));
+ method->open_for_write = tar_open_for_write;
+ method->write = tar_write;
+ method->get_current_pos = tar_get_current_pos;
+ method->get_file_size = tar_get_file_size;
+ method->get_file_name = tar_get_file_name;
+ method->compression_algorithm = tar_compression_algorithm;
+ method->close = tar_close;
+ method->sync = tar_sync;
+ method->existsfile = tar_existsfile;
+ method->finish = tar_finish;
+ method->getlasterror = tar_getlasterror;
+
+ tar_data = pg_malloc0(sizeof(TarMethodData));
+ tar_data->tarfilename = pg_malloc0(strlen(tarbase) + strlen(suffix) + 1);
+ sprintf(tar_data->tarfilename, "%s%s", tarbase, suffix);
+ tar_data->fd = -1;
+ tar_data->compression_algorithm = compression_algorithm;
+ tar_data->compression_level = compression_level;
+ tar_data->sync = sync;
+#ifdef HAVE_LIBZ
+ if (compression_algorithm == PG_COMPRESSION_GZIP)
+ tar_data->zlibOut = (char *) pg_malloc(ZLIB_OUT_SIZE + 1);
+#endif
+
+ return method;
+}
+
+void
+FreeWalTarMethod(void)
+{
+ pg_free(tar_data->tarfilename);
+#ifdef HAVE_LIBZ
+ if (tar_data->compression_algorithm == PG_COMPRESSION_GZIP)
+ pg_free(tar_data->zlibOut);
+#endif
+ pg_free(tar_data);
+ tar_data = NULL;
+}
diff --git a/src/bin/pg_basebackup/walmethods.h b/src/bin/pg_basebackup/walmethods.h
new file mode 100644
index 0000000..76530dc
--- /dev/null
+++ b/src/bin/pg_basebackup/walmethods.h
@@ -0,0 +1,107 @@
+/*-------------------------------------------------------------------------
+ *
+ * walmethods.h
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ * src/bin/pg_basebackup/walmethods.h
+ *-------------------------------------------------------------------------
+ */
+
+#include "common/compression.h"
+
+typedef void *Walfile;
+
+typedef enum
+{
+ CLOSE_NORMAL,
+ CLOSE_UNLINK,
+ CLOSE_NO_RENAME
+} WalCloseMethod;
+
+/*
+ * A WalWriteMethod structure represents the different methods used
+ * to write the streaming WAL as it's received.
+ *
+ * All methods that have a failure return indicator will set state
+ * allowing the getlasterror() method to return a suitable message.
+ * Commonly, errno is this state (or part of it); so callers must take
+ * care not to clobber errno between a failed method call and use of
+ * getlasterror() to retrieve the message.
+ */
+typedef struct WalWriteMethod WalWriteMethod;
+struct WalWriteMethod
+{
+ /*
+ * Open a target file. Returns Walfile, or NULL if open failed. If a temp
+ * suffix is specified, a file with that name will be opened, and then
+ * automatically renamed in close(). If pad_to_size is specified, the file
+ * will be padded with NUL up to that size, if supported by the Walmethod.
+ */
+ Walfile (*open_for_write) (const char *pathname, const char *temp_suffix, size_t pad_to_size);
+
+ /*
+ * Close an open Walfile, using one or more methods for handling automatic
+ * unlinking etc. Returns 0 on success, other values for error.
+ */
+ int (*close) (Walfile f, WalCloseMethod method);
+
+ /* Check if a file exist */
+ bool (*existsfile) (const char *pathname);
+
+ /* Return the size of a file, or -1 on failure. */
+ ssize_t (*get_file_size) (const char *pathname);
+
+ /*
+ * Return the name of the current file to work on in pg_malloc()'d string,
+ * without the base directory. This is useful for logging.
+ */
+ char *(*get_file_name) (const char *pathname, const char *temp_suffix);
+
+ /* Returns the compression method */
+ pg_compress_algorithm (*compression_algorithm) (void);
+
+ /*
+ * Write count number of bytes to the file, and return the number of bytes
+ * actually written or -1 for error.
+ */
+ ssize_t (*write) (Walfile f, const void *buf, size_t count);
+
+ /* Return the current position in a file or -1 on error */
+ off_t (*get_current_pos) (Walfile f);
+
+ /*
+ * fsync the contents of the specified file. Returns 0 on success.
+ */
+ int (*sync) (Walfile f);
+
+ /*
+ * Clean up the Walmethod, closing any shared resources. For methods like
+ * tar, this includes writing updated headers. Returns true if the
+ * close/write/sync of shared resources succeeded, otherwise returns false
+ * (but the resources are still closed).
+ */
+ bool (*finish) (void);
+
+ /* Return a text for the last error in this Walfile */
+ const char *(*getlasterror) (void);
+};
+
+/*
+ * Available WAL methods:
+ * - WalDirectoryMethod - write WAL to regular files in a standard pg_wal
+ * - WalTarMethod - write WAL to a tarfile corresponding to pg_wal
+ * (only implements the methods required for pg_basebackup,
+ * not all those required for pg_receivewal)
+ */
+WalWriteMethod *CreateWalDirectoryMethod(const char *basedir,
+ pg_compress_algorithm compression_algo,
+ int compression, bool sync);
+WalWriteMethod *CreateWalTarMethod(const char *tarbase,
+ pg_compress_algorithm compression_algo,
+ int compression, bool sync);
+
+/* Cleanup routines for previously-created methods */
+void FreeWalDirectoryMethod(void);
+void FreeWalTarMethod(void);