From 927474ce1a2498ddb617c6113a88ca61fbba161d Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Mon, 30 Sep 2019 12:57:35 -0300 Subject: [PATCH] pg_rewind: Allow writing recovery configuration MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This is provided with a new switch --write-recovery-conf and reuses the pg_basebackup code. Author: Paul Guo, Jimmy Yih, Ashwin Agrawal Reviewed-by: Alexey Kondratov, Michaël Paquier, Álvaro Herrera Discussion: https://postgr.es/m/CAEET0ZEffUkXc48pg2iqARQgGRYDiiVxDu+yYek_bTwJF+q=Uw@mail.gmail.com --- doc/src/sgml/ref/pg_rewind.sgml | 13 ++++++++++++ src/bin/pg_rewind/Makefile | 2 +- src/bin/pg_rewind/libpq_fetch.c | 3 +-- src/bin/pg_rewind/pg_rewind.c | 35 ++++++++++++++++++++++++++++++++- src/bin/pg_rewind/pg_rewind.h | 9 +++++++-- 5 files changed, 56 insertions(+), 6 deletions(-) diff --git a/doc/src/sgml/ref/pg_rewind.sgml b/doc/src/sgml/ref/pg_rewind.sgml index a06e5ac5e1..fbf454803b 100644 --- a/doc/src/sgml/ref/pg_rewind.sgml +++ b/doc/src/sgml/ref/pg_rewind.sgml @@ -180,6 +180,19 @@ PostgreSQL documentation + + + + + + Create standby.signal and append connection + settings to postgresql.auto.conf in the output + directory. --source-server is mandatory with + this option. + + + + diff --git a/src/bin/pg_rewind/Makefile b/src/bin/pg_rewind/Makefile index 859d3abc41..98fb381c62 100644 --- a/src/bin/pg_rewind/Makefile +++ b/src/bin/pg_rewind/Makefile @@ -16,7 +16,7 @@ top_builddir = ../../.. include $(top_builddir)/src/Makefile.global override CPPFLAGS := -I$(libpq_srcdir) -DFRONTEND $(CPPFLAGS) -LDFLAGS_INTERNAL += $(libpq_pgport) +LDFLAGS_INTERNAL += $(libpq_pgport) -L$(top_builddir)/src/fe_utils -lpgfeutils OBJS = pg_rewind.o parsexlog.o xlogreader.o datapagemap.o timeline.o \ fetch.o file_ops.o copy_fetch.o libpq_fetch.o filemap.o \ diff --git a/src/bin/pg_rewind/libpq_fetch.c b/src/bin/pg_rewind/libpq_fetch.c index 002776f696..f4ebf7d842 100644 --- a/src/bin/pg_rewind/libpq_fetch.c +++ b/src/bin/pg_rewind/libpq_fetch.c @@ -20,12 +20,11 @@ #include "file_ops.h" #include "filemap.h" -#include "libpq-fe.h" #include "catalog/pg_type_d.h" #include "fe_utils/connect.h" #include "port/pg_bswap.h" -static PGconn *conn = NULL; +PGconn *conn = NULL; /* * Files are fetched max CHUNKSIZE bytes at a time. diff --git a/src/bin/pg_rewind/pg_rewind.c b/src/bin/pg_rewind/pg_rewind.c index 8cb0d726cf..a7fd9e0cab 100644 --- a/src/bin/pg_rewind/pg_rewind.c +++ b/src/bin/pg_rewind/pg_rewind.c @@ -27,6 +27,7 @@ #include "common/file_perm.h" #include "common/file_utils.h" #include "common/restricted_token.h" +#include "fe_utils/recovery_gen.h" #include "getopt_long.h" #include "storage/bufpage.h" @@ -41,6 +42,7 @@ static void syncTargetDirectory(void); static void sanityChecks(void); static void findCommonAncestorTimeline(XLogRecPtr *recptr, int *tliIndex); static void ensureCleanShutdown(const char *argv0); +static void disconnect_atexit(void); static ControlFileData ControlFile_target; static ControlFileData ControlFile_source; @@ -76,6 +78,8 @@ usage(const char *progname) printf(_(" -D, --target-pgdata=DIRECTORY existing data directory to modify\n")); printf(_(" --source-pgdata=DIRECTORY source data directory to synchronize with\n")); printf(_(" --source-server=CONNSTR source server to synchronize with\n")); + printf(_(" -R, --write-recovery-conf write configuration for replication\n" + " (requires --source-server)\n")); printf(_(" -n, --dry-run stop before modifying anything\n")); printf(_(" -N, --no-sync do not wait for changes to be written\n" " safely to disk\n")); @@ -94,6 +98,7 @@ main(int argc, char **argv) static struct option long_options[] = { {"help", no_argument, NULL, '?'}, {"target-pgdata", required_argument, NULL, 'D'}, + {"write-recovery-conf", no_argument, NULL, 'R'}, {"source-pgdata", required_argument, NULL, 1}, {"source-server", required_argument, NULL, 2}, {"no-ensure-shutdown", no_argument, NULL, 44}, @@ -118,6 +123,7 @@ main(int argc, char **argv) XLogRecPtr endrec; TimeLineID endtli; ControlFileData ControlFile_new; + bool writerecoveryconf = false; pg_logging_init(argv[0]); set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_rewind")); @@ -138,7 +144,7 @@ main(int argc, char **argv) } } - while ((c = getopt_long(argc, argv, "D:nNP", long_options, &option_index)) != -1) + while ((c = getopt_long(argc, argv, "D:nNPR", long_options, &option_index)) != -1) { switch (c) { @@ -158,6 +164,10 @@ main(int argc, char **argv) do_sync = false; break; + case 'R': + writerecoveryconf = true; + break; + case 3: debug = true; pg_logging_set_level(PG_LOG_DEBUG); @@ -200,6 +210,13 @@ main(int argc, char **argv) exit(1); } + if (writerecoveryconf && connstr_source == NULL) + { + pg_log_error("no source server information (--source--server) specified for --write-recovery-conf"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + if (optind < argc) { pg_log_error("too many command-line arguments (first is \"%s\")", @@ -236,6 +253,8 @@ main(int argc, char **argv) umask(pg_mode_mask); + atexit(disconnect_atexit); + /* Connect to remote server */ if (connstr_source) libpqConnect(connstr_source); @@ -322,6 +341,9 @@ main(int argc, char **argv) if (!rewind_needed) { pg_log_info("no rewind required"); + if (writerecoveryconf) + WriteRecoveryConfig(conn, datadir_target, + GenerateRecoveryConfig(conn, NULL)); exit(0); } @@ -419,6 +441,10 @@ main(int argc, char **argv) pg_log_info("syncing target data directory"); syncTargetDirectory(); + if (writerecoveryconf) + WriteRecoveryConfig(conn, datadir_target, + GenerateRecoveryConfig(conn, NULL)); + pg_log_info("Done!"); return 0; @@ -828,3 +854,10 @@ ensureCleanShutdown(const char *argv0) pg_fatal("Command was: %s", cmd); } } + +static void +disconnect_atexit(void) +{ + if (conn != NULL) + PQfinish(conn); +} diff --git a/src/bin/pg_rewind/pg_rewind.h b/src/bin/pg_rewind/pg_rewind.h index 1125c7e60f..aa3a0ce8fc 100644 --- a/src/bin/pg_rewind/pg_rewind.h +++ b/src/bin/pg_rewind/pg_rewind.h @@ -14,10 +14,11 @@ #include "datapagemap.h" #include "access/timeline.h" +#include "common/logging.h" +#include "libpq-fe.h" #include "storage/block.h" #include "storage/relfilenode.h" -#include "common/logging.h" /* Configuration options */ extern char *datadir_target; @@ -31,6 +32,9 @@ extern int WalSegSz; extern TimeLineHistoryEntry *targetHistory; extern int targetNentries; +/* general state */ +extern PGconn *conn; + /* Progress counters */ extern uint64 fetch_size; extern uint64 fetch_done; @@ -53,6 +57,7 @@ extern void progress_report(bool force); /* in timeline.c */ extern TimeLineHistoryEntry *rewind_parseTimeLineHistory(char *buffer, - TimeLineID targetTLI, int *nentries); + TimeLineID targetTLI, + int *nentries); #endif /* PG_REWIND_H */ -- 2.40.0