summaryrefslogtreecommitdiffstats
path: root/src/bin/pg_archivecleanup
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:15:05 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:15:05 +0000
commit46651ce6fe013220ed397add242004d764fc0153 (patch)
tree6e5299f990f88e60174a1d3ae6e48eedd2688b2b /src/bin/pg_archivecleanup
parentInitial commit. (diff)
downloadpostgresql-14-46651ce6fe013220ed397add242004d764fc0153.tar.xz
postgresql-14-46651ce6fe013220ed397add242004d764fc0153.zip
Adding upstream version 14.5.upstream/14.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bin/pg_archivecleanup')
-rw-r--r--src/bin/pg_archivecleanup/.gitignore3
-rw-r--r--src/bin/pg_archivecleanup/Makefile36
-rw-r--r--src/bin/pg_archivecleanup/nls.mk6
-rw-r--r--src/bin/pg_archivecleanup/pg_archivecleanup.c378
-rw-r--r--src/bin/pg_archivecleanup/po/cs.po198
-rw-r--r--src/bin/pg_archivecleanup/po/de.po178
-rw-r--r--src/bin/pg_archivecleanup/po/el.po181
-rw-r--r--src/bin/pg_archivecleanup/po/es.po180
-rw-r--r--src/bin/pg_archivecleanup/po/fr.po201
-rw-r--r--src/bin/pg_archivecleanup/po/ja.po178
-rw-r--r--src/bin/pg_archivecleanup/po/ko.po184
-rw-r--r--src/bin/pg_archivecleanup/po/ru.po204
-rw-r--r--src/bin/pg_archivecleanup/po/sv.po179
-rw-r--r--src/bin/pg_archivecleanup/po/tr.po185
-rw-r--r--src/bin/pg_archivecleanup/po/uk.po168
-rw-r--r--src/bin/pg_archivecleanup/po/zh_CN.po179
-rw-r--r--src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl103
17 files changed, 2741 insertions, 0 deletions
diff --git a/src/bin/pg_archivecleanup/.gitignore b/src/bin/pg_archivecleanup/.gitignore
new file mode 100644
index 0000000..bd05d00
--- /dev/null
+++ b/src/bin/pg_archivecleanup/.gitignore
@@ -0,0 +1,3 @@
+/pg_archivecleanup
+
+/tmp_check/
diff --git a/src/bin/pg_archivecleanup/Makefile b/src/bin/pg_archivecleanup/Makefile
new file mode 100644
index 0000000..49935d6
--- /dev/null
+++ b/src/bin/pg_archivecleanup/Makefile
@@ -0,0 +1,36 @@
+# src/bin/pg_archivecleanup/Makefile
+
+PGFILEDESC = "pg_archivecleanup - cleans archive when used with streaming replication"
+PGAPPICON = win32
+
+subdir = src/bin/pg_archivecleanup
+top_builddir = ../../..
+include $(top_builddir)/src/Makefile.global
+
+OBJS = \
+ $(WIN32RES) \
+ pg_archivecleanup.o
+
+all: pg_archivecleanup
+
+pg_archivecleanup: $(OBJS) | submake-libpgport
+ $(CC) $(CFLAGS) $^ $(LDFLAGS) $(LDFLAGS_EX) $(LIBS) -o $@$(X)
+
+install: all installdirs
+ $(INSTALL_PROGRAM) pg_archivecleanup$(X) '$(DESTDIR)$(bindir)/pg_archivecleanup$(X)'
+
+installdirs:
+ $(MKDIR_P) '$(DESTDIR)$(bindir)'
+
+uninstall:
+ rm -f '$(DESTDIR)$(bindir)/pg_archivecleanup$(X)'
+
+clean distclean maintainer-clean:
+ rm -f pg_archivecleanup$(X) $(OBJS)
+ rm -rf tmp_check
+
+check:
+ $(prove_check)
+
+installcheck:
+ $(prove_installcheck)
diff --git a/src/bin/pg_archivecleanup/nls.mk b/src/bin/pg_archivecleanup/nls.mk
new file mode 100644
index 0000000..6150ac4
--- /dev/null
+++ b/src/bin/pg_archivecleanup/nls.mk
@@ -0,0 +1,6 @@
+# src/bin/pg_archivecleanup/nls.mk
+CATALOG_NAME = pg_archivecleanup
+AVAIL_LANGUAGES = cs de el es fr ja ko ru sv tr uk zh_CN
+GETTEXT_FILES = $(FRONTEND_COMMON_GETTEXT_FILES) pg_archivecleanup.c
+GETTEXT_TRIGGERS = $(FRONTEND_COMMON_GETTEXT_TRIGGERS)
+GETTEXT_FLAGS = $(FRONTEND_COMMON_GETTEXT_FLAGS)
diff --git a/src/bin/pg_archivecleanup/pg_archivecleanup.c b/src/bin/pg_archivecleanup/pg_archivecleanup.c
new file mode 100644
index 0000000..12338e3
--- /dev/null
+++ b/src/bin/pg_archivecleanup/pg_archivecleanup.c
@@ -0,0 +1,378 @@
+/*
+ * pg_archivecleanup.c
+ *
+ * To be used as archive_cleanup_command to clean an archive when using
+ * standby mode.
+ *
+ * src/bin/pg_archivecleanup/pg_archivecleanup.c
+ */
+#include "postgres_fe.h"
+
+#include <ctype.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/time.h>
+
+#include "access/xlog_internal.h"
+#include "common/logging.h"
+#include "pg_getopt.h"
+
+const char *progname;
+
+/* Options and defaults */
+bool dryrun = false; /* are we performing a dry-run operation? */
+char *additional_ext = NULL; /* Extension to remove from filenames */
+
+char *archiveLocation; /* where to find the archive? */
+char *restartWALFileName; /* the file from which we can restart restore */
+char exclusiveCleanupFileName[MAXFNAMELEN]; /* the oldest file we want
+ * to remain in archive */
+
+
+/* =====================================================================
+ *
+ * Customizable section
+ *
+ * =====================================================================
+ *
+ * Currently, this section assumes that the Archive is a locally
+ * accessible directory. If you want to make other assumptions,
+ * such as using a vendor-specific archive and access API, these
+ * routines are the ones you'll need to change. You're
+ * encouraged to submit any changes to pgsql-hackers@lists.postgresql.org
+ * or personally to the current maintainer. Those changes may be
+ * folded in to later versions of this program.
+ */
+
+/*
+ * Initialize allows customized commands into the archive cleanup program.
+ *
+ * You may wish to add code to check for tape libraries, etc..
+ */
+static void
+Initialize(void)
+{
+ /*
+ * This code assumes that archiveLocation is a directory, so we use stat
+ * to test if it's accessible.
+ */
+ struct stat stat_buf;
+
+ if (stat(archiveLocation, &stat_buf) != 0 ||
+ !S_ISDIR(stat_buf.st_mode))
+ {
+ pg_log_error("archive location \"%s\" does not exist",
+ archiveLocation);
+ exit(2);
+ }
+}
+
+static void
+TrimExtension(char *filename, char *extension)
+{
+ int flen;
+ int elen;
+
+ if (extension == NULL)
+ return;
+
+ elen = strlen(extension);
+ flen = strlen(filename);
+
+ if (flen > elen && strcmp(filename + flen - elen, extension) == 0)
+ filename[flen - elen] = '\0';
+}
+
+static void
+CleanupPriorWALFiles(void)
+{
+ int rc;
+ DIR *xldir;
+ struct dirent *xlde;
+ char walfile[MAXPGPATH];
+
+ if ((xldir = opendir(archiveLocation)) != NULL)
+ {
+ while (errno = 0, (xlde = readdir(xldir)) != NULL)
+ {
+ /*
+ * Truncation is essentially harmless, because we skip names of
+ * length other than XLOG_FNAME_LEN. (In principle, one could use
+ * a 1000-character additional_ext and get trouble.)
+ */
+ strlcpy(walfile, xlde->d_name, MAXPGPATH);
+ TrimExtension(walfile, additional_ext);
+
+ /*
+ * We ignore the timeline part of the XLOG segment identifiers in
+ * deciding whether a segment is still needed. This ensures that
+ * we won't prematurely remove a segment from a parent timeline.
+ * We could probably be a little more proactive about removing
+ * segments of non-parent timelines, but that would be a whole lot
+ * more complicated.
+ *
+ * We use the alphanumeric sorting property of the filenames to
+ * decide which ones are earlier than the exclusiveCleanupFileName
+ * file. Note that this means files are not removed in the order
+ * they were originally written, in case this worries you.
+ */
+ if ((IsXLogFileName(walfile) || IsPartialXLogFileName(walfile)) &&
+ strcmp(walfile + 8, exclusiveCleanupFileName + 8) < 0)
+ {
+ char WALFilePath[MAXPGPATH * 2]; /* the file path
+ * including archive */
+
+ /*
+ * Use the original file name again now, including any
+ * extension that might have been chopped off before testing
+ * the sequence.
+ */
+ snprintf(WALFilePath, sizeof(WALFilePath), "%s/%s",
+ archiveLocation, xlde->d_name);
+
+ if (dryrun)
+ {
+ /*
+ * Prints the name of the file to be removed and skips the
+ * actual removal. The regular printout is so that the
+ * user can pipe the output into some other program.
+ */
+ printf("%s\n", WALFilePath);
+ pg_log_debug("file \"%s\" would be removed", WALFilePath);
+ continue;
+ }
+
+ pg_log_debug("removing file \"%s\"", WALFilePath);
+
+ rc = unlink(WALFilePath);
+ if (rc != 0)
+ {
+ pg_log_error("could not remove file \"%s\": %m",
+ WALFilePath);
+ break;
+ }
+ }
+ }
+
+ if (errno)
+ pg_log_error("could not read archive location \"%s\": %m",
+ archiveLocation);
+ if (closedir(xldir))
+ pg_log_error("could not close archive location \"%s\": %m",
+ archiveLocation);
+ }
+ else
+ pg_log_error("could not open archive location \"%s\": %m",
+ archiveLocation);
+}
+
+/*
+ * SetWALFileNameForCleanup()
+ *
+ * Set the earliest WAL filename that we want to keep on the archive
+ * and decide whether we need cleanup
+ */
+static void
+SetWALFileNameForCleanup(void)
+{
+ bool fnameOK = false;
+
+ TrimExtension(restartWALFileName, additional_ext);
+
+ /*
+ * If restartWALFileName is a WAL file name then just use it directly. If
+ * restartWALFileName is a .partial or .backup filename, make sure we use
+ * the prefix of the filename, otherwise we will remove wrong files since
+ * 000000010000000000000010.partial and
+ * 000000010000000000000010.00000020.backup are after
+ * 000000010000000000000010.
+ */
+ if (IsXLogFileName(restartWALFileName))
+ {
+ strcpy(exclusiveCleanupFileName, restartWALFileName);
+ fnameOK = true;
+ }
+ else if (IsPartialXLogFileName(restartWALFileName))
+ {
+ int args;
+ uint32 tli = 1,
+ log = 0,
+ seg = 0;
+
+ args = sscanf(restartWALFileName, "%08X%08X%08X.partial",
+ &tli, &log, &seg);
+ if (args == 3)
+ {
+ fnameOK = true;
+
+ /*
+ * Use just the prefix of the filename, ignore everything after
+ * first period
+ */
+ XLogFileNameById(exclusiveCleanupFileName, tli, log, seg);
+ }
+ }
+ else if (IsBackupHistoryFileName(restartWALFileName))
+ {
+ int args;
+ uint32 tli = 1,
+ log = 0,
+ seg = 0,
+ offset = 0;
+
+ args = sscanf(restartWALFileName, "%08X%08X%08X.%08X.backup", &tli, &log, &seg, &offset);
+ if (args == 4)
+ {
+ fnameOK = true;
+
+ /*
+ * Use just the prefix of the filename, ignore everything after
+ * first period
+ */
+ XLogFileNameById(exclusiveCleanupFileName, tli, log, seg);
+ }
+ }
+
+ if (!fnameOK)
+ {
+ pg_log_error("invalid file name argument");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(2);
+ }
+}
+
+/* =====================================================================
+ * End of Customizable section
+ * =====================================================================
+ */
+
+static void
+usage(void)
+{
+ printf(_("%s removes older WAL files from PostgreSQL archives.\n\n"), progname);
+ printf(_("Usage:\n"));
+ printf(_(" %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"), progname);
+ printf(_("\nOptions:\n"));
+ printf(_(" -d generate debug output (verbose mode)\n"));
+ printf(_(" -n dry run, show the names of the files that would be removed\n"));
+ printf(_(" -V, --version output version information, then exit\n"));
+ printf(_(" -x EXT clean up files if they have this extension\n"));
+ printf(_(" -?, --help show this help, then exit\n"));
+ printf(_("\n"
+ "For use as archive_cleanup_command in postgresql.conf:\n"
+ " archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+ "e.g.\n"
+ " archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"));
+ printf(_("\n"
+ "Or for use as a standalone archive cleaner:\n"
+ "e.g.\n"
+ " pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"));
+ printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT);
+ printf(_("%s home page: <%s>\n"), PACKAGE_NAME, PACKAGE_URL);
+}
+
+/*------------ MAIN ----------------------------------------*/
+int
+main(int argc, char **argv)
+{
+ int c;
+
+ pg_logging_init(argv[0]);
+ set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_archivecleanup"));
+ progname = get_progname(argv[0]);
+
+ if (argc > 1)
+ {
+ if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
+ {
+ usage();
+ exit(0);
+ }
+ if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
+ {
+ puts("pg_archivecleanup (PostgreSQL) " PG_VERSION);
+ exit(0);
+ }
+ }
+
+ while ((c = getopt(argc, argv, "x:dn")) != -1)
+ {
+ switch (c)
+ {
+ case 'd': /* Debug mode */
+ pg_logging_increase_verbosity();
+ break;
+ case 'n': /* Dry-Run mode */
+ dryrun = true;
+ break;
+ case 'x':
+ additional_ext = pg_strdup(optarg); /* Extension to remove
+ * from xlogfile names */
+ break;
+ default:
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(2);
+ break;
+ }
+ }
+
+ /*
+ * We will go to the archiveLocation to check restartWALFileName.
+ * restartWALFileName may not exist anymore, which would not be an error,
+ * so we separate the archiveLocation and restartWALFileName so we can
+ * check separately whether archiveLocation exists, if not that is an
+ * error
+ */
+ if (optind < argc)
+ {
+ archiveLocation = argv[optind];
+ optind++;
+ }
+ else
+ {
+ pg_log_error("must specify archive location");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(2);
+ }
+
+ if (optind < argc)
+ {
+ restartWALFileName = argv[optind];
+ optind++;
+ }
+ else
+ {
+ pg_log_error("must specify oldest kept WAL file");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(2);
+ }
+
+ if (optind < argc)
+ {
+ pg_log_error("too many command-line arguments");
+ fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
+ exit(2);
+ }
+
+ /*
+ * Check archive exists and other initialization if required.
+ */
+ Initialize();
+
+ /*
+ * Check filename is a valid name, then process to find cut-off
+ */
+ SetWALFileNameForCleanup();
+
+ pg_log_debug("keeping WAL file \"%s/%s\" and later",
+ archiveLocation, exclusiveCleanupFileName);
+
+ /*
+ * Remove WAL files older than cut-off
+ */
+ CleanupPriorWALFiles();
+
+ exit(0);
+}
diff --git a/src/bin/pg_archivecleanup/po/cs.po b/src/bin/pg_archivecleanup/po/cs.po
new file mode 100644
index 0000000..3a9419c
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/cs.po
@@ -0,0 +1,198 @@
+# LANGUAGE message translation file for pg_archivecleanup
+# Copyright (C) 2018 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2018.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 11\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2020-10-31 16:16+0000\n"
+"PO-Revision-Date: 2020-10-31 21:37+0100\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: cs\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.4.1\n"
+
+#: ../../../src/common/logging.c:236
+#, c-format
+msgid "fatal: "
+msgstr "fatal: "
+
+#: ../../../src/common/logging.c:243
+#, c-format
+msgid "error: "
+msgstr "error: "
+
+#: ../../../src/common/logging.c:250
+#, c-format
+msgid "warning: "
+msgstr "warning: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "archivní lokace \"%s\" neexistuje"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "nelze odstranit soubor \"%s\": %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "nelze načíst archivní lokaci \"%s\": %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "nelze uzavřít archivní lokaci \"%s\": %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "nelze otevřít archivní lokaci \"%s\": %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "chybný argument jména souboru"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Zkuste \"%s --help\" pro více informací.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s odstraní starší WAL soubory z PostgreSQL archivů.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Použití:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Přepínače:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d vygeneruje debug výstup (více informací)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n zkušební běh, ukazuje jména souborů které by byly odstraněny\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version vypíše informaci o verzi, pak skončí\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT vyčistí soubory pokud mají tuto příponu\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help ukáže tuto nápovědu, a skončí\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"Pro použití jako archive_cleanup_command v recovery.conf pokud standby_mode = on:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Nebo jako samostatný čistič archivu:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Chyby hlašte na <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s domácí stránka: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "nutno zadat archivní lokaci"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "nutno zadat nejstarčí uchovávaný WAL soubor"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "příliš mnoho argumentů na příkazové řádce"
+
+#~ msgid "%s: file \"%s\" would be removed\n"
+#~ msgstr "%s: soubor \"%s\" by byl odstraněn\n"
+
+#~ msgid "%s: removing file \"%s\"\n"
+#~ msgstr "%s: odstraňuji soubor \"%s\"\n"
+
+#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n"
+#~ msgstr "%s: ERROR: nelze odstranit soubor \"%s\": %s\n"
+
+#~ msgid "%s: keeping WAL file \"%s\" and later\n"
+#~ msgstr "%s: uchovávám WAL soubor \"%s\" a novější\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Chyby hlaste na adresu <pgsql-bugs@postgresql.org>.\n"
diff --git a/src/bin/pg_archivecleanup/po/de.po b/src/bin/pg_archivecleanup/po/de.po
new file mode 100644
index 0000000..7f1664b
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/de.po
@@ -0,0 +1,178 @@
+# pg_archivecleanup message translation file for pg_archivecleanup
+# Copyright (C) 2019-2020 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Peter Eisentraut <peter@eisentraut.org>, 2019 - 2020.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 13\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2020-04-09 10:17+0000\n"
+"PO-Revision-Date: 2020-04-09 15:15+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"
+
+#: ../../../src/common/logging.c:236
+#, c-format
+msgid "fatal: "
+msgstr "Fatal: "
+
+#: ../../../src/common/logging.c:243
+#, c-format
+msgid "error: "
+msgstr "Fehler: "
+
+#: ../../../src/common/logging.c:250
+#, c-format
+msgid "warning: "
+msgstr "Warnung: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "Archivverzeichnis »%s« existiert nicht"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "konnte Datei »%s« nicht löschen: %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "konnte Archivverzeichnis »%s« nicht lesen: %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "konnte Archivverzeichnis »%s« nicht schließen: %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "konnte Archivverzeichnis »%s« nicht öffnen: %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "ungültiges Dateinamenargument"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Versuchen Sie »%s --help« für weitere Informationen.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s entfernt alte WAL-Dateien aus PostgreSQL-Archiven.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Aufruf:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [OPTION]... ARCHIVVERZEICHNIS ÄLTESTE-ZU-BEHALTENE-WALDATEI\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Optionen:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d Debug-Ausgaben erzeugen (Verbose-Modus)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n Probelauf, Namen der Dateien anzeigen, die entfernt würden\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version Versionsinformationen anzeigen, dann beenden\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x ERW Dateien mit dieser Erweiterung aufräumen\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help diese Hilfe anzeigen, dann beenden\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"Verwendung als archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVVERZ %%r'\n"
+"z.B.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiv %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Oder alleinstehende Verwendung zum Aufräumen eines Archivs:\n"
+"z.B.\n"
+" pg_archivecleanup /mnt/server/archiv 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Berichten Sie Fehler an <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s Homepage: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "Archivverzeichnis muss angegeben werden"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "älteste zu behaltene WAL-Datei muss angegeben werden"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "zu viele Kommandozeilenargumente"
diff --git a/src/bin/pg_archivecleanup/po/el.po b/src/bin/pg_archivecleanup/po/el.po
new file mode 100644
index 0000000..0d2d49e
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/el.po
@@ -0,0 +1,181 @@
+# Greek message translation file for pg_archivecleanup
+# Copyright (C) 2021 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package.
+# Georgios Kokolatos <gkokolatos@pm.me>, 2021
+#
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-07-21 05:18+0000\n"
+"PO-Revision-Date: 2021-07-21 10:02+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"
+"X-Generator: Poedit 3.0\n"
+
+#: ../../../src/common/logging.c:259
+#, c-format
+msgid "fatal: "
+msgstr "κρίσιμο: "
+
+#: ../../../src/common/logging.c:266
+#, c-format
+msgid "error: "
+msgstr "σφάλμα: "
+
+#: ../../../src/common/logging.c:273
+#, c-format
+msgid "warning: "
+msgstr "προειδοποίηση: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "η τοποθεσία της αρχειοθήκης «%s» δεν υπάρχει"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "δεν ήταν δυνατή η αφαίρεση του αρχείου «%s»: %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "δεν ήταν δυνατή η ανάγνωση της τοποθεσίας αρχειοθήκης «%s»: %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "δεν ήταν δυνατό το κλείσιμο της τοποθεσίας αρχειοθήκης «%s»: %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "δεν ήταν δυνατό το άνοιγμα της τοποθεσίας αρχειοθήκης «%s»: %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "μη έγκυρη παράμετρος ονόματος αρχείου"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Δοκιμάστε «%s --help» για περισσότερες πληροφορίες.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s αφαιρεί παλαιότερα αρχεία WAL από αρχειοθήκες PostgreSQL.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Χρήση:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [ΕΠΙΛΟΓΗ]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Επιλογές:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d δημιουργία εξόδου αποσφαλμάτωσης (περιφραστική λειτουργία)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n ξηρή λειτουργία, εμφάνιση των ονομάτων των αρχείων που θα αφαιρεθούν\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version εμφάνισε πληροφορίες έκδοσης, στη συνέχεια έξοδος\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT εκκαθάριση αρχείων εάν περιέχουν αυτήν την επέκταση\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help εμφάνισε αυτό το μήνυμα βοήθειας, στη συνέχεια έξοδος\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"Για χρήση ως archive_cleanup_command στο postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [ΕΠΙΛΟΓΗ]... ARCHIVELOCATION %%r’\n"
+"π.χ.\n"
+" archive_cleanup_command = ‘pg_archivecleanup /mnt/διακομιστής/αρχειοθήκη %%r’\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Ή για χρήση ως αυτόνομο εκκαθαριστικό αρχειοθήκης:\n"
+"π.χ.\n"
+" pg_archivecleanup /mnt/server/archiverdir 0000000100000000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Υποβάλετε αναφορές σφάλματων σε <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s αρχική σελίδα: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "πρέπει να καθορίσετε τη τοποθεσία αρχειοθήκης"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "πρέπει να καθορίσετε το παλαιότερο κρατημένο αρχείο WAL"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "πάρα πολλές παράμετροι εισόδου από την γραμμή εντολών"
diff --git a/src/bin/pg_archivecleanup/po/es.po b/src/bin/pg_archivecleanup/po/es.po
new file mode 100644
index 0000000..a3473be
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/es.po
@@ -0,0 +1,180 @@
+# Spanish message translation file for pg_archivecleanup
+# Copyright (c) 2017-2021, PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+#
+# Carlos Chapi <carlos.chapi@2ndquadrant.com>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-08-07 20:36+0000\n"
+"PO-Revision-Date: 2020-09-12 23:13-0300\n"
+"Last-Translator: Carlos Chapi <carlos.chapi@2ndquadrant.com>\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"
+"X-Generator: BlackCAT 1.0\n"
+
+#: ../../../src/common/logging.c:259
+#, c-format
+msgid "fatal: "
+msgstr "fatal: "
+
+#: ../../../src/common/logging.c:266
+#, c-format
+msgid "error: "
+msgstr "error: "
+
+#: ../../../src/common/logging.c:273
+#, c-format
+msgid "warning: "
+msgstr "precaución: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "ubicación de archivador «%s» no existe"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "no se pudo eliminar el archivo «%s»: %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "no se pudo leer la ubicación del archivador «%s»: %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "no se pudo cerrar la ubicación del archivador «%s»: %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "no se pudo abrir la ubicación del archivador «%s»: %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "el nombre de archivo usado como argumento no es válido"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Pruebe «%s --help» para mayor información.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s elimina archivos de WAL antiguos del archivador de PostgreSQL.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Empleo:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [OPCIÓN].... UBICACIÓNARCHIVADOR WALMÁSANTIGUOAMANTENER\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Opciones:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d genera salida de depuración (modo verboso)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n simulacro, muestra el nombre de los archivos que se eliminarían\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version muestra información de la versión, luego sale\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT hace limpieza de archivos que tengan esta extensión\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help muestra esta ayuda, luego sale\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"Para usar como archive_cleanup_command en postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPCIÓN]... UBICACIÓNARCHIVADOR %%r'\n"
+"por ej.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/servidor/directorioarchivador %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"O para usar como un limpiador de archivador de forma independiente:\n"
+"por ej.\n"
+" pg_archivecleanup /mnt/servidor/directorioarchivador 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Reporte errores a <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Sitio web de %s: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "debe especificar la ubicación del archivador"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "debe especificar el fichero WAL más antiguo a mantener"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "demasiados argumentos de línea de órdenes"
diff --git a/src/bin/pg_archivecleanup/po/fr.po b/src/bin/pg_archivecleanup/po/fr.po
new file mode 100644
index 0000000..7d7248d
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/fr.po
@@ -0,0 +1,201 @@
+# LANGUAGE message translation file for pg_archivecleanup
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2020-04-16 06:16+0000\n"
+"PO-Revision-Date: 2020-04-16 13:39+0200\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: fr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.3\n"
+
+#: ../../../src/common/logging.c:236
+#, c-format
+msgid "fatal: "
+msgstr "fatal : "
+
+#: ../../../src/common/logging.c:243
+#, c-format
+msgid "error: "
+msgstr "erreur : "
+
+#: ../../../src/common/logging.c:250
+#, c-format
+msgid "warning: "
+msgstr "attention : "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "l'emplacement d'archivage « %s » n'existe pas"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "n'a pas pu supprimer le fichier « %s » : %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "n'a pas pu lire l'emplacement de l'archive « %s » : %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "n'a pas pu fermer l'emplacement de l'archive « %s » : %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "n'a pas pu ouvrir l'emplacement de l'archive « %s » : %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "argument du nom de fichier invalide"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Essayez « %s --help » pour plus d'informations.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s supprime les anciens fichiers WAL des archives de PostgreSQL.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Usage :\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [OPTION]... EMPLACEMENTARCHIVE PLUSANCIENFICHIERWALCONSERVÉ\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Options :\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d affiche des informations de débugage (mode verbeux)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n test, affiche le nom des fichiers qui seraient supprimés\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version affiche la version et quitte\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT nettoie les fichiers s'ils ont cette extension\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help affiche cette aide et quitte\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"Pour utiliser comme archive_cleanup_command dans postgresql.conf :\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... EMPLACEMENTARCHIVE %%r'\n"
+"Par exemple :\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/serveur/reparchives %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Ou pour utiliser comme nettoyeur autonome d'archives :\n"
+"Par exemple :\n"
+" pg_archivecleanup /mnt/serveur/reparchives 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Rapporter les bogues à <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Page d'accueil de %s : <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "doit spécifier l'emplacement de l'archive"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "doit spécifier le plus ancien journal de transactions conservé"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "trop d'arguments en ligne de commande"
+
+#~ msgid "%s: file \"%s\" would be removed\n"
+#~ msgstr "%s : le fichier « %s » serait supprimé\n"
+
+#~ msgid "%s: removing file \"%s\"\n"
+#~ msgstr "%s : suppression du fichier « %s »\n"
+
+#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n"
+#~ msgstr "%s : ERREUR : n'a pas pu supprimer le fichier « %s » : %s\n"
+
+#~ msgid "%s: keeping WAL file \"%s\" and later\n"
+#~ msgstr "%s : conservation du fichier WAL « %s » et des suivants\n"
+
+#~ msgid "%s: too many parameters\n"
+#~ msgstr "%s : trop de paramètres\n"
+
+#~ msgid ""
+#~ "\n"
+#~ "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Rapporter les bogues à <pgsql-bugs@lists.postgresql.org>.\n"
diff --git a/src/bin/pg_archivecleanup/po/ja.po b/src/bin/pg_archivecleanup/po/ja.po
new file mode 100644
index 0000000..788eab5
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/ja.po
@@ -0,0 +1,178 @@
+# Japanese message translation file for pg_archivecleanup
+# Copyright (C) 2022 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL 14)\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-08-25 17:21+0900\n"
+"PO-Revision-Date: 2021-05-18 17:08+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"
+"X-Generator: Poedit 1.8.13\n"
+
+#: ../../../src/common/logging.c:259
+#, c-format
+msgid "fatal: "
+msgstr "致命的エラー: "
+
+#: ../../../src/common/logging.c:266
+#, c-format
+msgid "error: "
+msgstr "エラー: "
+
+#: ../../../src/common/logging.c:273
+#, c-format
+msgid "warning: "
+msgstr "警告: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "アーカイブの場所\"%s\"が存在しません"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "ファイル\"%s\"を削除できませんでした: %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "アーカイブの場所\"%s\"を読み込めませんでした: %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "アーカイブの場所\"%s\"をクローズできませんでした: %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "アーカイブの場所\"%s\"をオープンできませんでした: %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "ファイル名引数が無効です"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "詳細は\"%s --help\"で確認してください。\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%sはPostgreSQLのアーカイブから古いWALファイルを削除します。\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "使用方法:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr "%s [オプション] ... {アーカイブの場所} {保存する最古の WAL ファイル名}\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"オプション:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d デバッグ情報を出力(冗長モード)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n リハーサル、削除対象のファイル名を表示\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version バージョン情報を出力して終了\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT この拡張子を持つファイルを削除対象とする\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help このヘルプを表示して終了\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"postgresql.confでarchive_cleanup_commandとして使用する場合は以下のようにします:\n"
+" archive_cleanup_command = 'pg_archivecleanup [オプション]... アーカイブの場所 %%r'\n"
+"例としては:\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"もしくはスタンドアロンのアーカイブクリーナーとして使う場合は:\n"
+"使用例\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"バグは<%s>に報告してください。\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s ホームページ: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "アーカイブの場所を指定してください"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "保存する最古のWALファイルを指定してください"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "コマンドライン引数が多すぎます"
diff --git a/src/bin/pg_archivecleanup/po/ko.po b/src/bin/pg_archivecleanup/po/ko.po
new file mode 100644
index 0000000..785839a
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/ko.po
@@ -0,0 +1,184 @@
+# LANGUAGE message translation file for pg_archivecleanup
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Ioseph Kim <ioseph@uri.sarang.net>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 13\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2020-10-05 01:16+0000\n"
+"PO-Revision-Date: 2020-10-05 17:51+0900\n"
+"Last-Translator: Ioseph Kim <ioseph@uri.sarang.net>\n"
+"Language-Team: Korean <pgsql-kr@postgresql.kr>\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:236
+#, c-format
+msgid "fatal: "
+msgstr "심각: "
+
+#: ../../../src/common/logging.c:243
+#, c-format
+msgid "error: "
+msgstr "오류: "
+
+#: ../../../src/common/logging.c:250
+#, c-format
+msgid "warning: "
+msgstr "경고: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "\"%s\" 이름의 아카이브 위치가 없음"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "\"%s\" 파일을 삭제할 수 없음: %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "\"%s\" 아카이브 위치를 읽을 수 없음: %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "\"%s\" 아카이브 위치를 닫을 수 없음: %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "\"%s\" 아카이브 위치를 열 수 없음: %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "잘못된 파일 이름 매개변수"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "보다 자세한 정보는 \"%s --help\" 명령을 참조하세요.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s 명령은 PostgreSQL 아카이브 보관소에서 오래된\n"
+"WAL 파일을 지웁니다.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "사용법:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [옵션]... 아카이브위치 보관할제일오래된파일\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"옵션들:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d 보다 자세한 작업 내용 출력\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid ""
+" -n dry run, show the names of the files that would be removed\n"
+msgstr " -n 지울 대상만 확인하고 지우지는 않음\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version 버전 정보를 보여주고 마침\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT 해당 확장자 파일들을 작업 대상으로 함\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help 도움말을 보여주고 마침\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION "
+"%%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"postgresql.conf 파일에서 archive_cleanup_command 설정 방법:\n"
+" archive_cleanup_command = 'pg_archivecleanup [옵션]... 아카이브위치 %%r'\n"
+"사용예:\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir "
+"000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"또는 명령행에서 독립적으로 사용하는 경우:\n"
+"사용예:\n"
+" pg_archivecleanup /mnt/server/archiverdir "
+"000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"문제점 보고 주소: <%s>\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s 홈페이지: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "아카이브 위치는 지정해야 함"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "남길 가장 오래된 WAL 파일은 지정해야 함"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "너무 많은 명령행 인자를 지정했음"
diff --git a/src/bin/pg_archivecleanup/po/ru.po b/src/bin/pg_archivecleanup/po/ru.po
new file mode 100644
index 0000000..22d0f77
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/ru.po
@@ -0,0 +1,204 @@
+# Russian message translation file for pg_archivecleanup
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the PostgreSQL package.
+# Alexander Lakhin <a.lakhin@postgrespro.ru>, 2017, 2019, 2020.
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-08-14 06:29+0300\n"
+"PO-Revision-Date: 2020-09-03 12:40+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:259
+#, c-format
+msgid "fatal: "
+msgstr "важно: "
+
+#: ../../../src/common/logging.c:266
+#, c-format
+msgid "error: "
+msgstr "ошибка: "
+
+#: ../../../src/common/logging.c:273
+#, c-format
+msgid "warning: "
+msgstr "предупреждение: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "расположение архива \"%s\" не существует"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "не удалось стереть файл \"%s\": %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "не удалось прочитать расположение архива \"%s\": %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "не удалось закрыть расположение архива \"%s\": %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "не удалось открыть расположение архива \"%s\": %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "неверный аргумент с именем файла"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Для дополнительной информации попробуйте \"%s --help\".\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s удаляет старые файлы WAL из архивов PostgreSQL.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Использование:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr ""
+" %s [ПАРАМЕТР]... РАСПОЛОЖЕНИЕ_АРХИВА СТАРЕЙШИЙ_СОХРАНЯЕМЫЙ_ФАЙЛ_WAL\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Параметры:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d генерировать подробные сообщения (отладочный режим)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid ""
+" -n dry run, show the names of the files that would be removed\n"
+msgstr ""
+" -n холостой запуск, только показать имена файлов, которые "
+"будут удалены\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version показать версию и выйти\n"
+
+# well-spelled: РСШ
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x РСШ убрать файлы с заданным расширением\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help показать эту справку и выйти\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION "
+"%%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"Для использования в качестве archive_cleanup_command в postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [ПАРАМЕТР]... "
+"РАСПОЛОЖЕНИЕ_АРХИВА %%r'\n"
+"например:\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir "
+"000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Либо для использования в качестве отдельного средства очистки архива,\n"
+"например:\n"
+" pg_archivecleanup /mnt/server/archiverdir "
+"000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Об ошибках сообщайте по адресу <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Домашняя страница %s: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "необходимо задать расположение архива"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "необходимо задать имя старейшего сохраняемого файла WAL"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "слишком много аргументов командной строки"
+
+#~ msgid ""
+#~ "\n"
+#~ "Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"
+#~ msgstr ""
+#~ "\n"
+#~ "Об ошибках сообщайте по адресу <pgsql-bugs@lists.postgresql.org>.\n"
+
+#~ msgid "%s: file \"%s\" would be removed\n"
+#~ msgstr "%s: файл \"%s\" не будет удалён\n"
+
+#~ msgid "%s: removing file \"%s\"\n"
+#~ msgstr "%s: удаление файла \"%s\"\n"
+
+#~ msgid "%s: keeping WAL file \"%s\" and later\n"
+#~ msgstr "%s: будет сохранён файл WAL \"%s\" и последующие\n"
diff --git a/src/bin/pg_archivecleanup/po/sv.po b/src/bin/pg_archivecleanup/po/sv.po
new file mode 100644
index 0000000..a1fafe8
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/sv.po
@@ -0,0 +1,179 @@
+# Swedish message translation file for pg_archivecleanup
+# 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.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: PostgreSQL 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2020-04-11 01:17+0000\n"
+"PO-Revision-Date: 2021-11-07 10:36+0100\n"
+"Last-Translator: FDennis 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:236
+#, c-format
+msgid "fatal: "
+msgstr "fatalt: "
+
+#: ../../../src/common/logging.c:243
+#, c-format
+msgid "error: "
+msgstr "fel: "
+
+#: ../../../src/common/logging.c:250
+#, c-format
+msgid "warning: "
+msgstr "varning: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "arkivplats \"%s\" finns inte"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "kunde inte ta bort fil \"%s\": %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "kunde inte läsa arkivplats \"%s\": %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "kunde inte stänga arkivplats \"%s\": %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "kunde inte öppna arkivplats \"%s\": %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "ogiltigt filnamnsargument"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Försök med \"%s --help\" för mer information.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s tar bort gamla WAL-filer från PostgreSQLs arkiv.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Användning:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [FLAGGA]... ARKIVPLATS ÄLDSTASPARADEWALFIL\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Flaggor:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d generera debugutskrift (utförligt läge)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n gör inga ändringar visa namn på de filer som skulle ha tagits bort\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version visa versionsinformation, avsluta sedan\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x SUF städa upp filer om de har detta suffix\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help visa denna hjälp, avsluta sedan\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"För att använda som archive_cleanup_command i postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [FLAGGA]... ARKIVPLATS %%r'\n"
+"t.ex.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Eller för att använda som en separat arkivstädare:\n"
+"t.ex.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"Rapportera fel till <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "hemsida för %s: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "måste ange en arkivplats"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "måste ange äldsta sparade WAL-filen"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "för många kommandoradsargument"
diff --git a/src/bin/pg_archivecleanup/po/tr.po b/src/bin/pg_archivecleanup/po/tr.po
new file mode 100644
index 0000000..fac3be6
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/tr.po
@@ -0,0 +1,185 @@
+# LANGUAGE message translation file for pg_archivecleanup
+# Copyright (C) 2017 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 10\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2019-04-26 13:48+0000\n"
+"PO-Revision-Date: 2021-09-16 09:39+0200\n"
+"Last-Translator: \n"
+"Language-Team: \n"
+"Language: tr\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 1.8.7.1\n"
+
+#: ../../../src/fe_utils/logging.c:182
+#, c-format
+msgid "fatal: "
+msgstr "ölümcül (fatal): "
+
+#: ../../../src/fe_utils/logging.c:189
+#, c-format
+msgid "error: "
+msgstr "hata: "
+
+#: ../../../src/fe_utils/logging.c:196
+#, c-format
+msgid "warning: "
+msgstr "uyarı: "
+
+#: pg_archivecleanup.c:68
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "\"%s\" arşiv lokasyonu mevcut değil"
+
+#: pg_archivecleanup.c:153
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "\"%s\" dosyası silinemedi: %m"
+
+#: pg_archivecleanup.c:161
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "\"%s\" arşiv lokasyonu okunamadı: %m"
+
+#: pg_archivecleanup.c:164
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "\"%s\" arşiv lokasyonu kapatılamadı: %m"
+
+#: pg_archivecleanup.c:168
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "\"%s\" arşiv lokasyonu açılamadı: %m"
+
+#: pg_archivecleanup.c:241
+#, c-format
+msgid "invalid file name argument"
+msgstr "geçersiz dosya adı argümanı"
+
+#: pg_archivecleanup.c:242 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Daha fazla bilgi için \"%s --help\" yazın\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr "%s daha eski WAL dosyalarını PostgreSQL arşivlerinden kaldırır.\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid "Usage:\n"
+msgstr "Kullanımı:\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [SECENEK]... ARSIVLOKASYONU TUTULANENESKIWALDOSYASI\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"Seçenekler:\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d hata ayıklama çıktısı oluştur (ayrıntılı açıklamalı mod)\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n tatbikat modu, sadece kaldırılacak dosyaların adlarını göster\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version sürüm bilgisini göster, sonra çık\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT bu uzantıya sahip dosyaları temizle\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help bu yardımı göster, sonra çık\n"
+
+#: pg_archivecleanup.c:264
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"postgresql.conf'da archive_cleanup_command olarak kullanmak için:\n"
+" archive_cleanup_command = 'pg_archivecleanup [SECENEK]... ARSIVLOKASYONU %%r'\n"
+"örnek:\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+"\n"
+
+#: pg_archivecleanup.c:269
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"Veya bağımsız bir arşiv temizleyici olarak kullanmak için: \n"
+"örnek:\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <pgsql-bugs@lists.postgresql.org>.\n"
+msgstr ""
+"\n"
+"Hataları <pgsql-bugs@lists.postgresql.org> adresine bildirebilirsiniz.\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "arşiv lokasyonu belirtilmeli"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "tutulan en eski WAL dosyası belirtilmeli"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "çok fazla komut-satırı argümanı"
+
+#~ msgid "%s: keeping WAL file \"%s\" and later\n"
+#~ msgstr "%s: \"%s\" ve sonrasındaki WAl dosyaları tutuluyor\n"
+
+#~ msgid "%s: ERROR: could not remove file \"%s\": %s\n"
+#~ msgstr "%s: HATA: \"%s\" dosyası kaldırılamadı: %s\n"
+
+#~ msgid "%s: removing file \"%s\"\n"
+#~ msgstr "%s: \"%s\" dosyası kaldırılıyor\n"
+
+#~ msgid "%s: file \"%s\" would be removed\n"
+#~ msgstr "%s: \"%s\" dosyası kaldırılacak\n"
diff --git a/src/bin/pg_archivecleanup/po/uk.po b/src/bin/pg_archivecleanup/po/uk.po
new file mode 100644
index 0000000..4c090ac
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/uk.po
@@ -0,0 +1,168 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: postgresql\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2022-03-16 09:18+0000\n"
+"PO-Revision-Date: 2022-06-19 10:10\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_14_STABLE/pg_archivecleanup.pot\n"
+"X-Crowdin-File-ID: 760\n"
+
+#: ../../../src/common/logging.c:259
+#, c-format
+msgid "fatal: "
+msgstr "збій: "
+
+#: ../../../src/common/logging.c:266
+#, c-format
+msgid "error: "
+msgstr "помилка: "
+
+#: ../../../src/common/logging.c:273
+#, c-format
+msgid "warning: "
+msgstr "попередження: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "архівного розташування \"%s\" не існує"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "не можливо видалити файл \"%s\": %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "не вдалося прочитати архівне розташування \"%s\":%m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "не вдалося закрити архівне розташування \"%s\":%m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "не вдалося відкрити архівне розташування \"%s\":%m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "недійсна назва файла з аргументом"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "Спробуйте \"%s --help\" для додаткової інформації.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid "%s removes older WAL files from PostgreSQL archives.\n\n"
+msgstr "%s видаляє старі WAL-файли з архівів PostgreSQL.\n\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "Використання:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [OPTION]... РОЗТАШУВАННЯ_АРХІВА НАЙДАВНІШИЙ_ЗБЕРЕЖЕНИЙ_WAL_ФАЙЛ\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid "\n"
+"Options:\n"
+msgstr "\n"
+"Параметри:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d генерує налагоджувальні повідомлення (детальний режим)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n сухий запуск, показує тільки ті файли, які будуть видалені\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version показати версію, потім вийти\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT прибрати файли з цим розширенням\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help показати цю довідку, потім вийти\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid "\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr "\n"
+"Для використання як archive_cleanup_command у postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"напр.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid "\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr "\n"
+"Або для використання в якості окремого засобу для чистки архівів,\n"
+"наприклад:\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid "\n"
+"Report bugs to <%s>.\n"
+msgstr "\n"
+"Повідомляти про помилки на <%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "Домашня сторінка %s: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "необхідно вказати розташування архіва"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "необхідно вказати найдавніший збережений WAL-файл"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "занадто багато аргументів командного рядка"
+
diff --git a/src/bin/pg_archivecleanup/po/zh_CN.po b/src/bin/pg_archivecleanup/po/zh_CN.po
new file mode 100644
index 0000000..e8c3348
--- /dev/null
+++ b/src/bin/pg_archivecleanup/po/zh_CN.po
@@ -0,0 +1,179 @@
+# LANGUAGE message translation file for pg_archivecleanup
+# Copyright (C) 2019 PostgreSQL Global Development Group
+# This file is distributed under the same license as the pg_archivecleanup (PostgreSQL) package.
+# FIRST AUTHOR <zhangjie2@fujitsu.com>, 2019.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: pg_archivecleanup (PostgreSQL) 14\n"
+"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
+"POT-Creation-Date: 2021-08-14 05:48+0000\n"
+"PO-Revision-Date: 2021-08-14 19:40+0800\n"
+"Last-Translator: Jie Zhang <zhangjie2@fujitsu.com>\n"
+"Language-Team: Chinese (Simplified) <zhangjie2@fujitsu.com>\n"
+"Language: zh_CN\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../../../src/common/logging.c:259
+#, c-format
+msgid "fatal: "
+msgstr "致命的: "
+
+#: ../../../src/common/logging.c:266
+#, c-format
+msgid "error: "
+msgstr "错误: "
+
+#: ../../../src/common/logging.c:273
+#, c-format
+msgid "warning: "
+msgstr "警告: "
+
+#: pg_archivecleanup.c:66
+#, c-format
+msgid "archive location \"%s\" does not exist"
+msgstr "存档位置\"%s\"不存在"
+
+#: pg_archivecleanup.c:152
+#, c-format
+msgid "could not remove file \"%s\": %m"
+msgstr "无法删除文件 \"%s\": %m"
+
+#: pg_archivecleanup.c:160
+#, c-format
+msgid "could not read archive location \"%s\": %m"
+msgstr "无法读取存档位置\"%s\": %m"
+
+#: pg_archivecleanup.c:163
+#, c-format
+msgid "could not close archive location \"%s\": %m"
+msgstr "无法关闭存档位置 \"%s\": %m"
+
+#: pg_archivecleanup.c:167
+#, c-format
+msgid "could not open archive location \"%s\": %m"
+msgstr "无法打开存档位置\"%s\": %m"
+
+#: pg_archivecleanup.c:240
+#, c-format
+msgid "invalid file name argument"
+msgstr "文件名参数无效"
+
+#: pg_archivecleanup.c:241 pg_archivecleanup.c:315 pg_archivecleanup.c:336
+#: pg_archivecleanup.c:348 pg_archivecleanup.c:355
+#, c-format
+msgid "Try \"%s --help\" for more information.\n"
+msgstr "请用 \"%s --help\" 获取更多的信息.\n"
+
+#: pg_archivecleanup.c:254
+#, c-format
+msgid ""
+"%s removes older WAL files from PostgreSQL archives.\n"
+"\n"
+msgstr ""
+"%s 从PostgreSQL存档中删除旧的WAL文件.\n"
+"\n"
+
+#: pg_archivecleanup.c:255
+#, c-format
+msgid "Usage:\n"
+msgstr "使用方法:\n"
+
+#: pg_archivecleanup.c:256
+#, c-format
+msgid " %s [OPTION]... ARCHIVELOCATION OLDESTKEPTWALFILE\n"
+msgstr " %s [OPTION]... 归档文件位置 最早保存的WAL文件\n"
+
+#: pg_archivecleanup.c:257
+#, c-format
+msgid ""
+"\n"
+"Options:\n"
+msgstr ""
+"\n"
+"选项:\n"
+
+#: pg_archivecleanup.c:258
+#, c-format
+msgid " -d generate debug output (verbose mode)\n"
+msgstr " -d 生成调试输出(详细模式)\n"
+
+#: pg_archivecleanup.c:259
+#, c-format
+msgid " -n dry run, show the names of the files that would be removed\n"
+msgstr " -n dry运行,显示要删除的文件的名称\n"
+
+#: pg_archivecleanup.c:260
+#, c-format
+msgid " -V, --version output version information, then exit\n"
+msgstr " -V, --version 输出版本信息,然后退出\n"
+
+#: pg_archivecleanup.c:261
+#, c-format
+msgid " -x EXT clean up files if they have this extension\n"
+msgstr " -x EXT 如果文件具有此扩展名,则清除文件\n"
+
+#: pg_archivecleanup.c:262
+#, c-format
+msgid " -?, --help show this help, then exit\n"
+msgstr " -?, --help 显示帮助信息,然后退出\n"
+
+#: pg_archivecleanup.c:263
+#, c-format
+msgid ""
+"\n"
+"For use as archive_cleanup_command in postgresql.conf:\n"
+" archive_cleanup_command = 'pg_archivecleanup [OPTION]... ARCHIVELOCATION %%r'\n"
+"e.g.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+msgstr ""
+"\n"
+"在postgresql.conf中,archive_cleanup_command的用法 \n"
+" archive_cleanup_command = 'pg_archivecleanup [选项]... 存档位置 %%r'\n"
+"例.\n"
+" archive_cleanup_command = 'pg_archivecleanup /mnt/server/archiverdir %%r'\n"
+
+#: pg_archivecleanup.c:268
+#, c-format
+msgid ""
+"\n"
+"Or for use as a standalone archive cleaner:\n"
+"e.g.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+msgstr ""
+"\n"
+"或者,用作独立存档清理程序:\n"
+"例.\n"
+" pg_archivecleanup /mnt/server/archiverdir 000000010000000000000010.00000020.backup\n"
+
+#: pg_archivecleanup.c:272
+#, c-format
+msgid ""
+"\n"
+"Report bugs to <%s>.\n"
+msgstr ""
+"\n"
+"臭虫报告至<%s>.\n"
+
+#: pg_archivecleanup.c:273
+#, c-format
+msgid "%s home page: <%s>\n"
+msgstr "%s 主页: <%s>\n"
+
+#: pg_archivecleanup.c:335
+#, c-format
+msgid "must specify archive location"
+msgstr "必须指定存档位置"
+
+#: pg_archivecleanup.c:347
+#, c-format
+msgid "must specify oldest kept WAL file"
+msgstr "必须指定最早保存的WAL文件"
+
+#: pg_archivecleanup.c:354
+#, c-format
+msgid "too many command-line arguments"
+msgstr "命令行参数太多"
+
diff --git a/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
new file mode 100644
index 0000000..8d689b9
--- /dev/null
+++ b/src/bin/pg_archivecleanup/t/010_pg_archivecleanup.pl
@@ -0,0 +1,103 @@
+
+# Copyright (c) 2021, PostgreSQL Global Development Group
+
+use strict;
+use warnings;
+use TestLib;
+use Test::More tests => 42;
+
+program_help_ok('pg_archivecleanup');
+program_version_ok('pg_archivecleanup');
+program_options_handling_ok('pg_archivecleanup');
+
+my $tempdir = TestLib::tempdir;
+
+my @walfiles = (
+ '00000001000000370000000C.gz', '00000001000000370000000D',
+ '00000001000000370000000E', '00000001000000370000000F.partial',);
+
+sub create_files
+{
+ foreach my $fn (@walfiles, 'unrelated_file')
+ {
+ open my $file, '>', "$tempdir/$fn";
+ print $file 'CONTENT';
+ close $file;
+ }
+ return;
+}
+
+create_files();
+
+command_fails_like(
+ ['pg_archivecleanup'],
+ qr/must specify archive location/,
+ 'fails if archive location is not specified');
+
+command_fails_like(
+ [ 'pg_archivecleanup', $tempdir ],
+ qr/must specify oldest kept WAL file/,
+ 'fails if oldest kept WAL file name is not specified');
+
+command_fails_like(
+ [ 'pg_archivecleanup', 'notexist', 'foo' ],
+ qr/archive location .* does not exist/,
+ 'fails if archive location does not exist');
+
+command_fails_like(
+ [ 'pg_archivecleanup', $tempdir, 'foo', 'bar' ],
+ qr/too many command-line arguments/,
+ 'fails with too many command-line arguments');
+
+command_fails_like(
+ [ 'pg_archivecleanup', $tempdir, 'foo' ],
+ qr/invalid file name argument/,
+ 'fails with invalid restart file name');
+
+{
+ # like command_like but checking stderr
+ my $stderr;
+ my $result = IPC::Run::run [ 'pg_archivecleanup', '-d', '-n', $tempdir,
+ $walfiles[2] ], '2>', \$stderr;
+ ok($result, "pg_archivecleanup dry run: exit code 0");
+ like(
+ $stderr,
+ qr/$walfiles[1].*would be removed/,
+ "pg_archivecleanup dry run: matches");
+ foreach my $fn (@walfiles)
+ {
+ ok(-f "$tempdir/$fn", "$fn not removed");
+ }
+}
+
+sub run_check
+{
+ local $Test::Builder::Level = $Test::Builder::Level + 1;
+
+ my ($suffix, $test_name) = @_;
+
+ create_files();
+
+ command_ok(
+ [
+ 'pg_archivecleanup', '-x', '.gz', $tempdir,
+ $walfiles[2] . $suffix
+ ],
+ "$test_name: runs");
+
+ ok(!-f "$tempdir/$walfiles[0]",
+ "$test_name: first older WAL file was cleaned up");
+ ok(!-f "$tempdir/$walfiles[1]",
+ "$test_name: second older WAL file was cleaned up");
+ ok(-f "$tempdir/$walfiles[2]",
+ "$test_name: restartfile was not cleaned up");
+ ok(-f "$tempdir/$walfiles[3]",
+ "$test_name: newer WAL file was not cleaned up");
+ ok(-f "$tempdir/unrelated_file",
+ "$test_name: unrelated file was not cleaned up");
+ return;
+}
+
+run_check('', 'pg_archivecleanup');
+run_check('.partial', 'pg_archivecleanup with .partial file');
+run_check('.00000020.backup', 'pg_archivecleanup with .backup file');