From 66578336861e02b9dc5544b7d2fed46261681998 Mon Sep 17 00:00:00 2001 From: Vigneshwaran c Date: Mon, 8 Jul 2019 22:49:18 +0530 Subject: [PATCH] pg_upgrade failure fix. For adjusting undo the old cluster redo need to be passed. Patch by Vigneshwaran C, reviewed by Dilip Kumar. --- src/bin/pg_resetwal/pg_resetwal.c | 34 ++++++++++++++++++++++++++++------ src/bin/pg_upgrade/pg_upgrade.c | 4 ++-- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index 0610a8c..396613b 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -85,7 +85,7 @@ static bool ReadControlFile(void); static void GuessControlValues(void); static void PrintControlValues(bool guessed); static void PrintNewControlValues(void); -static void AdjustRedoLocation(const char *DataDir); +static void AdjustRedoLocation(const char *DataDir, uint64 prev_redo); static void RewriteControlFile(void); static void FindEndOfXLOG(void); static void KillExistingXLOG(void); @@ -109,6 +109,7 @@ main(int argc, char *argv[]) {"next-oid", required_argument, NULL, 'o'}, {"multixact-offset", required_argument, NULL, 'O'}, {"next-transaction-id", required_argument, NULL, 'x'}, + {"old-redo", required_argument, NULL, 'r'}, {"wal-segsize", required_argument, NULL, 1}, {NULL, 0, NULL, 0} }; @@ -121,6 +122,7 @@ main(int argc, char *argv[]) char *endptr2; char *DataDir = NULL; char *log_fname = NULL; + uint64 old_redo = 0; int fd; char latest_undo_checkpoint_file[MAXPGPATH]; char new_undo_checkpoint_file[MAXPGPATH]; @@ -145,7 +147,7 @@ main(int argc, char *argv[]) } - while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:O:x:", long_options, NULL)) != -1) + while ((c = getopt_long(argc, argv, "c:D:e:fl:m:no:r:O:x:", long_options, NULL)) != -1) { switch (c) { @@ -239,6 +241,21 @@ main(int argc, char *argv[]) } break; + case 'r': + old_redo = strtoull(optarg, &endptr, 0); + if (endptr == optarg || *endptr != '\0') + { + pg_log_error("invalid argument for option %s", "-r"); + fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); + exit(1); + } + if (old_redo == 0) + { + pg_log_error("Old Redo (-r) must not be 0"); + exit(1); + } + break; + case 'm': set_mxid = strtoul(optarg, &endptr, 0); if (endptr == optarg || *endptr != ',') @@ -521,7 +538,7 @@ main(int argc, char *argv[]) /* * Else, do the dirty deed. */ - AdjustRedoLocation(DataDir); + AdjustRedoLocation(DataDir, old_redo); RewriteControlFile(); /* @@ -800,6 +817,9 @@ PrintControlValues(bool guessed) ControlFile.catalog_version_no); printf(_("Database system identifier: %s\n"), sysident_str); + printf(_("Latest checkpoint's REDO location: %X/%X\n"), + (uint32) (ControlFile.checkPointCopy.redo >> 32), + (uint32) ControlFile.checkPointCopy.redo); printf(_("Latest checkpoint's TimeLineID: %u\n"), ControlFile.checkPointCopy.ThisTimeLineID); printf(_("Latest checkpoint's full_page_writes: %s\n"), @@ -940,9 +960,10 @@ PrintNewControlValues(void) * occurs before the controlfile is rewritten won't be fatal. */ static void -AdjustRedoLocation(const char *DataDir) +AdjustRedoLocation(const char *DataDir, uint64 prev_redo) { - uint64 old_redo = ControlFile.checkPointCopy.redo; + uint64 old_redo = (prev_redo != 0) ? prev_redo: + ControlFile.checkPointCopy.redo; char old_pg_undo_path[MAXPGPATH]; char new_pg_undo_path[MAXPGPATH]; int old_fd; @@ -985,7 +1006,7 @@ AdjustRedoLocation(const char *DataDir) new_fd = open(new_pg_undo_path, O_RDWR | O_CREAT, 0644); if (new_fd < 0) { - pg_log_error("could not open \"%s\": %m", old_pg_undo_path); + pg_log_error("could not open \"%s\": %m", new_pg_undo_path); exit(1); } while ((nread = read(old_fd, buffer, sizeof(buffer))) > 0) @@ -1399,6 +1420,7 @@ usage(void) printf(_(" -n, --dry-run no update, just show what would be done\n")); printf(_(" -o, --next-oid=OID set next OID\n")); printf(_(" -O, --multixact-offset=OFFSET set next multitransaction offset\n")); + printf(_(" -r, --old-redo=REDO use old redo for adjusting the UNDO\n")); printf(_(" -V, --version output version information, then exit\n")); printf(_(" -x, --next-transaction-id=XID set next transaction ID\n")); printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n")); diff --git a/src/bin/pg_upgrade/pg_upgrade.c b/src/bin/pg_upgrade/pg_upgrade.c index c611203..3a6ade9 100644 --- a/src/bin/pg_upgrade/pg_upgrade.c +++ b/src/bin/pg_upgrade/pg_upgrade.c @@ -484,9 +484,9 @@ copy_xact_xlog_xid(void) /* set the next transaction id and epoch of the new cluster */ prep_status("Setting next transaction ID and epoch for new cluster"); exec_prog(UTILITY_LOG_FILE, NULL, true, true, - "\"%s/pg_resetwal\" -f -x %u \"%s\"", + "\"%s/pg_resetwal\" -f -x %u -r "UINT64_FORMAT" \"%s\"", new_cluster.bindir, old_cluster.controldata.chkpnt_nxtxid, - new_cluster.pgdata); + old_cluster.controldata.redo_location, new_cluster.pgdata); exec_prog(UTILITY_LOG_FILE, NULL, true, true, "\"%s/pg_resetwal\" -f -e %u \"%s\"", new_cluster.bindir, old_cluster.controldata.chkpnt_nxtepoch, -- 1.8.3.1